Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d7fd56eb authored by shiwgupt's avatar shiwgupt
Browse files

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

CRs-Fixed: 2692379
Change-Id: Ic13dc903e861e7c49bf3b375a66b96bfbe5d9c70
Signed-off-by: default avatarshiwgupt <shiwgupt@codeaurora.org>
parent c106d6be
Loading
Loading
Loading
Loading
+19 −14
Original line number Diff line number Diff line
@@ -177,10 +177,11 @@ 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;
@@ -188,6 +189,14 @@ static void cam_cci_dump_registers(struct cci_device *cci_dev,
	uint32_t read_data_reg_offset = 0x0;
	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;
	}

	/* CCI Top Registers */
	CAM_INFO(CAM_CCI, "****CCI TOP Registers ****");
	for (i = 0; i < DEBUG_TOP_REG_COUNT; i++) {
@@ -238,7 +247,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,
@@ -256,9 +265,8 @@ static uint32_t cam_cci_wait(struct cci_device *cci_dev,
	CAM_DBG(CAM_CCI, "wait DONE_for_completion_timeout");

	if (rc <= 0) {
#ifdef DUMP_CCI_REGISTERS
		cam_cci_dump_registers(cci_dev, master, queue);
#endif

		CAM_ERR(CAM_CCI, "wait for queue: %d", queue);
		if (rc == 0)
			rc = -ETIMEDOUT;
@@ -1031,9 +1039,8 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd,
			CAM_ERR(CAM_CCI,
				"wait_for_completion_timeout rc = %d FIFO buf_lvl:0x%x",
				rc, val);
#ifdef DUMP_CCI_REGISTERS
			cam_cci_dump_registers(cci_dev, master, queue);
#endif

			cam_cci_flush_queue(cci_dev, master);
			goto rel_mutex_q;
		}
@@ -1111,10 +1118,9 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd,
				CAM_ERR(CAM_CCI,
					"Failed to receive RD_DONE irq rc = %d FIFO buf_lvl:0x%x",
					rc, val);
				#ifdef DUMP_CCI_REGISTERS
				cam_cci_dump_registers(cci_dev,
					master, queue);
				#endif

				cam_cci_flush_queue(cci_dev, master);
				goto rel_mutex_q;
			}
@@ -1288,9 +1294,8 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd,
	rc = wait_for_completion_timeout(
		&cci_dev->cci_master_info[master].rd_done, CCI_TIMEOUT);
	if (rc <= 0) {
#ifdef DUMP_CCI_REGISTERS
		cam_cci_dump_registers(cci_dev, master, queue);
#endif

		if (rc == 0)
			rc = -ETIMEDOUT;
		val = cam_io_r_mb(base +
+101 −4
Original line number Diff line number Diff line
@@ -11,6 +11,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)
{
@@ -223,9 +224,22 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
	}
	if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) {
		cci_dev->cci_master_info[MASTER_0].status = -EINVAL;
		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK)
			CAM_ERR(CAM_CCI, "Base:%pK, M0 NACK ERROR: 0x%x",
		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERROR_BMSK) {
			CAM_ERR(CAM_CCI, "Base:%pK, M0_Q0 NACK ERROR: 0x%x",
				base, 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]);
		}
		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERROR_BMSK) {
			CAM_ERR(CAM_CCI, "Base:%pK, M0_Q1 NACK ERROR: 0x%x",
				base, 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]);
		}
		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK)
			CAM_ERR(CAM_CCI,
			"Base:%pK, M0 QUEUE_OVER/UNDER_FLOW OR CMD ERR: 0x%x",
@@ -238,9 +252,22 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
	}
	if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) {
		cci_dev->cci_master_info[MASTER_1].status = -EINVAL;
		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK)
			CAM_ERR(CAM_CCI, "Base:%pK, M1 NACK ERROR: 0x%x",
		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERROR_BMSK) {
			CAM_ERR(CAM_CCI, "Base:%pK, M1_Q0 NACK ERROR: 0x%x",
				base, 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]);
		}
		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERROR_BMSK) {
			CAM_ERR(CAM_CCI, "Base:%pK, M1_Q1 NACK ERROR: 0x%x",
				base, 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]);
		}
		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK)
			CAM_ERR(CAM_CCI,
			"Base:%pK, M1 QUEUE_OVER_UNDER_FLOW OR CMD ERROR:0x%x",
@@ -369,6 +396,70 @@ static long cam_cci_subdev_fops_compat_ioctl(struct file *file,
}
#endif

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_platform_probe(struct platform_device *pdev)
{
	struct cam_cpas_register_params cpas_parms;
@@ -448,6 +539,11 @@ static int cam_cci_platform_probe(struct platform_device *pdev)
		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;
	}
	return rc;
cci_no_resource:
	kfree(new_cci_dev);
@@ -461,6 +557,7 @@ static int cam_cci_device_remove(struct platform_device *pdev)
		v4l2_get_subdevdata(subdev);

	cam_cpas_unregister_client(cci_dev->cpas_handle);
	debugfs_remove_recursive(debugfs_root);
	cam_cci_soc_remove(pdev, cci_dev);
	devm_kfree(&pdev->dev, cci_dev);
	return 0;
+9 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/semaphore.h>
#include <linux/debugfs.h>
#include <media/cam_sensor.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
@@ -71,7 +72,11 @@
#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,
	MSM_SYNC_ENABLE,
@@ -201,6 +206,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 +236,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 {
@@ -302,6 +309,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);

#define VIDIOC_MSM_CCI_CFG \
	_IOWR('V', BASE_VIDIOC_PRIVATE + 23, struct cam_cci_ctrl)
+5 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2012-2015, 2017-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2015, 2017-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _CAM_CCI_HWREG_
@@ -56,6 +56,10 @@
#define CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK                          0x60EE6000
#define CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK                     0x18000000
#define CCI_IRQ_STATUS_0_I2C_M1_NACK_ERROR_BMSK                     0x60000000
#define CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERROR_BMSK                   0x8000000
#define CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERROR_BMSK                  0x10000000
#define CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERROR_BMSK                  0x20000000
#define CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERROR_BMSK                  0x40000000
#define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK                          0xEE0
#define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_ERROR_BMSK                       0xEE0000
#define CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK                              0x6