Bläddra i källkod

Merge "msm: camera: cdm: Add support for testing irq line" into camera-kernel.lnx.6.0

Haritha Chintalapati 3 år sedan
förälder
incheckning
226acd5b9f

+ 1 - 0
drivers/cam_cdm/cam_cdm.h

@@ -581,6 +581,7 @@ struct cam_cdm_intf_mgr {
 	uint32_t dt_supported_hw_cdm;
 	int32_t refcount;
 	struct cam_cdm_intf_devices nodes[CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM];
+	struct dentry *dentry;
 };
 
 int cam_cdm_intf_register_hw_cdm(struct cam_hw_intf *hw,

+ 33 - 19
drivers/cam_cdm/cam_cdm_core_common.c

@@ -18,6 +18,38 @@
 #include "cam_cdm_soc.h"
 #include "cam_cdm_core_common.h"
 
+int cam_cdm_util_cpas_start(struct cam_hw_info *cdm_hw)
+{
+	struct cam_cdm *core = NULL;
+	struct cam_ahb_vote ahb_vote;
+	struct cam_axi_vote axi_vote = {0};
+	int rc = 0;
+
+	if (!cdm_hw) {
+		CAM_ERR(CAM_CDM, "Invalid cdm hw");
+		return -EINVAL;
+	}
+
+	core = (struct cam_cdm *)cdm_hw->core_info;
+
+	ahb_vote.type = CAM_VOTE_ABSOLUTE;
+	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
+	axi_vote.num_paths = 1;
+	axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
+	axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_READ;
+	axi_vote.axi_path[0].camnoc_bw = CAM_CPAS_DEFAULT_AXI_BW;
+	axi_vote.axi_path[0].mnoc_ab_bw = CAM_CPAS_DEFAULT_AXI_BW;
+	axi_vote.axi_path[0].mnoc_ib_bw = CAM_CPAS_DEFAULT_AXI_BW;
+
+	rc = cam_cpas_start(core->cpas_handle, &ahb_vote, &axi_vote);
+	if (rc) {
+		CAM_ERR(CAM_CDM, "CDM[%d] CPAS start failed rc=%d", core->index, rc);
+		return rc;
+	}
+
+	return rc;
+}
+
 static void cam_cdm_get_client_refcount(struct cam_cdm_client *client)
 {
 	mutex_lock(&client->lock);
@@ -341,25 +373,7 @@ int cam_cdm_stream_ops_internal(void *hw_priv,
 
 	if (operation == true) {
 		if (!cdm_hw->open_count) {
-			struct cam_ahb_vote ahb_vote;
-			struct cam_axi_vote axi_vote = {0};
-
-			ahb_vote.type = CAM_VOTE_ABSOLUTE;
-			ahb_vote.vote.level = CAM_LOWSVS_VOTE;
-			axi_vote.num_paths = 1;
-			axi_vote.axi_path[0].path_data_type =
-				CAM_AXI_PATH_DATA_ALL;
-			axi_vote.axi_path[0].transac_type =
-				CAM_AXI_TRANSACTION_READ;
-			axi_vote.axi_path[0].camnoc_bw =
-				CAM_CPAS_DEFAULT_AXI_BW;
-			axi_vote.axi_path[0].mnoc_ab_bw =
-				CAM_CPAS_DEFAULT_AXI_BW;
-			axi_vote.axi_path[0].mnoc_ib_bw =
-				CAM_CPAS_DEFAULT_AXI_BW;
-
-			rc = cam_cpas_start(core->cpas_handle,
-				&ahb_vote, &axi_vote);
+			rc = cam_cdm_util_cpas_start(cdm_hw);
 			if (rc != 0) {
 				CAM_ERR(CAM_CDM, "CPAS start failed");
 				goto end;

+ 2 - 1
drivers/cam_cdm/cam_cdm_core_common.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_CDM_CORE_COMMON_H_
@@ -58,5 +58,6 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
 	enum cam_cdm_cb_status status, void *data);
 void cam_hw_cdm_dump_core_debug_registers(
 	struct cam_hw_info *cdm_hw, bool pause_core);
+int cam_cdm_util_cpas_start(struct cam_hw_info *cdm_hw);
 
 #endif /* _CAM_CDM_CORE_COMMON_H_ */

+ 63 - 12
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -2135,6 +2135,65 @@ int cam_hw_cdm_deinit(void *hw_priv,
 	return rc;
 }
 
+#if (defined(CONFIG_CAM_TEST_IRQ_LINE) && defined(CONFIG_CAM_TEST_IRQ_LINE_AT_PROBE))
+static int cam_cdm_test_irq_line(void *hw_priv)
+{
+	struct cam_hw_info *cdm_hw = hw_priv;
+	struct cam_cdm *core = NULL;
+	int rc = 0;
+
+	if (!cdm_hw) {
+		CAM_ERR(CAM_CDM, "Invalid cdm hw");
+		return -EINVAL;
+	}
+
+	core = (struct cam_cdm *)cdm_hw->core_info;
+
+	rc = cam_cdm_util_cpas_start(cdm_hw);
+	if (rc) {
+		CAM_ERR(CAM_CDM, "CDM[%d] Failed in cpas start rc", core->index, rc);
+		goto done;
+	}
+
+	rc = cam_hw_cdm_init(cdm_hw, NULL, 0);
+	if (rc) {
+		CAM_ERR(CAM_CDM, "CDM[%d] Failed in cdm init rc", core->index, rc);
+		goto cpas_stop;
+	}
+
+	rc = cam_hw_cdm_deinit(cdm_hw, NULL, 0);
+	if (rc) {
+		CAM_ERR(CAM_CDM, "CDM[%d] Failed in cdm deinit rc", core->index, rc);
+		goto cpas_stop;
+	}
+
+cpas_stop:
+	rc = cam_cpas_stop(core->cpas_handle);
+	if (rc)
+		CAM_ERR(CAM_CDM, "CDM[%d] Failed in cpas stop rc", core->index, rc);
+done:
+	return rc;
+}
+#else
+static int cam_cdm_test_irq_line(void *hw_priv)
+{
+	return -EPERM;
+}
+#endif
+
+
+#if (defined(CONFIG_CAM_TEST_IRQ_LINE) && defined(CONFIG_CAM_TEST_IRQ_LINE_AT_PROBE))
+static int cam_cdm_test_irq_line_at_probe(struct cam_hw_info *cdm_hw)
+{
+	return cam_cdm_test_irq_line(cdm_hw);
+}
+#else
+static int cam_cdm_test_irq_line_at_probe(struct cam_hw_info *cdm_hw)
+{
+	return -EPERM;
+}
+#endif
+
 static int cam_hw_cdm_component_bind(struct device *dev,
 	struct device *master_dev, void *data)
 {
@@ -2144,8 +2203,6 @@ static int cam_hw_cdm_component_bind(struct device *dev,
 	struct cam_cdm *cdm_core = NULL;
 	struct cam_cdm_private_dt_data *soc_private = NULL;
 	struct cam_cpas_register_params cpas_parms;
-	struct cam_ahb_vote ahb_vote;
-	struct cam_axi_vote axi_vote = {0};
 	char cdm_name[128], work_q_name[128];
 	struct platform_device *pdev = to_platform_device(dev);
 
@@ -2213,6 +2270,7 @@ static int cam_hw_cdm_component_bind(struct device *dev,
 	cdm_hw_intf->hw_ops.read = NULL;
 	cdm_hw_intf->hw_ops.write = NULL;
 	cdm_hw_intf->hw_ops.process_cmd = cam_cdm_process_cmd;
+	cdm_hw_intf->hw_ops.test_irq_line = cam_cdm_test_irq_line;
 	mutex_lock(&cdm_hw->hw_mutex);
 
 	CAM_DBG(CAM_CDM, "type %d index %d", cdm_hw_intf->hw_type,
@@ -2285,16 +2343,7 @@ static int cam_hw_cdm_component_bind(struct device *dev,
 		cpas_parms.client_handle);
 	cdm_core->cpas_handle = cpas_parms.client_handle;
 
-	ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
-	axi_vote.num_paths = 1;
-	axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
-	axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_READ;
-	axi_vote.axi_path[0].camnoc_bw = CAM_CPAS_DEFAULT_AXI_BW;
-	axi_vote.axi_path[0].mnoc_ab_bw = CAM_CPAS_DEFAULT_AXI_BW;
-	axi_vote.axi_path[0].mnoc_ib_bw = CAM_CPAS_DEFAULT_AXI_BW;
-
-	rc = cam_cpas_start(cdm_core->cpas_handle, &ahb_vote, &axi_vote);
+	rc = cam_cdm_util_cpas_start(cdm_hw);
 	if (rc) {
 		CAM_ERR(CAM_CDM, "CPAS start failed");
 		goto cpas_unregister;
@@ -2357,6 +2406,8 @@ static int cam_hw_cdm_component_bind(struct device *dev,
 		CAM_ERR(CAM_CDM, "HW CDM Interface registration failed");
 		goto cpas_unregister;
 	}
+
+	cam_cdm_test_irq_line_at_probe(cdm_hw);
 	mutex_unlock(&cdm_hw->hw_mutex);
 
 	CAM_DBG(CAM_CDM, "%s component bound successfully", cdm_core->name);

+ 78 - 1
drivers/cam_cdm/cam_cdm_intf.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/delay.h>
@@ -617,6 +617,80 @@ int cam_cdm_intf_deregister_hw_cdm(struct cam_hw_intf *hw,
 	return rc;
 }
 
+static int cam_cdm_set_irq_line_test(void *data, u64 val)
+{
+	int i, rc = 0;
+	struct cam_hw_intf *hw_intf;
+
+	if (get_cdm_mgr_refcount()) {
+		CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
+		return rc;
+	}
+	mutex_lock(&cam_cdm_mgr_lock);
+
+	for (i = 0 ; i < cdm_mgr.cdm_count; i++) {
+		if (!cdm_mgr.nodes[i].device || !cdm_mgr.nodes[i].data) {
+			CAM_ERR(CAM_CDM, "invalid node present in index=%d", i);
+			continue;
+		}
+
+		hw_intf = cdm_mgr.nodes[i].device;
+
+		if (hw_intf->hw_ops.test_irq_line) {
+			CAM_DBG(CAM_CDM, "Testing irq line for CDM at index %d", i);
+
+			rc = hw_intf->hw_ops.test_irq_line(hw_intf->hw_priv);
+			if (rc)
+				CAM_ERR(CAM_CDM,
+					"[%d] : CDM%d type %d - irq line test failed rc %d",
+					i, hw_intf->hw_idx, hw_intf->hw_type, rc);
+			else
+				CAM_INFO(CAM_CDM,
+					"[%d] : CDM%d type %d - irq line test passed",
+					i, hw_intf->hw_idx, hw_intf->hw_type);
+		} else {
+			CAM_WARN(CAM_CDM, "test irq line interface not present for cdm at index %d",
+				i);
+		}
+	}
+
+	mutex_unlock(&cam_cdm_mgr_lock);
+	put_cdm_mgr_refcount();
+
+	return rc;
+}
+
+static int cam_cdm_get_irq_line_test(void *data, u64 *val)
+{
+	return 0;
+}
+
+
+DEFINE_DEBUGFS_ATTRIBUTE(cam_cdm_irq_line_test, cam_cdm_get_irq_line_test,
+	cam_cdm_set_irq_line_test, "%16llu");
+
+int cam_cdm_debugfs_init(struct cam_cdm_intf_mgr *mgr)
+{
+	struct dentry *dbgfileptr = NULL;
+	int rc;
+
+	if (!cam_debugfs_available())
+		return 0;
+
+	rc = cam_debugfs_create_subdir("cdm", &dbgfileptr);
+	if (rc) {
+		CAM_ERR(CAM_CDM, "DebugFS could not create directory!");
+		return rc;
+	}
+
+	mgr->dentry = dbgfileptr;
+
+	debugfs_create_file("test_irq_line", 0644,
+		mgr->dentry, NULL, &cam_cdm_irq_line_test);
+
+	return 0;
+}
+
 static int cam_cdm_intf_component_bind(struct device *dev,
 	struct device *master_dev, void *data)
 {
@@ -655,6 +729,8 @@ static int cam_cdm_intf_component_bind(struct device *dev,
 		mutex_unlock(&cam_cdm_mgr_lock);
 	}
 
+	cam_cdm_debugfs_init(&cdm_mgr);
+
 	CAM_DBG(CAM_CDM, "CDM Intf component bound successfully");
 
 	return rc;
@@ -695,6 +771,7 @@ static void cam_cdm_intf_component_unbind(struct device *dev,
 		cdm_mgr.nodes[i].data = NULL;
 		cdm_mgr.nodes[i].refcount = 0;
 	}
+
 	cdm_mgr.probe_done = false;
 
 end: