Bläddra i källkod

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 år sedan
förälder
incheckning
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);
 	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)
 	enum cci_i2c_master_t master, enum cci_i2c_queue_t queue)
 {
 {
+	uint32_t dump_en = 0;
 	uint32_t read_val = 0;
 	uint32_t read_val = 0;
 	uint32_t i = 0;
 	uint32_t i = 0;
 	uint32_t reg_offset = 0;
 	uint32_t reg_offset = 0;
 	void __iomem *base = cci_dev->soc_info.reg_map[0].mem_base;
 	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 ****",
 	CAM_INFO(CAM_CCI, "**** CCI:%d register dump ****",
-		cci_dev->soc_info->index);
+		cci_dev->soc_info.index);
 
 
 	/* CCI Top Registers */
 	/* CCI Top Registers */
 	CAM_INFO(CAM_CCI, "****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);
 			reg_offset, read_val);
 	}
 	}
 }
 }
-#endif
+EXPORT_SYMBOL(cam_cci_dump_registers);
 
 
 static uint32_t cam_cci_wait(struct cci_device *cci_dev,
 static uint32_t cam_cci_wait(struct cci_device *cci_dev,
 	enum cci_i2c_master_t master,
 	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(
 	if (!wait_for_completion_timeout(
 		&cci_dev->cci_master_info[master].report_q[queue],
 		&cci_dev->cci_master_info[master].report_q[queue],
 		CCI_TIMEOUT)) {
 		CCI_TIMEOUT)) {
-#ifdef DUMP_CCI_REGISTERS
 		cam_cci_dump_registers(cci_dev, master, queue);
 		cam_cci_dump_registers(cci_dev, master, queue);
-#endif
+
 		CAM_ERR(CAM_CCI,
 		CAM_ERR(CAM_CCI,
 			"wait timeout for cci:%d, Maser:%d, Queue:%d, rc=%d",
 			"wait timeout for cci:%d, Maser:%d, Queue:%d, rc=%d",
 			cci_dev->soc_info.index, master, queue, rc);
 			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,
 			CAM_ERR(CAM_CCI,
 				"wait timeout for th_complete cci: %d, master: %d, FIFO buf_lvl:0x%x, rc: %d",
 				"wait timeout for th_complete cci: %d, master: %d, FIFO buf_lvl:0x%x, rc: %d",
 				cci_dev->soc_info.index, master, val, rc);
 				cci_dev->soc_info.index, master, val, rc);
-#ifdef DUMP_CCI_REGISTERS
 			cam_cci_dump_registers(cci_dev, master, queue);
 			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;
 			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",
 					"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,
 					cci_dev->soc_info.index, master,
 					val, rc);
 					val, rc);
-				#ifdef DUMP_CCI_REGISTERS
-					cam_cci_dump_registers(cci_dev,
+				cam_cci_dump_registers(cci_dev,
 						master, queue);
 						master, queue);
-				#endif
-					cam_cci_flush_queue(cci_dev, master);
+
+				cam_cci_flush_queue(cci_dev, master);
 				goto rel_mutex_q;
 				goto rel_mutex_q;
 			}
 			}
 
 
@@ -1364,9 +1370,8 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd,
 
 
 	if (!wait_for_completion_timeout(
 	if (!wait_for_completion_timeout(
 		&cci_dev->cci_master_info[master].rd_done, CCI_TIMEOUT)) {
 		&cci_dev->cci_master_info[master].rd_done, CCI_TIMEOUT)) {
-#ifdef DUMP_CCI_REGISTERS
 		cam_cci_dump_registers(cci_dev, master, queue);
 		cam_cci_dump_registers(cci_dev, master, queue);
-#endif
+
 		rc = -ETIMEDOUT;
 		rc = -ETIMEDOUT;
 		val = cam_io_r_mb(base +
 		val = cam_io_r_mb(base +
 			CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100);
 			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
 #define CCI_MAX_DELAY 1000000
 
 
 static struct v4l2_subdev *g_cci_subdev[MAX_CCI];
 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)
 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,
 			CAM_ERR(CAM_CCI,
 				"Base:%pK,cci: %d, M0_Q0 NACK ERROR: 0x%x",
 				"Base:%pK,cci: %d, M0_Q0 NACK ERROR: 0x%x",
 				base, cci_dev->soc_info.index, irq_status0);
 				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]
 			complete_all(&cci_dev->cci_master_info[MASTER_0]
 				.report_q[QUEUE_0]);
 				.report_q[QUEUE_0]);
 		}
 		}
@@ -240,6 +243,8 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
 			CAM_ERR(CAM_CCI,
 			CAM_ERR(CAM_CCI,
 				"Base:%pK,cci: %d, M0_Q1 NACK ERROR: 0x%x",
 				"Base:%pK,cci: %d, M0_Q1 NACK ERROR: 0x%x",
 				base, cci_dev->soc_info.index, irq_status0);
 				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]
 			complete_all(&cci_dev->cci_master_info[MASTER_0]
 			.report_q[QUEUE_1]);
 			.report_q[QUEUE_1]);
 		}
 		}
@@ -261,6 +266,8 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
 			CAM_ERR(CAM_CCI,
 			CAM_ERR(CAM_CCI,
 				"Base:%pK, cci: %d, M1_Q0 NACK ERROR: 0x%x",
 				"Base:%pK, cci: %d, M1_Q0 NACK ERROR: 0x%x",
 				base, cci_dev->soc_info.index, irq_status0);
 				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]
 			complete_all(&cci_dev->cci_master_info[MASTER_1]
 			.report_q[QUEUE_0]);
 			.report_q[QUEUE_0]);
 		}
 		}
@@ -268,6 +275,8 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
 			CAM_ERR(CAM_CCI,
 			CAM_ERR(CAM_CCI,
 				"Base:%pK, cci: %d, M1_Q1 NACK ERROR: 0x%x",
 				"Base:%pK, cci: %d, M1_Q1 NACK ERROR: 0x%x",
 				base, cci_dev->soc_info.index, irq_status0);
 				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]
 			complete_all(&cci_dev->cci_master_info[MASTER_1]
 			.report_q[QUEUE_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 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,
 static int cam_cci_component_bind(struct device *dev,
 	struct device *master_dev, void *data)
 	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",
 	CAM_DBG(CAM_CCI, "CPAS registration successful handle=%d",
 		cpas_parms.client_handle);
 		cpas_parms.client_handle);
 	new_cci_dev->cpas_handle = 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");
 	CAM_DBG(CAM_CCI, "Component bound successfully");
 	return rc;
 	return rc;
 
 
@@ -468,6 +547,7 @@ static void cam_cci_component_unbind(struct device *dev,
 		v4l2_get_subdevdata(subdev);
 		v4l2_get_subdevdata(subdev);
 
 
 	cam_cpas_unregister_client(cci_dev->cpas_handle);
 	cam_cpas_unregister_client(cci_dev->cpas_handle);
+	debugfs_remove_recursive(debugfs_root);
 	cam_cci_soc_remove(pdev, cci_dev);
 	cam_cci_soc_remove(pdev, cci_dev);
 	rc = cam_unregister_subdev(&(cci_dev->v4l2_dev_str));
 	rc = cam_unregister_subdev(&(cci_dev->v4l2_dev_str));
 	if (rc < 0)
 	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/iommu.h>
 #include <linux/timer.h>
 #include <linux/timer.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
+#include <linux/debugfs.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/semaphore.h>
 #include <linux/semaphore.h>
 #include <media/cam_sensor.h>
 #include <media/cam_sensor.h>
@@ -68,6 +69,9 @@
 #define PRIORITY_QUEUE (QUEUE_0)
 #define PRIORITY_QUEUE (QUEUE_0)
 #define SYNC_QUEUE (QUEUE_1)
 #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
 #define CCI_VERSION_1_2_9 0x10020009
 enum cci_i2c_sync {
 enum cci_i2c_sync {
 	MSM_SYNC_DISABLE,
 	MSM_SYNC_DISABLE,
@@ -200,6 +204,7 @@ enum cam_cci_state_t {
  * @irqs_disabled:              Mask for IRQs that are disabled
  * @irqs_disabled:              Mask for IRQs that are disabled
  * @init_mutex:                 Mutex for maintaining refcount for attached
  * @init_mutex:                 Mutex for maintaining refcount for attached
  *                              devices to cci during init/deinit.
  *                              devices to cci during init/deinit.
+ * @dump_en:                    To enable the selective dump
  */
  */
 struct cci_device {
 struct cci_device {
 	struct v4l2_subdev subdev;
 	struct v4l2_subdev subdev;
@@ -230,6 +235,7 @@ struct cci_device {
 	bool is_burst_read;
 	bool is_burst_read;
 	uint32_t irqs_disabled;
 	uint32_t irqs_disabled;
 	struct mutex init_mutex;
 	struct mutex init_mutex;
+	uint64_t  dump_en;
 };
 };
 
 
 enum cam_cci_i2c_cmd_type {
 enum cam_cci_i2c_cmd_type {
@@ -301,6 +307,8 @@ struct cci_write_async {
 irqreturn_t cam_cci_irq(int irq_num, void *data);
 irqreturn_t cam_cci_irq(int irq_num, void *data);
 
 
 struct v4l2_subdev *cam_cci_get_subdev(int cci_dev_index);
 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.
  * @brief : API to register CCI hw to platform framework.