Parcourir la source

msm: camera: csiphy: Add debugfs support for csiphy

Add debugfs support for csiphy and create a new debugfs
for enable/disable csiphy irqs. Following command can be
used to enable the csiphy0 irqs:
adb shell "echo 0x1 >>
/sys/kernel/debug/camera_csiphy/csiphy0_en_irq_dump".

CRs-Fixed: 2829969
Change-Id: I769c84f0cd0bf048652cf2d186d900e470973b0a
Signed-off-by: Jigar Agrawal <[email protected]>
Jigar Agrawal il y a 4 ans
Parent
commit
18e1773e75

+ 6 - 19
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.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/module.h>
@@ -516,8 +516,6 @@ void cam_csiphy_cphy_irq_disable(struct csiphy_device *csiphy_dev)
 
 irqreturn_t cam_csiphy_irq(int irq_num, void *data)
 {
-	uint32_t irq;
-	uint8_t i;
 	struct csiphy_device *csiphy_dev =
 		(struct csiphy_device *)data;
 	struct cam_hw_soc_info *soc_info = NULL;
@@ -530,25 +528,14 @@ irqreturn_t cam_csiphy_irq(int irq_num, void *data)
 	}
 
 	soc_info = &csiphy_dev->soc_info;
-	base =  csiphy_dev->soc_info.reg_map[0].mem_base;
+	base = csiphy_dev->soc_info.reg_map[0].mem_base;
 	csiphy_reg = &csiphy_dev->ctrl_reg->csiphy_reg;
 
-	for (i = 0; i < csiphy_dev->num_irq_registers; i++) {
-		irq = cam_io_r(base +
-			csiphy_reg->mipi_csiphy_interrupt_status0_addr +
-			(0x4 * i));
-		cam_io_w_mb(irq, base +
-			csiphy_reg->mipi_csiphy_interrupt_clear0_addr +
-			(0x4 * i));
-		CAM_ERR_RATE_LIMIT(CAM_CSIPHY,
-			"CSIPHY%d_IRQ_STATUS_ADDR%d = 0x%x",
-			soc_info->index, i, irq);
-		cam_io_w_mb(0x0, base +
-			csiphy_reg->mipi_csiphy_interrupt_clear0_addr +
-			(0x4 * i));
+	if (csiphy_dev->enable_irq_dump) {
+		cam_csiphy_status_dmp(csiphy_dev);
+		cam_io_w_mb(0x1, base + csiphy_reg->mipi_csiphy_glbl_irq_cmd_addr);
+		cam_io_w_mb(0x0, base + csiphy_reg->mipi_csiphy_glbl_irq_cmd_addr);
 	}
-	cam_io_w_mb(0x1, base + csiphy_reg->mipi_csiphy_glbl_irq_cmd_addr);
-	cam_io_w_mb(0x0, base + csiphy_reg->mipi_csiphy_glbl_irq_cmd_addr);
 
 	return IRQ_HANDLED;
 }

+ 53 - 1
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.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 "cam_csiphy_dev.h"
@@ -10,6 +10,8 @@
 #include <media/cam_sensor.h>
 #include "camera_main.h"
 
+static struct dentry *root_dentry;
+
 static void cam_csiphy_subdev_handle_message(
 		struct v4l2_subdev *sd,
 		enum cam_subdev_message_type_t message_type,
@@ -29,6 +31,51 @@ static void cam_csiphy_subdev_handle_message(
 	}
 }
 
+static int cam_csiphy_debug_register(struct csiphy_device *csiphy_dev)
+{
+	int rc = 0;
+	struct dentry *dbgfileptr = NULL;
+	char debugfs_name[25];
+
+	if (!csiphy_dev) {
+		CAM_ERR(CAM_CSIPHY, "null CSIPHY dev ptr");
+		return -EINVAL;
+	}
+
+	if (!root_dentry) {
+		dbgfileptr = debugfs_create_dir("camera_csiphy", NULL);
+		if (!dbgfileptr) {
+			CAM_ERR(CAM_CSIPHY,
+				"Debugfs could not create directory!");
+			rc = -ENOENT;
+			goto end;
+		}
+		/* Store parent inode for cleanup in caller */
+		root_dentry = dbgfileptr;
+	}
+
+	snprintf(debugfs_name, 25, "%s%d%s", "csiphy",
+		csiphy_dev->soc_info.index,
+		"_en_irq_dump");
+	dbgfileptr = debugfs_create_bool(debugfs_name, 0644,
+		root_dentry, &csiphy_dev->enable_irq_dump);
+
+	if (IS_ERR(dbgfileptr)) {
+		if (PTR_ERR(dbgfileptr) == -ENODEV)
+			CAM_WARN(CAM_CSIPHY, "DebugFS not enabled in kernel!");
+		else
+			rc = PTR_ERR(dbgfileptr);
+	}
+end:
+	return rc;
+}
+
+static void cam_csiphy_debug_unregister(void)
+{
+	debugfs_remove_recursive(root_dentry);
+	root_dentry = NULL;
+}
+
 static long cam_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
 	unsigned int cmd, void *arg)
 {
@@ -212,6 +259,7 @@ static int cam_csiphy_component_bind(struct device *dev,
 	cpas_parms.userdata = new_csiphy_dev;
 
 	strlcpy(cpas_parms.identifier, "csiphy", CAM_HW_IDENTIFIER_LENGTH);
+
 	rc = cam_cpas_register_client(&cpas_parms);
 	if (rc) {
 		CAM_ERR(CAM_CSIPHY, "CPAS registration failed rc: %d", rc);
@@ -227,6 +275,9 @@ static int cam_csiphy_component_bind(struct device *dev,
 
 	CAM_DBG(CAM_CSIPHY, "%s component bound successfully",
 		pdev->name);
+
+	cam_csiphy_debug_register(new_csiphy_dev);
+
 	return rc;
 
 csiphy_unregister_subdev:
@@ -246,6 +297,7 @@ static void cam_csiphy_component_unbind(struct device *dev,
 	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
 	struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(subdev);
 
+	cam_csiphy_debug_unregister();
 	CAM_INFO(CAM_CSIPHY, "Unbind CSIPHY component");
 	cam_cpas_unregister_client(csiphy_dev->cpas_handle);
 	cam_csiphy_soc_release(csiphy_dev);

+ 3 - 3
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.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_CSIPHY_DEV_H_
@@ -64,8 +64,6 @@
 #define DPHY_LANE_3    BIT(6)
 #define DPHY_CLK_LN    BIT(7)
 
-#define ENABLE_IRQ false
-
 enum cam_csiphy_state {
 	CAM_CSIPHY_INIT,
 	CAM_CSIPHY_ACQUIRE,
@@ -266,6 +264,7 @@ struct cam_csiphy_param {
  * @combo_mode:                 Info regarding combo_mode is enable / disable
  * @ops:                        KMD operations
  * @crm_cb:                     Callback API pointers
+ * @enable_irq_dump:            Debugfs variable to enable hw IRQ register dump
  */
 struct csiphy_device {
 	char                           device_name[CAM_CTX_DEV_NAME_MAX_LENGTH];
@@ -298,6 +297,7 @@ struct csiphy_device {
 	uint8_t                        cphy_dphy_combo_mode;
 	struct cam_req_mgr_kmd_ops     ops;
 	struct cam_req_mgr_crm_cb     *crm_cb;
+	bool                           enable_irq_dump;
 };
 
 /**

+ 8 - 15
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_soc.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 "cam_csiphy_soc.h"
@@ -87,11 +87,11 @@ int32_t cam_csiphy_mem_dmp(struct cam_hw_soc_info *soc_info)
 int32_t cam_csiphy_status_dmp(struct csiphy_device *csiphy_dev)
 {
 	struct csiphy_reg_parms_t *csiphy_reg = NULL;
-	int32_t                   rc = 0;
-	resource_size_t           size = 0;
+	int32_t                    rc = 0;
+	resource_size_t            size = 0;
 	void __iomem              *phy_base = NULL;
-	int                       reg_id = 0;
-	uint32_t                  irq, status_reg, clear_reg;
+	int                        reg_id = 0;
+	uint32_t                   irq, status_reg, clear_reg;
 
 	if (!csiphy_dev) {
 		rc = -EINVAL;
@@ -110,13 +110,8 @@ int32_t cam_csiphy_status_dmp(struct csiphy_device *csiphy_dev)
 
 	if (phy_base != NULL) {
 		for (reg_id = 0; reg_id < size; reg_id++) {
-			uint32_t offset;
-
-			offset = status_reg + (0x4 * reg_id);
-			irq = cam_io_r(phy_base +  offset);
-			offset = clear_reg + (0x4 * reg_id);
-			cam_io_w_mb(irq, phy_base + offset);
-			cam_io_w_mb(0, phy_base + offset);
+			irq = cam_io_r(phy_base + status_reg + (0x4 * reg_id));
+			cam_io_w_mb(irq, phy_base + clear_reg + (0x4 * reg_id));
 
 			CAM_INFO(CAM_CSIPHY,
 				"CSIPHY%d_IRQ_STATUS_ADDR%d = 0x%x",
@@ -130,8 +125,6 @@ int32_t cam_csiphy_status_dmp(struct csiphy_device *csiphy_dev)
 	return rc;
 }
 
-
-
 enum cam_vote_level get_clk_vote_default(struct csiphy_device *csiphy_dev,
 	int32_t index)
 {
@@ -200,7 +193,7 @@ int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev, int32_t index)
 
 	vote_level = csiphy_dev->ctrl_reg->getclockvoting(csiphy_dev, index);
 	rc = cam_soc_util_enable_platform_resource(soc_info, true,
-		vote_level, ENABLE_IRQ);
+		vote_level, true);
 	if (rc < 0) {
 		CAM_ERR(CAM_CSIPHY, "failed to enable platform resources %d",
 			rc);