Browse Source

msm: camera: jpeg: Add mechanism to verify IRQ lines

IRQ line verification can now be triggerred from JPEG HW manager by
writing to a debugfs file as follows:
    echo 1 > /d/camera/jpeg/test_irq_line

IRQ line verification can also be done at probe if
CONFIG_CAM_TEST_IRQ_LINE_AT_PROBE is set to true during compilation.
Both debugfs and probe-time verifications are only active if
CONFIG_CAM_TEST_IRQ_LINE is set to true during compilation.

CRs-Fixed: 3071027
Change-Id: Ib24022a12e3aa3ac529c7bc925fd4df1f2a96310
Signed-off-by: Anand Ravi <[email protected]>
Anand Ravi 3 years ago
parent
commit
4355ad8cb4

+ 73 - 4
drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/uaccess.h>
@@ -43,6 +44,8 @@
 #define CAM_JPEG_PARAM_CMD_BUFF_IDX                   2
 #define CAM_JPEG_THUBMNAIL_SIZE_CMD_BUFF_IDX          3
 
+#define CAM_JPEG_DEV_TYPE(type) ((type) == CAM_JPEG_DEV_TYPE_ENC ? "ENC" : "DMA")
+
 static struct cam_jpeg_hw_mgr g_jpeg_hw_mgr;
 
 static int32_t cam_jpeg_hw_mgr_sched_bottom_half(uint32_t irq_status,
@@ -324,7 +327,7 @@ static int cam_jpeg_process_next_hw_update(void *priv, void *data,
 	}
 
 	CAM_TRACE(CAM_JPEG, "Start JPEG %s ctx %lld Req %llu Pass %d",
-		(dev_type == CAM_JPEG_DEV_TYPE_ENC) ? "ENC" : "DMA",
+		CAM_JPEG_DEV_TYPE(dev_type),
 		(uint64_t) ctx_data,
 		config_args->request_id, pass_num);
 
@@ -2122,6 +2125,69 @@ static int cam_jpeg_get_bug_on_misr(void *data, u64 *val)
 DEFINE_DEBUGFS_ATTRIBUTE(bug_on_misr_mismatch, cam_jpeg_get_bug_on_misr,
 	cam_jpeg_set_bug_on_misr, "%08llu");
 
+#ifdef CONFIG_CAM_TEST_IRQ_LINE
+
+static int cam_jpeg_test_irq_line(void)
+{
+	struct cam_hw_intf *hw_intf;
+	int rc = -EINVAL, i, j;
+
+	for (i = 0; i < CAM_JPEG_DEV_PER_TYPE_MAX; i++) {
+		for (j = 0; j < CAM_JPEG_DEV_MAX; j++) {
+			hw_intf = g_jpeg_hw_mgr.devices[j][i];
+			if (hw_intf && hw_intf->hw_ops.test_irq_line) {
+				rc = hw_intf->hw_ops.test_irq_line(hw_intf->hw_priv);
+				if (rc)
+					CAM_ERR(CAM_JPEG,
+						"failed to verify IRQ line for JPEG-%s[%d]",
+						CAM_JPEG_DEV_TYPE(j), i);
+			}
+		}
+	}
+
+	return rc;
+}
+
+#else
+
+static int cam_jpeg_test_irq_line(void)
+{
+	CAM_ERR(CAM_JPEG, "IRQ line verification disabled!");
+	return -EPERM;
+}
+
+#endif
+
+#if (defined(CONFIG_CAM_TEST_IRQ_LINE) && defined(CONFIG_CAM_TEST_IRQ_LINE_AT_PROBE))
+
+static int cam_jpeg_test_irq_line_at_probe(void)
+{
+	return cam_jpeg_test_irq_line();
+}
+
+#else
+
+static int cam_jpeg_test_irq_line_at_probe(void)
+{
+	return 0;
+}
+
+#endif
+
+static int cam_jpeg_set_irq_line_test(void *data, u64 val)
+{
+	cam_jpeg_test_irq_line();
+	return 0;
+}
+
+static int cam_jpeg_get_irq_line_test(void *data, u64 *val)
+{
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(cam_jpeg_irq_line_test, cam_jpeg_get_irq_line_test,
+	cam_jpeg_set_irq_line_test, "%08llu");
+
 static int cam_jpeg_mgr_create_debugfs_entry(void)
 {
 	int rc = 0;
@@ -2144,6 +2210,9 @@ static int cam_jpeg_mgr_create_debugfs_entry(void)
 	debugfs_create_file("bug_on_misr_mismatch", 0644, g_jpeg_hw_mgr.dentry,
 		NULL, &bug_on_misr_mismatch);
 
+	debugfs_create_file("test_irq_line", 0644, g_jpeg_hw_mgr.dentry,
+		NULL, &cam_jpeg_irq_line_test);
+
 	return rc;
 }
 
@@ -2236,10 +2305,10 @@ int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
 		*iommu_hdl = g_jpeg_hw_mgr.iommu_hdl;
 
 	cam_common_register_mini_dump_cb(cam_jpeg_hw_mgr_mini_dump_cb, "CAM_JPEG");
+	cam_jpeg_mgr_create_debugfs_entry();
+	cam_jpeg_test_irq_line_at_probe();
 
-	rc = cam_jpeg_mgr_create_debugfs_entry();
-	if (!rc)
-		return rc;
+	return 0;
 
 cdm_iommu_failed:
 	cam_smmu_destroy_handle(g_jpeg_hw_mgr.iommu_hdl);

+ 38 - 1
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/of.h>
@@ -200,6 +200,8 @@ irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data)
 		if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING) {
 			core_info->core_state = CAM_JPEG_DMA_CORE_READY;
 			complete(&jpeg_dma_dev->hw_complete);
+			CAM_DBG(CAM_JPEG, "JPEG DMA %s reset done",
+				jpeg_dma_dev->soc_info.dev_name);
 		} else if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING_ON_DONE) {
 			if (core_info->irq_cb.jpeg_hw_mgr_cb) {
 				core_info->irq_cb.jpeg_hw_mgr_cb(irq_status, 1,
@@ -241,6 +243,7 @@ int cam_jpeg_dma_reset_hw(void *data,
 	struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
 	void __iomem *mem_base;
 	unsigned long rem_jiffies;
+	int rc = 0;
 
 	if (!jpeg_dma_dev) {
 		CAM_ERR(CAM_JPEG, "Invalid args");
@@ -282,9 +285,43 @@ int cam_jpeg_dma_reset_hw(void *data,
 	if (!rem_jiffies) {
 		CAM_ERR(CAM_JPEG, "dma error Reset Timeout");
 		core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
+		rc = -ETIMEDOUT;
 	}
 
 	mutex_unlock(&core_info->core_mutex);
+	return rc;
+}
+
+int cam_jpeg_dma_test_irq_line(void *data)
+{
+	struct cam_hw_info *jpeg_dma_dev = data;
+	struct cam_jpeg_dma_device_core_info *core_info = NULL;
+	int rc;
+
+	if (!data) {
+		CAM_ERR(CAM_JPEG, "invalid args");
+		return -EINVAL;
+	}
+
+	core_info = jpeg_dma_dev->core_info;
+
+	rc = cam_jpeg_dma_init_hw(data, NULL, 0);
+	if (rc) {
+		CAM_ERR(CAM_JPEG, "failed to init hw (rc=%d)", rc);
+		return rc;
+	}
+
+	rc = cam_jpeg_dma_reset_hw(data, NULL, 0);
+	if (rc)
+		CAM_ERR(CAM_JPEG, "failed to trigger reset irq (rc=%d)", rc);
+	else
+		CAM_INFO(CAM_JPEG, "verified JPEG DMA (%s) IRQ line",
+			jpeg_dma_dev->soc_info.dev_name);
+
+	rc = cam_jpeg_dma_deinit_hw(data, NULL, 0);
+	if (rc)
+		CAM_ERR(CAM_JPEG, "failed to de-init hw (rc=%d)", rc);
+
 	return 0;
 }
 

+ 2 - 0
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef CAM_JPEG_DMA_CORE_H
@@ -118,6 +119,7 @@ int cam_jpeg_dma_reset_hw(void *device_priv,
 	void *reset_hw_args, uint32_t arg_size);
 int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
 	void *cmd_args, uint32_t arg_size);
+int cam_jpeg_dma_test_irq_line(void *data);
 irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data);
 
 /**

+ 2 - 1
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -97,6 +97,7 @@ static int cam_jpeg_dma_component_bind(struct device *dev,
 	jpeg_dma_dev_intf->hw_ops.stop = cam_jpeg_dma_stop_hw;
 	jpeg_dma_dev_intf->hw_ops.reset = cam_jpeg_dma_reset_hw;
 	jpeg_dma_dev_intf->hw_ops.process_cmd = cam_jpeg_dma_process_cmd;
+	jpeg_dma_dev_intf->hw_ops.test_irq_line = cam_jpeg_dma_test_irq_line;
 	jpeg_dma_dev_intf->hw_type = CAM_JPEG_DEV_DMA;
 
 	platform_set_drvdata(pdev, jpeg_dma_dev_intf);

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

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/of.h>
@@ -227,6 +227,8 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data)
 		if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) {
 			core_info->core_state = CAM_JPEG_ENC_CORE_READY;
 			complete(&jpeg_enc_dev->hw_complete);
+			CAM_DBG(CAM_JPEG, "JPEG ENC (%s) reset done",
+				jpeg_enc_dev->soc_info.dev_name);
 		} else {
 			CAM_ERR(CAM_JPEG, "unexpected reset irq");
 		}
@@ -274,6 +276,7 @@ int cam_jpeg_enc_reset_hw(void *data,
 	void __iomem *mem_base;
 	unsigned long rem_jiffies;
 	unsigned long flags;
+	int rc = 0;
 
 	if (!jpeg_enc_dev) {
 		CAM_ERR(CAM_JPEG, "Invalid args");
@@ -320,9 +323,43 @@ int cam_jpeg_enc_reset_hw(void *data,
 	if (!rem_jiffies) {
 		CAM_ERR(CAM_JPEG, "error Reset Timeout");
 		core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
+		rc = -ETIMEDOUT;
 	}
 
 	mutex_unlock(&core_info->core_mutex);
+	return rc;
+}
+
+int cam_jpeg_enc_test_irq_line(void *data)
+{
+	struct cam_hw_info *jpeg_enc_dev = data;
+	struct cam_jpeg_enc_device_core_info *core_info = NULL;
+	int rc;
+
+	if (!data) {
+		CAM_ERR(CAM_JPEG, "invalid args");
+		return -EINVAL;
+	}
+
+	core_info = jpeg_enc_dev->core_info;
+
+	rc = cam_jpeg_enc_init_hw(data, NULL, 0);
+	if (rc) {
+		CAM_ERR(CAM_JPEG, "failed to init hw (rc=%d)", rc);
+		return rc;
+	}
+
+	rc = cam_jpeg_enc_reset_hw(data, NULL, 0);
+	if (rc)
+		CAM_ERR(CAM_JPEG, "failed to trigger reset irq (rc=%d)", rc);
+	else
+		CAM_INFO(CAM_JPEG, "verified JPEG DMA (%s) IRQ line",
+			jpeg_enc_dev->soc_info.dev_name);
+
+	rc = cam_jpeg_enc_deinit_hw(data, NULL, 0);
+	if (rc)
+		CAM_ERR(CAM_JPEG, "failed to de-init hw (rc=%d)", rc);
+
 	return 0;
 }
 

+ 3 - 0
drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef CAM_JPEG_ENC_CORE_H
@@ -117,6 +118,8 @@ int cam_jpeg_enc_reset_hw(void *device_priv,
 	void *reset_hw_args, uint32_t arg_size);
 int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
 	void *cmd_args, uint32_t arg_size);
+int cam_jpeg_enc_test_irq_line(void *data);
+
 irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data);
 
 /**

+ 2 - 1
drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -98,6 +98,7 @@ static int cam_jpeg_enc_component_bind(struct device *dev,
 	jpeg_enc_dev_intf->hw_ops.stop = cam_jpeg_enc_stop_hw;
 	jpeg_enc_dev_intf->hw_ops.reset = cam_jpeg_enc_reset_hw;
 	jpeg_enc_dev_intf->hw_ops.process_cmd = cam_jpeg_enc_process_cmd;
+	jpeg_enc_dev_intf->hw_ops.test_irq_line = cam_jpeg_enc_test_irq_line;
 	jpeg_enc_dev_intf->hw_type = CAM_JPEG_DEV_ENC;
 
 	platform_set_drvdata(pdev, jpeg_enc_dev_intf);