Explorar o código

Merge "msm: camera: cci: Enable compilation for cci dump code" into camera-kernel.lnx.4.0

Camera Software Integration %!s(int64=4) %!d(string=hai) anos
pai
achega
6b144e04c6

+ 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.