msm: camera: isp: Fix to assign IFE composite groups

Previously same composite group was being assigned
for multiple devices even when the user has not
applied such settings. Enum values from UMD did not
match KMD's enum values. Also the ife_irq registers
were being reset without waiting on both devices of a
given grp to finish. Fix ensures support for both
composite grps and individual write masters as desired
by the user.

Change-Id: Id714509e94bf508e90c92da2f87a2d65e4b0a100
Signed-off-by: Karthik Anantha Ram <kartanan@codeaurora.org>
Signed-off-by: Harsh Shah <harshs@codeaurora.org>
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
index 1fbc105..4d98e29 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
@@ -71,6 +71,16 @@
 	PACKER_FMT_MAX                         = 0xF,
 };
 
+enum cam_vfe_bus_comp_grp_id {
+	CAM_VFE_BUS_COMP_GROUP_NONE = -EINVAL,
+	CAM_VFE_BUS_COMP_GROUP_ID_0 = 0x0,
+	CAM_VFE_BUS_COMP_GROUP_ID_1 = 0x1,
+	CAM_VFE_BUS_COMP_GROUP_ID_2 = 0x2,
+	CAM_VFE_BUS_COMP_GROUP_ID_3 = 0x3,
+	CAM_VFE_BUS_COMP_GROUP_ID_4 = 0x4,
+	CAM_VFE_BUS_COMP_GROUP_ID_5 = 0x5,
+};
+
 struct cam_vfe_bus_ver2_common_data {
 	uint32_t                                    core_index;
 	void __iomem                               *mem_base;
@@ -136,6 +146,9 @@
 	uint32_t                         intra_client_mask;
 	uint32_t                         composite_mask;
 
+	uint32_t                         acquire_dev_cnt;
+	uint32_t                         irq_trigger_cnt;
+
 	void                            *ctx;
 };
 
@@ -187,6 +200,28 @@
 	return 0;
 }
 
+static enum cam_vfe_bus_comp_grp_id
+	cam_vfe_bus_comp_grp_id_convert(uint32_t comp_grp)
+{
+	switch (comp_grp) {
+	case CAM_ISP_RES_COMP_GROUP_ID_0:
+		return CAM_VFE_BUS_COMP_GROUP_ID_0;
+	case CAM_ISP_RES_COMP_GROUP_ID_1:
+		return CAM_VFE_BUS_COMP_GROUP_ID_1;
+	case CAM_ISP_RES_COMP_GROUP_ID_2:
+		return CAM_VFE_BUS_COMP_GROUP_ID_2;
+	case CAM_ISP_RES_COMP_GROUP_ID_3:
+		return CAM_VFE_BUS_COMP_GROUP_ID_3;
+	case CAM_ISP_RES_COMP_GROUP_ID_4:
+		return CAM_VFE_BUS_COMP_GROUP_ID_4;
+	case CAM_ISP_RES_COMP_GROUP_ID_5:
+		return CAM_VFE_BUS_COMP_GROUP_ID_5;
+	case CAM_ISP_RES_COMP_GROUP_NONE:
+	default:
+		return CAM_VFE_BUS_COMP_GROUP_NONE;
+	}
+}
+
 static int cam_vfe_bus_put_evt_payload(void     *core_info,
 	struct cam_vfe_bus_irq_evt_payload     **evt_payload)
 {
@@ -1182,12 +1217,18 @@
 	struct cam_isp_resource_node       **comp_grp)
 {
 	int rc = 0;
+	uint32_t bus_comp_grp_id;
 	struct cam_isp_resource_node           *comp_grp_local = NULL;
 	struct cam_vfe_bus_ver2_comp_grp_data  *rsrc_data = NULL;
 
-	/* Check if matching comp_grp already acquired */
-	cam_vfe_bus_match_comp_grp(ver2_bus_priv, &comp_grp_local,
-		out_port_info->comp_grp_id, unique_id);
+	bus_comp_grp_id = cam_vfe_bus_comp_grp_id_convert(
+		out_port_info->comp_grp_id);
+	/* Perform match only if there is valid comp grp request */
+	if (out_port_info->comp_grp_id != CAM_ISP_RES_COMP_GROUP_NONE) {
+		/* Check if matching comp_grp already acquired */
+		cam_vfe_bus_match_comp_grp(ver2_bus_priv, &comp_grp_local,
+			bus_comp_grp_id, unique_id);
+	}
 
 	if (!comp_grp_local) {
 		/* First find a free group */
@@ -1222,7 +1263,7 @@
 		rsrc_data->is_master = is_master;
 		rsrc_data->composite_mask = 0;
 		rsrc_data->unique_id = unique_id;
-		rsrc_data->comp_grp_local_idx = out_port_info->comp_grp_id;
+		rsrc_data->comp_grp_local_idx = bus_comp_grp_id;
 
 		list_add_tail(&comp_grp_local->list,
 			&ver2_bus_priv->used_comp_grp);
@@ -1240,6 +1281,7 @@
 	}
 
 	rsrc_data->ctx = ctx;
+	rsrc_data->acquire_dev_cnt++;
 	*comp_grp = comp_grp_local;
 
 	return rc;
@@ -1254,15 +1296,21 @@
 	int match_found = 0;
 
 	if (!in_comp_grp) {
-		CAM_ERR(CAM_ISP, "Invalid Params Comp Grp %pK", in_rsrc_data);
+		CAM_ERR(CAM_ISP, "Invalid Params Comp Grp %pK", in_comp_grp);
 		return -EINVAL;
 	}
 
 	if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
-		/* Already Released. Do Nothing */
+		CAM_ERR(CAM_ISP, "Already released Comp Grp");
 		return 0;
 	}
 
+	if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_STREAMING) {
+		CAM_ERR(CAM_ISP, "Invalid State %d",
+			in_comp_grp->res_state);
+		return -EBUSY;
+	}
+
 	in_rsrc_data = in_comp_grp->res_priv;
 
 	list_for_each_entry(comp_grp, &ver2_bus_priv->used_comp_grp, list) {
@@ -1278,23 +1326,31 @@
 		return -ENODEV;
 	}
 
+	in_rsrc_data->acquire_dev_cnt--;
+	if (in_rsrc_data->acquire_dev_cnt == 0) {
+		list_del(&comp_grp->list);
 
-	list_del(&comp_grp->list);
-	if (in_rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
-		in_rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
-		list_add_tail(&comp_grp->list,
-			&ver2_bus_priv->free_dual_comp_grp);
-	else if (in_rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
-		&& in_rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
-		list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
+		in_rsrc_data->unique_id = 0;
+		in_rsrc_data->comp_grp_local_idx = CAM_VFE_BUS_COMP_GROUP_NONE;
+		in_rsrc_data->composite_mask = 0;
+		in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
 
-	in_rsrc_data->unique_id = 0;
-	in_rsrc_data->comp_grp_local_idx = 0;
-	in_rsrc_data->composite_mask = 0;
-	in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
+		comp_grp->tasklet_info = NULL;
+		comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
 
-	comp_grp->tasklet_info = NULL;
-	comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
+		if (in_rsrc_data->comp_grp_type >=
+			CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
+			in_rsrc_data->comp_grp_type <=
+			CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
+			list_add_tail(&comp_grp->list,
+				&ver2_bus_priv->free_dual_comp_grp);
+		else if (in_rsrc_data->comp_grp_type >=
+			CAM_VFE_BUS_VER2_COMP_GRP_0 &&
+			in_rsrc_data->comp_grp_type <=
+			CAM_VFE_BUS_VER2_COMP_GRP_5)
+			list_add_tail(&comp_grp->list,
+				&ver2_bus_priv->free_comp_grp);
+	}
 
 	return 0;
 }
@@ -1485,8 +1541,13 @@
 
 		/* Regular Composite SUCCESS */
 		if (status_reg & BIT(comp_grp_id + 5)) {
-			cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0] &=
-				~BIT(comp_grp_id + 5);
+			rsrc_data->irq_trigger_cnt++;
+			if (rsrc_data->irq_trigger_cnt ==
+				rsrc_data->acquire_dev_cnt) {
+				cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0] &=
+					~BIT(comp_grp_id + 5);
+				rsrc_data->irq_trigger_cnt = 0;
+			}
 			rc = CAM_VFE_IRQ_STATUS_SUCCESS;
 		}
 
@@ -1524,8 +1585,13 @@
 
 		/* DUAL Composite SUCCESS */
 		if (status_reg & BIT(comp_grp_id)) {
-			cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
-				~BIT(comp_grp_id + 5);
+			rsrc_data->irq_trigger_cnt++;
+			if (rsrc_data->irq_trigger_cnt ==
+				rsrc_data->acquire_dev_cnt) {
+				cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
+					~BIT(comp_grp_id + 5);
+				rsrc_data->irq_trigger_cnt = 0;
+			}
 			rc = CAM_VFE_IRQ_STATUS_SUCCESS;
 		}