Просмотр исходного кода

msm: camera: cpas: Add support to turn on optional clks

This change is needed for domain id feature support.

When a PHY and its lanes for a particular CSID are
protected in a secure session, the same for other
unused CSIDs are to be protected as well. This is
to prevent other CSIDs from tapping the data streaming
onto those lanes if they share the same PHY.

For this, the clocks for other CSIDs (eg CSID-Lite)
need to be turned on. Given that the existing driver
turns on the clocks for the CSID in use, and that
this clock information is embedded within the CSID
hw blocks, these clocks are now exposed as optional
clocks to CPAS to enable the PHY driver to turn them
on during streamon for secure session.

CRs-Fixed: 3304650
Change-Id: I1415e78467208b6b4a74223521d964a199288857
Signed-off-by: Li Sha Lim <[email protected]>
Li Sha Lim 2 лет назад
Родитель
Сommit
28ed69bb34

+ 60 - 0
drivers/cam_cpas/cam_cpas_hw.c

@@ -3097,6 +3097,53 @@ static int cam_cpas_hw_csid_input_core_info_update(struct cam_hw_info *cpas_hw,
 	return rc;
 }
 
+static int cam_cpas_hw_enable_domain_id_clks(struct cam_hw_info *cpas_hw,
+	bool enable)
+{
+	int rc = 0, i;
+	struct cam_cpas_private_soc *soc_private =
+		(struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
+	struct cam_cpas_domain_id_support_clks *domain_id_clks =
+		soc_private->domain_id_clks;
+
+	if (!soc_private->domain_id_info.domain_id_supported) {
+		CAM_DBG(CAM_CPAS, "Domain-id not supported on target");
+		return -EINVAL;
+	}
+
+	if (enable) {
+		for (i = 0; i < domain_id_clks->number_clks; i++) {
+			rc = cam_soc_util_clk_enable(&cpas_hw->soc_info, true,
+				domain_id_clks->clk_idx[i], 0, NULL);
+			if (rc) {
+				CAM_ERR(CAM_CPAS, "Domain-id clk %s enable failed, rc: %d",
+					domain_id_clks->clk_names[i], i);
+				goto clean_up;
+			}
+		}
+		CAM_DBG(CAM_CPAS, "Domain-id clks enable success");
+	} else {
+		for (i = 0; i < domain_id_clks->number_clks; i++) {
+			rc = cam_soc_util_clk_disable(&cpas_hw->soc_info, true,
+				domain_id_clks->clk_idx[i]);
+			if (rc)
+				CAM_WARN(CAM_CPAS, "Domain-id clk %s disable failed, rc: %d",
+					domain_id_clks->clk_names[i], rc);
+		}
+		if (!rc)
+			CAM_DBG(CAM_CPAS, "Domain-id clks disable success");
+	}
+
+	return rc;
+
+clean_up:
+	for (--i; i >= 0; i--)
+		cam_soc_util_clk_disable(&cpas_hw->soc_info, true,
+			domain_id_clks->clk_idx[i]);
+
+	return rc;
+}
+
 static int cam_cpas_hw_csid_process_resume(struct cam_hw_info *cpas_hw, uint32_t csid_idx)
 {
 	int i, rc = 0;
@@ -3357,6 +3404,19 @@ static int cam_cpas_hw_process_cmd(void *hw_priv,
 		rc = cam_cpas_hw_csid_process_resume(hw_priv, *csid_idx);
 		break;
 	}
+	case CAM_CPAS_HW_CMD_ENABLE_DISABLE_DOMAIN_ID_CLK: {
+		bool *enable;
+
+		if (sizeof(bool) != arg_size) {
+			CAM_ERR(CAM_CPAS, "cmd_type %d, size mismatch %d",
+				cmd_type, arg_size);
+			break;
+		}
+
+		enable = (bool *)cmd_args;
+		rc = cam_cpas_hw_enable_domain_id_clks(hw_priv, *enable);
+		break;
+	}
 
 	default:
 		CAM_ERR(CAM_CPAS, "CPAS HW command not valid =%d", cmd_type);

+ 1 - 0
drivers/cam_cpas/cam_cpas_hw_intf.h

@@ -50,6 +50,7 @@ enum cam_cpas_hw_cmd_process {
 	CAM_CPAS_HW_CMD_DUMP_BUFF_FILL_INFO,
 	CAM_CPAS_HW_CMD_CSID_INPUT_CORE_INFO_UPDATE,
 	CAM_CPAS_HW_CMD_CSID_PROCESS_RESUME,
+	CAM_CPAS_HW_CMD_ENABLE_DISABLE_DOMAIN_ID_CLK,
 	CAM_CPAS_HW_CMD_INVALID,
 };
 

+ 20 - 0
drivers/cam_cpas/cam_cpas_intf.c

@@ -803,6 +803,26 @@ bool cam_cpas_query_domain_id_security_support(void)
 }
 EXPORT_SYMBOL(cam_cpas_query_domain_id_security_support);
 
+int cam_cpas_enable_clks_for_domain_id(bool enable)
+{
+	int rc = 0;
+
+	if (!CAM_CPAS_INTF_INITIALIZED()) {
+		CAM_ERR(CAM_CPAS, "cpas intf not initialized");
+		return -ENODEV;
+	}
+
+	if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
+		rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
+			g_cpas_intf->hw_intf->hw_priv,
+			CAM_CPAS_HW_CMD_ENABLE_DISABLE_DOMAIN_ID_CLK, &enable,
+			sizeof(enable));
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(cam_cpas_enable_clks_for_domain_id);
+
 int cam_cpas_subdev_cmd(struct cam_cpas_intf *cpas_intf,
 	struct cam_control *cmd)
 {

+ 75 - 2
drivers/cam_cpas/cam_cpas_soc.c

@@ -948,6 +948,69 @@ err:
 	return rc;
 }
 
+static int cam_cpas_get_domain_id_support_clks(struct device_node *of_node,
+	struct cam_hw_soc_info *soc_info, struct cam_cpas_private_soc *soc_private)
+{
+	int rc = 0, count, i;
+	struct cam_cpas_domain_id_support_clks *domain_id_clks;
+
+	soc_private->domain_id_clks = kzalloc(sizeof(struct cam_cpas_domain_id_support_clks),
+		GFP_KERNEL);
+	if (!soc_private->domain_id_clks) {
+		CAM_ERR(CAM_CPAS, "Failed in allocating memory for domain_id_clk");
+		return -ENOMEM;
+	}
+
+	domain_id_clks = soc_private->domain_id_clks;
+
+	count = of_property_count_strings(of_node, "domain-id-support-clks");
+	CAM_DBG(CAM_CPAS, "Domain-id clk count: %d", count);
+	if (count > CAM_SOC_MAX_OPT_CLK) {
+		CAM_ERR(CAM_CPAS, "Invalid cnt of clocks, count: %d", count);
+		rc  = -EINVAL;
+		goto err;
+	}
+	if (count <= 0) {
+		CAM_ERR(CAM_CPAS, "No domain-id clk found");
+		rc = -EINVAL;
+		goto err;
+	}
+
+	domain_id_clks->number_clks = count;
+
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(of_node, "domain-id-support-clks",
+			i, &domain_id_clks->clk_names[i]);
+		if (rc) {
+			CAM_ERR(CAM_CPAS,
+				"Failed reading domain-id clk name at i: %d, total clks: %d",
+				i, count);
+			rc = -EINVAL;
+			goto err;
+		}
+
+		rc = cam_soc_util_get_option_clk_by_name(soc_info, domain_id_clks->clk_names[i],
+			&domain_id_clks->clk_idx[i]);
+		if (rc) {
+			CAM_ERR(CAM_CPAS,
+				"Failed reading domain-id clk %s at i: %d, total clks; %d",
+					domain_id_clks->clk_names[i], i, count);
+			rc = -EINVAL;
+			goto err;
+		}
+
+	CAM_DBG(CAM_CPAS, "Domain-id-clk %s with clk index %d",
+		domain_id_clks->clk_names[i], domain_id_clks->clk_idx[i]);
+
+	}
+
+	return rc;
+
+err:
+	kfree(domain_id_clks);
+	return rc;
+}
+
 int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
 	struct platform_device *pdev, struct cam_cpas_private_soc *soc_private)
 {
@@ -1500,11 +1563,19 @@ int cam_cpas_soc_init_resources(struct cam_hw_soc_info *soc_info,
 	rc = cam_soc_util_get_option_clk_by_name(soc_info, CAM_ICP_CLK_NAME,
 		&soc_private->icp_clk_index);
 	if (rc) {
-		CAM_DBG(CAM_CPAS, "Option clk get failed with rc %d", rc);
+		CAM_DBG(CAM_CPAS, "ICP option clk get failed with rc %d", rc);
 		soc_private->icp_clk_index = -1;
 		rc = 0;
 	} else {
-		CAM_DBG(CAM_CPAS, "Option clk get success index %d", soc_private->icp_clk_index);
+		CAM_DBG(CAM_CPAS, "ICP option clk get success index %d",
+			soc_private->icp_clk_index);
+	}
+
+	if (soc_private->domain_id_info.domain_id_supported) {
+		rc = cam_cpas_get_domain_id_support_clks(soc_info->pdev->dev.of_node,
+			soc_info, soc_private);
+		if (rc)
+			goto free_soc_private;
 	}
 
 	return rc;
@@ -1532,6 +1603,8 @@ int cam_cpas_soc_deinit_resources(struct cam_hw_soc_info *soc_info)
 
 	kfree(soc_private->domain_id_info.domain_id_entries);
 
+	kfree(soc_private->domain_id_clks);
+
 	rc = cam_soc_util_release_platform_resource(soc_info);
 	if (rc)
 		CAM_ERR(CAM_CPAS, "release platform failed, rc=%d", rc);

+ 17 - 0
drivers/cam_cpas/cam_cpas_soc.h

@@ -168,6 +168,21 @@ struct cam_cpas_domain_id_info {
 	bool domain_id_supported;
 };
 
+/**
+ * struct cam_cpas_domain_id_support_clks : Stores all information
+ *                                          related to clocks
+ *                                          needed to turn on SWIs
+ *                                          for domain id programming
+ * @clk_names:   Clock names as declared in DT
+ * @clk_idx:     Corresponding clk index as declared in DT
+ * @number_clks: Number of clocks declared to turn all CSIDs
+ */
+struct cam_cpas_domain_id_support_clks {
+	const char *clk_names[CAM_SOC_MAX_OPT_CLK];
+	int32_t clk_idx[CAM_SOC_MAX_OPT_CLK];
+	int number_clks;
+};
+
 /**
  * struct cam_cpas_private_soc : CPAS private DT info
  *
@@ -198,6 +213,7 @@ struct cam_cpas_domain_id_info {
  * @smart_qos_info: Pointer to smart qos info
  * @icp_clk_index: Index of optional icp clk
  * @domain_id_info: Stores all information related to domain id support
+ * @domain_id_clks: All clock related information for domain id support
  */
 struct cam_cpas_private_soc {
 	const char *arch_compat;
@@ -225,6 +241,7 @@ struct cam_cpas_private_soc {
 	struct cam_cpas_smart_qos_info *smart_qos_info;
 	int32_t icp_clk_index;
 	struct cam_cpas_domain_id_info domain_id_info;
+	struct cam_cpas_domain_id_support_clks *domain_id_clks;
 };
 
 void cam_cpas_util_debug_parse_data(struct cam_cpas_private_soc *soc_private);

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

@@ -906,4 +906,15 @@ int cam_cpas_query_drv_enable(bool *is_drv_enabled);
  */
 bool cam_cpas_query_domain_id_security_support(void);
 
+/**
+ * cam_cpas_enable_clks_for_domain_id()
+ *
+ * @brief: API to enable/disable clocks for domain id support.
+ *         All CSIDs including those not in use for a ctxt
+ *         needs to be programmed in a secure session.
+ * @enable: True to turn on, false otherwise.
+ * @return 0 on success
+ */
+int cam_cpas_enable_clks_for_domain_id(bool enable);
+
 #endif /* _CAM_CPAS_API_H_ */

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

@@ -1232,7 +1232,7 @@ static int cam_csiphy_program_secure_mode(struct csiphy_device *csiphy_dev,
 			protect, offset);
 
 		if (!protect)
-			csiphy_dev->csiphy_info[offset].secure_info.protect = false;
+			csiphy_dev->csiphy_info[offset].secure_info_updated = false;
 	}
 
 	return rc;

+ 1 - 1
drivers/cam_utils/cam_soc_util.h

@@ -43,7 +43,7 @@
 #define CAM_SOC_MAX_CLK             32
 
 /* maximum number of optional device clock */
-#define CAM_SOC_MAX_OPT_CLK    2
+#define CAM_SOC_MAX_OPT_CLK    7
 
 /* maximum number of pinctrl mapping */
 #define CAM_SOC_MAX_PINCTRL_MAP     2