Bladeren bron

msm: camera: cci: Enable compilation for cci dump code

CCI register dump is only enable when dump flag is defined. Remove
this flag and add control via debugfs entry. This change helps
debugfs entry to control cci device individually on the fly for
debugging rather than to rebuild.

CRs-Fixed: 2692379
Change-Id: Ic13dc903e861e7c49bf3b375a66b96bfbe5d9c70
Signed-off-by: shiwgupt <[email protected]>
shiwgupt 4 jaren geleden
bovenliggende
commit
c5f8e70b0f

+ 19 - 14
drivers/cam_sensor_module/cam_cci/cam_cci_core.c

@@ -193,17 +193,26 @@ static int32_t cam_cci_lock_queue(struct cci_device *cci_dev,
 	return cam_cci_write_i2c_queue(cci_dev, val, master, queue);
 }
 
-#ifdef DUMP_CCI_REGISTERS
-static void cam_cci_dump_registers(struct cci_device *cci_dev,
+
+void cam_cci_dump_registers(struct cci_device *cci_dev,
 	enum cci_i2c_master_t master, enum cci_i2c_queue_t queue)
 {
+	uint32_t dump_en = 0;
 	uint32_t read_val = 0;
 	uint32_t i = 0;
 	uint32_t reg_offset = 0;
 	void __iomem *base = cci_dev->soc_info.reg_map[0].mem_base;
 
+	dump_en = cci_dev->dump_en;
+	if (!(dump_en & CAM_CCI_NACK_DUMP_EN) &&
+		!(dump_en & CAM_CCI_TIMEOUT_DUMP_EN)) {
+		CAM_DBG(CAM_CCI,
+			"Nack and Timeout dump is not enabled");
+		return;
+	}
+
 	CAM_INFO(CAM_CCI, "**** CCI:%d register dump ****",
-		cci_dev->soc_info->index);
+		cci_dev->soc_info.index);
 
 	/* CCI Top Registers */
 	CAM_INFO(CAM_CCI, "****CCI TOP Registers ****");
@@ -247,7 +256,7 @@ static void cam_cci_dump_registers(struct cci_device *cci_dev,
 			reg_offset, read_val);
 	}
 }
-#endif
+EXPORT_SYMBOL(cam_cci_dump_registers);
 
 static uint32_t cam_cci_wait(struct cci_device *cci_dev,
 	enum cci_i2c_master_t master,
@@ -263,9 +272,8 @@ static uint32_t cam_cci_wait(struct cci_device *cci_dev,
 	if (!wait_for_completion_timeout(
 		&cci_dev->cci_master_info[master].report_q[queue],
 		CCI_TIMEOUT)) {
-#ifdef DUMP_CCI_REGISTERS
 		cam_cci_dump_registers(cci_dev, master, queue);
-#endif
+
 		CAM_ERR(CAM_CCI,
 			"wait timeout for cci:%d, Maser:%d, Queue:%d, rc=%d",
 			cci_dev->soc_info.index, master, queue, rc);
@@ -1076,9 +1084,8 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd,
 			CAM_ERR(CAM_CCI,
 				"wait timeout for th_complete cci: %d, master: %d, FIFO buf_lvl:0x%x, rc: %d",
 				cci_dev->soc_info.index, master, val, rc);
-#ifdef DUMP_CCI_REGISTERS
 			cam_cci_dump_registers(cci_dev, master, queue);
-#endif
+
 			cam_cci_flush_queue(cci_dev, master);
 			goto rel_mutex_q;
 		}
@@ -1167,11 +1174,10 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd,
 					"wait timeout for RD_DONE irq for cci: %d, master: %d, rc = %d FIFO buf_lvl:0x%x, rc: %d",
 					cci_dev->soc_info.index, master,
 					val, rc);
-				#ifdef DUMP_CCI_REGISTERS
-					cam_cci_dump_registers(cci_dev,
+				cam_cci_dump_registers(cci_dev,
 						master, queue);
-				#endif
-					cam_cci_flush_queue(cci_dev, master);
+
+				cam_cci_flush_queue(cci_dev, master);
 				goto rel_mutex_q;
 			}
 
@@ -1364,9 +1370,8 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd,
 
 	if (!wait_for_completion_timeout(
 		&cci_dev->cci_master_info[master].rd_done, CCI_TIMEOUT)) {
-#ifdef DUMP_CCI_REGISTERS
 		cam_cci_dump_registers(cci_dev, master, queue);
-#endif
+
 		rc = -ETIMEDOUT;
 		val = cam_io_r_mb(base +
 			CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100);

+ 80 - 0
drivers/cam_sensor_module/cam_cci/cam_cci_dev.c

@@ -12,6 +12,7 @@
 #define CCI_MAX_DELAY 1000000
 
 static struct v4l2_subdev *g_cci_subdev[MAX_CCI];
+static struct dentry *debugfs_root;
 
 struct v4l2_subdev *cam_cci_get_subdev(int cci_dev_index)
 {
@@ -233,6 +234,8 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
 			CAM_ERR(CAM_CCI,
 				"Base:%pK,cci: %d, M0_Q0 NACK ERROR: 0x%x",
 				base, cci_dev->soc_info.index, irq_status0);
+			cam_cci_dump_registers(cci_dev, MASTER_0,
+					QUEUE_0);
 			complete_all(&cci_dev->cci_master_info[MASTER_0]
 				.report_q[QUEUE_0]);
 		}
@@ -240,6 +243,8 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
 			CAM_ERR(CAM_CCI,
 				"Base:%pK,cci: %d, M0_Q1 NACK ERROR: 0x%x",
 				base, cci_dev->soc_info.index, irq_status0);
+			cam_cci_dump_registers(cci_dev, MASTER_0,
+					QUEUE_1);
 			complete_all(&cci_dev->cci_master_info[MASTER_0]
 			.report_q[QUEUE_1]);
 		}
@@ -261,6 +266,8 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
 			CAM_ERR(CAM_CCI,
 				"Base:%pK, cci: %d, M1_Q0 NACK ERROR: 0x%x",
 				base, cci_dev->soc_info.index, irq_status0);
+			cam_cci_dump_registers(cci_dev, MASTER_1,
+					QUEUE_0);
 			complete_all(&cci_dev->cci_master_info[MASTER_1]
 			.report_q[QUEUE_0]);
 		}
@@ -268,6 +275,8 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
 			CAM_ERR(CAM_CCI,
 				"Base:%pK, cci: %d, M1_Q1 NACK ERROR: 0x%x",
 				base, cci_dev->soc_info.index, irq_status0);
+			cam_cci_dump_registers(cci_dev, MASTER_1,
+				QUEUE_1);
 			complete_all(&cci_dev->cci_master_info[MASTER_1]
 			.report_q[QUEUE_1]);
 		}
@@ -372,6 +381,70 @@ static const struct v4l2_subdev_ops cci_subdev_ops = {
 
 static const struct v4l2_subdev_internal_ops cci_subdev_intern_ops;
 
+static int cam_cci_get_debug(void *data, u64 *val)
+{
+	struct cci_device *cci_dev = (struct cci_device *)data;
+
+	*val = cci_dev->dump_en;
+
+	return 0;
+}
+
+static int cam_cci_set_debug(void *data, u64 val)
+{
+	struct cci_device *cci_dev = (struct cci_device *)data;
+
+	cci_dev->dump_en = val;
+
+	return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(cam_cci_debug,
+	cam_cci_get_debug,
+	cam_cci_set_debug, "%16llu\n");
+
+static int cam_cci_create_debugfs_entry(struct cci_device *cci_dev)
+{
+	int rc = 0;
+	struct dentry *dbgfileptr = NULL;
+
+	if (!debugfs_root) {
+		dbgfileptr = debugfs_create_dir("cam_cci", NULL);
+		if (!dbgfileptr) {
+			CAM_ERR(CAM_CCI, "debugfs directory creation fail");
+			rc = -ENOENT;
+			goto end;
+		}
+		debugfs_root = dbgfileptr;
+	}
+
+	if (cci_dev->soc_info.index == 0) {
+		dbgfileptr = debugfs_create_file("en_dump_cci0", 0644,
+			debugfs_root, cci_dev, &cam_cci_debug);
+		if (IS_ERR(dbgfileptr)) {
+			if (PTR_ERR(dbgfileptr) == -ENODEV)
+				CAM_WARN(CAM_CCI, "DebugFS not enabled");
+			else {
+				rc = PTR_ERR(dbgfileptr);
+				goto end;
+			}
+		}
+	} else {
+		dbgfileptr = debugfs_create_file("en_dump_cci1", 0644,
+			debugfs_root, cci_dev, &cam_cci_debug);
+		if (IS_ERR(dbgfileptr)) {
+			if (PTR_ERR(dbgfileptr) == -ENODEV)
+				CAM_WARN(CAM_CCI, "DebugFS not enabled");
+			else {
+				rc = PTR_ERR(dbgfileptr);
+				goto end;
+			}
+		}
+	}
+end:
+	return rc;
+}
+
 static int cam_cci_component_bind(struct device *dev,
 	struct device *master_dev, void *data)
 {
@@ -447,6 +520,12 @@ static int cam_cci_component_bind(struct device *dev,
 	CAM_DBG(CAM_CCI, "CPAS registration successful handle=%d",
 		cpas_parms.client_handle);
 	new_cci_dev->cpas_handle = cpas_parms.client_handle;
+
+	rc = cam_cci_create_debugfs_entry(new_cci_dev);
+	if (rc) {
+		CAM_WARN(CAM_CCI, "debugfs creation failed");
+		rc = 0;
+	}
 	CAM_DBG(CAM_CCI, "Component bound successfully");
 	return rc;
 
@@ -468,6 +547,7 @@ static void cam_cci_component_unbind(struct device *dev,
 		v4l2_get_subdevdata(subdev);
 
 	cam_cpas_unregister_client(cci_dev->cpas_handle);
+	debugfs_remove_recursive(debugfs_root);
 	cam_cci_soc_remove(pdev, cci_dev);
 	rc = cam_unregister_subdev(&(cci_dev->v4l2_dev_str));
 	if (rc < 0)

+ 8 - 0
drivers/cam_sensor_module/cam_cci/cam_cci_dev.h

@@ -16,6 +16,7 @@
 #include <linux/iommu.h>
 #include <linux/timer.h>
 #include <linux/kernel.h>
+#include <linux/debugfs.h>
 #include <linux/platform_device.h>
 #include <linux/semaphore.h>
 #include <media/cam_sensor.h>
@@ -68,6 +69,9 @@
 #define PRIORITY_QUEUE (QUEUE_0)
 #define SYNC_QUEUE (QUEUE_1)
 
+#define CAM_CCI_NACK_DUMP_EN      BIT(1)
+#define CAM_CCI_TIMEOUT_DUMP_EN   BIT(2)
+
 #define CCI_VERSION_1_2_9 0x10020009
 enum cci_i2c_sync {
 	MSM_SYNC_DISABLE,
@@ -200,6 +204,7 @@ enum cam_cci_state_t {
  * @irqs_disabled:              Mask for IRQs that are disabled
  * @init_mutex:                 Mutex for maintaining refcount for attached
  *                              devices to cci during init/deinit.
+ * @dump_en:                    To enable the selective dump
  */
 struct cci_device {
 	struct v4l2_subdev subdev;
@@ -230,6 +235,7 @@ struct cci_device {
 	bool is_burst_read;
 	uint32_t irqs_disabled;
 	struct mutex init_mutex;
+	uint64_t  dump_en;
 };
 
 enum cam_cci_i2c_cmd_type {
@@ -301,6 +307,8 @@ struct cci_write_async {
 irqreturn_t cam_cci_irq(int irq_num, void *data);
 
 struct v4l2_subdev *cam_cci_get_subdev(int cci_dev_index);
+void cam_cci_dump_registers(struct cci_device *cci_dev,
+		enum cci_i2c_master_t master, enum cci_i2c_queue_t queue);
 
 /**
  * @brief : API to register CCI hw to platform framework.