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

Commit 4574450a authored by Tejas Prajapati's avatar Tejas Prajapati
Browse files

msm: camera: common: Merge camera-kernel.3.1 changes in camera-kernel.4.0



msm: camera: cdm: Fix dangling pointer issue
msm: camera: cdm: change work record to atomic variable
msm: camera: utils: Adding device type to track device handles
msm: camera: tfe: Reduce stack footprint during bw vote
msm: camera: req_mgr: Thread switch delay detection mechanisms
msm: camera: cdm: Avoid submitting BL if FIFO is full
msm: camera: tfe: check cdm hang in the tfe config timeout
msm: camera: req_mgr: Delay detection mechanism
msm: camera: cdm: Debug info in case of cdm page fault
msm: camera: isp: Max context reduction for TFE in isp driver
msm: camera: ope: Maintain current clock value during acquire
msm: camera: req_mgr: Limit CAM_ERR log in case of no empty task
msm: camera: cdm: Decrement write-count only after Bl commit
msm: camera: isp: Added CSID recovery mechanism.

CRs-Fixed: 2792394
Change-Id: I1c7a903ae15b572acf3f6318cda7394cb6549c8d
Signed-off-by: default avatarTejas Prajapati <tpraja@codeaurora.org>
parent fabd1f7b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -440,6 +440,7 @@ struct cam_cdm_work_payload {
	uint32_t irq_status;
	uint32_t irq_data;
	int fifo_idx;
	ktime_t workq_scheduled_ts;
	struct work_struct work;
};

@@ -476,7 +477,7 @@ struct cam_cdm_bl_fifo {
	uint8_t bl_tag;
	uint32_t bl_depth;
	uint8_t last_bl_tag_done;
	uint32_t work_record;
	atomic_t work_record;
};

/**
+1 −4
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
	} else if (status == CAM_CDM_CB_STATUS_HW_RESET_DONE ||
			status == CAM_CDM_CB_STATUS_HW_FLUSH ||
			status == CAM_CDM_CB_STATUS_HW_RESUBMIT ||
			status == CAM_CDM_CB_STATUS_INVALID_BL_CMD ||
			status == CAM_CDM_CB_STATUS_HW_ERROR) {
		int client_idx;
		struct cam_cdm_bl_cb_request_entry *node =
@@ -800,13 +801,11 @@ int cam_cdm_process_cmd(void *hw_priv,
		}

		idx = CAM_CDM_GET_CLIENT_IDX(*handle);
		mutex_lock(&cdm_hw->hw_mutex);
		client = core->clients[idx];
		if (!client) {
			CAM_ERR(CAM_CDM,
				"Client not present for handle %d",
				*handle);
			mutex_unlock(&cdm_hw->hw_mutex);
			break;
		}

@@ -814,12 +813,10 @@ int cam_cdm_process_cmd(void *hw_priv,
			CAM_ERR(CAM_CDM,
				"handle mismatch, client handle %d index %d received handle %d",
				client->handle, idx, *handle);
			mutex_unlock(&cdm_hw->hw_mutex);
			break;
		}

		rc = cam_hw_cdm_hang_detect(cdm_hw, *handle);
		mutex_unlock(&cdm_hw->hw_mutex);
		break;
	}
	case CAM_CDM_HW_INTF_DUMP_DBG_REGS:
+205 −117
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include "cam_cdm_hw_reg_2_1.h"
#include "camera_main.h"
#include "cam_trace.h"
#include "cam_req_mgr_workq.h"

#define CAM_CDM_BL_FIFO_WAIT_TIMEOUT 2000
#define CAM_CDM_DBG_GEN_IRQ_USR_DATA 0xff
@@ -569,7 +570,7 @@ int cam_hw_cdm_wait_for_bl_fifo(
			CAM_DBG(CAM_CDM,
				"BL slot available_cnt=%d requested=%d",
				(available_bl_slots - 1), bl_count);
				rc = bl_count;
				rc = available_bl_slots - 1;
				break;
		} else if (0 == (available_bl_slots - 1)) {
			rc = cam_hw_cdm_enable_bl_done_irq(cdm_hw,
@@ -595,7 +596,7 @@ int cam_hw_cdm_wait_for_bl_fifo(
			if (cam_hw_cdm_enable_bl_done_irq(cdm_hw,
					false, fifo_idx))
				CAM_ERR(CAM_CDM, "Disable BL done irq failed");
			rc = 0;
			rc = 1;
			CAM_DBG(CAM_CDM, "CDM HW is ready for data");
		} else {
			rc = (bl_count - (available_bl_slots - 1));
@@ -702,6 +703,7 @@ int cam_hw_cdm_submit_gen_irq(
			core->bl_fifo[fifo_idx].bl_tag);
		list_del_init(&node->entry);
		kfree(node);
		node = NULL;
		rc = -EIO;
		goto end;
	}
@@ -712,6 +714,7 @@ int cam_hw_cdm_submit_gen_irq(
			core->bl_fifo[fifo_idx].bl_tag);
		list_del_init(&node->entry);
		kfree(node);
		node = NULL;
		rc = -EIO;
	}

@@ -922,8 +925,6 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
				rc = -EIO;
				break;
			}
		} else {
			write_count--;
		}

		if (req->data->type == CAM_CDM_BL_CMD_TYPE_MEM_HANDLE) {
@@ -1026,27 +1027,58 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
					rc = -EIO;
					break;
				}
				write_count--;
				CAM_DBG(CAM_CDM, "commit success BL %d tag=%d",
					i, core->bl_fifo[fifo_idx].bl_tag);
			}
			core->bl_fifo[fifo_idx].bl_tag++;

			if (cdm_cmd->cmd[i].enable_debug_gen_irq) {
				if (write_count == 0) {
					write_count =
						cam_hw_cdm_wait_for_bl_fifo(
						cdm_hw, 1, fifo_idx);
					if (write_count < 0) {
						CAM_ERR(CAM_CDM,
						"wait for bl fifo failed %d:%d",
						i, req->data->cmd_arrary_count);
						rc = -EIO;
						break;
					}
				}

				rc = cam_hw_cdm_submit_debug_gen_irq(cdm_hw,
					fifo_idx);
				if (rc == 0)
				if (rc == 0) {
					write_count--;
					core->bl_fifo[fifo_idx].bl_tag++;
				}
				if (core->bl_fifo[fifo_idx].bl_tag >=
						(bl_fifo->bl_depth -
						1))
					core->bl_fifo[fifo_idx].bl_tag = 0;
			}

			if ((req->data->flag == true) &&
			if ((!rc) && (req->data->flag == true) &&
				(i == (req->data->cmd_arrary_count -
				1))) {

				if (write_count == 0) {
					write_count =
						cam_hw_cdm_wait_for_bl_fifo(
						cdm_hw, 1, fifo_idx);
					if (write_count < 0) {
						CAM_ERR(CAM_CDM,
						"wait for bl fifo failed %d:%d",
						i, req->data->cmd_arrary_count);
						rc = -EIO;
						break;
					}
				}

				if (core->arbitration !=
					CAM_CDM_ARBITRATION_PRIORITY_BASED) {

					rc = cam_hw_cdm_submit_gen_irq(
						cdm_hw, req, fifo_idx,
						cdm_cmd->gen_irq_arb);
@@ -1080,7 +1112,8 @@ static void cam_hw_cdm_reset_cleanup(
	struct cam_cdm_bl_cb_request_entry *node, *tnode;
	bool flush_hw = false;

	if (test_bit(CAM_CDM_FLUSH_HW_STATUS, &core->cdm_status))
	if (test_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status) ||
		test_bit(CAM_CDM_FLUSH_HW_STATUS, &core->cdm_status))
		flush_hw = true;

	for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++) {
@@ -1104,10 +1137,11 @@ static void cam_hw_cdm_reset_cleanup(
			}
			list_del_init(&node->entry);
			kfree(node);
			node = NULL;
		}
		core->bl_fifo[i].bl_tag = 0;
		core->bl_fifo[i].last_bl_tag_done = -1;
		core->bl_fifo[i].work_record = 0;
		atomic_set(&core->bl_fifo[i].work_record, 0);
	}
}

@@ -1116,24 +1150,33 @@ static void cam_hw_cdm_work(struct work_struct *work)
	struct cam_cdm_work_payload *payload;
	struct cam_hw_info *cdm_hw;
	struct cam_cdm *core;
	int i;
	int i, fifo_idx;
	struct cam_cdm_bl_cb_request_entry *tnode = NULL;
	struct cam_cdm_bl_cb_request_entry *node = NULL;

	payload = container_of(work, struct cam_cdm_work_payload, work);
	if (payload) {
	if (!payload) {
		CAM_ERR(CAM_CDM, "NULL payload");
		return;
	}

	cdm_hw = payload->hw;
	core = (struct cam_cdm *)cdm_hw->core_info;
		if (payload->fifo_idx >= core->offsets->reg_data->num_bl_fifo) {
	fifo_idx = payload->fifo_idx;
	if (fifo_idx >= core->offsets->reg_data->num_bl_fifo) {
		CAM_ERR(CAM_CDM, "Invalid fifo idx %d",
				payload->fifo_idx);
			fifo_idx);
		kfree(payload);
		payload = NULL;
		return;
	}

	cam_req_mgr_thread_switch_delay_detect(
		payload->workq_scheduled_ts);

	CAM_DBG(CAM_CDM, "IRQ status=0x%x", payload->irq_status);
	if (payload->irq_status &
		CAM_CDM_IRQ_STATUS_INLINE_IRQ_MASK) {
			struct cam_cdm_bl_cb_request_entry *node, *tnode;

		CAM_DBG(CAM_CDM, "inline IRQ data=0x%x last tag: 0x%x",
			payload->irq_data,
			core->bl_fifo[payload->fifo_idx]
@@ -1142,35 +1185,32 @@ static void cam_hw_cdm_work(struct work_struct *work)
		if (payload->irq_data == 0xff) {
			CAM_INFO(CAM_CDM, "Debug genirq received");
			kfree(payload);
			payload = NULL;
			return;
		}

			mutex_lock(&core->bl_fifo[payload->fifo_idx]
				.fifo_lock);
		mutex_lock(&core->bl_fifo[fifo_idx].fifo_lock);

			if (core->bl_fifo[payload->fifo_idx].work_record)
				core->bl_fifo[payload->fifo_idx].work_record--;
		if (atomic_read(&core->bl_fifo[fifo_idx].work_record))
			atomic_dec(&core->bl_fifo[fifo_idx].work_record);

			if (list_empty(&core->bl_fifo[payload->fifo_idx]
		if (list_empty(&core->bl_fifo[fifo_idx]
				.bl_request_list)) {
			CAM_INFO(CAM_CDM,
				"Fifo list empty, idx %d tag %d arb %d",
					payload->fifo_idx, payload->irq_data,
				fifo_idx, payload->irq_data,
				core->arbitration);
				mutex_unlock(&core->bl_fifo[payload->fifo_idx]
			mutex_unlock(&core->bl_fifo[fifo_idx]
					.fifo_lock);
			return;
		}

			if (core->bl_fifo[payload->fifo_idx]
				.last_bl_tag_done !=
		if (core->bl_fifo[fifo_idx].last_bl_tag_done !=
			payload->irq_data) {
				core->bl_fifo[payload->fifo_idx]
					.last_bl_tag_done =
			core->bl_fifo[fifo_idx].last_bl_tag_done =
				payload->irq_data;
			list_for_each_entry_safe(node, tnode,
					&core->bl_fifo[payload->fifo_idx]
						.bl_request_list,
				&core->bl_fifo[fifo_idx].bl_request_list,
				entry) {
				if (node->request_type ==
					CAM_HW_CDM_BL_CB_CLIENT) {
@@ -1187,8 +1227,11 @@ static void cam_hw_cdm_work(struct work_struct *work)
				list_del_init(&node->entry);
				if (node->bl_tag == payload->irq_data) {
					kfree(node);
					node = NULL;
					break;
				}
				kfree(node);
				node = NULL;
			}
		} else {
			CAM_INFO(CAM_CDM,
@@ -1209,6 +1252,8 @@ static void cam_hw_cdm_work(struct work_struct *work)
	}
	if (payload->irq_status &
		CAM_CDM_IRQ_STATUS_ERRORS) {
		int reset_hw_hdl = 0x0;

		CAM_ERR_RATE_LIMIT(CAM_CDM,
			"CDM Error IRQ status %d\n",
			payload->irq_status);
@@ -1217,10 +1262,45 @@ static void cam_hw_cdm_work(struct work_struct *work)
		for (i = 0; i < core->offsets->reg_data->num_bl_fifo;
				i++)
			mutex_lock(&core->bl_fifo[i].fifo_lock);
		/*
		 * First pause CDM, If it fails still proceed
		 * to dump debug info
		 */
		cam_hw_cdm_pause_core(cdm_hw, true);
		cam_hw_cdm_dump_core_debug_registers(cdm_hw, true);

		if (payload->irq_status &
		CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK) {
			node = list_first_entry_or_null(
			&core->bl_fifo[payload->fifo_idx].bl_request_list,
			struct cam_cdm_bl_cb_request_entry, entry);

			if (node != NULL) {
				if (node->request_type ==
					CAM_HW_CDM_BL_CB_CLIENT) {
					cam_cdm_notify_clients(cdm_hw,
					CAM_CDM_CB_STATUS_INVALID_BL_CMD,
						(void *)node);
				} else if (node->request_type ==
					CAM_HW_CDM_BL_CB_INTERNAL) {
					CAM_ERR(CAM_CDM,
						"Invalid node=%pK %d", node,
						node->request_type);
				}
				list_del_init(&node->entry);
				kfree(node);
			}
		}
		/* Resume CDM back */
		cam_hw_cdm_pause_core(cdm_hw, false);
		for (i = 0; i < core->offsets->reg_data->num_bl_fifo;
				i++)
			mutex_unlock(&core->bl_fifo[i].fifo_lock);

		if (payload->irq_status &
			CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK)
			cam_hw_cdm_reset_hw(cdm_hw, reset_hw_hdl);

		mutex_unlock(&cdm_hw->hw_mutex);
		if (!(payload->irq_status &
				CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK))
@@ -1228,9 +1308,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
				&core->cdm_status);
	}
	kfree(payload);
	} else {
		CAM_ERR(CAM_CDM, "NULL payload");
	}
	payload = NULL;

}

@@ -1369,7 +1447,9 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
			return IRQ_HANDLED;
		}

		cdm_core->bl_fifo[i].work_record++;
		atomic_inc(&cdm_core->bl_fifo[i].work_record);
		payload[i]->workq_scheduled_ts = ktime_get();

		work_status = queue_work(
			cdm_core->bl_fifo[i].work_queue,
			&payload[i]->work);
@@ -1379,6 +1459,7 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
				"Failed to queue work for FIFO: %d irq=0x%x",
				i, payload[i]->irq_status);
			kfree(payload[i]);
			payload[i] = NULL;
		}
	}
	if (rst_done_cnt == cdm_core->offsets->reg_data->num_bl_fifo_irq) {
@@ -1629,6 +1710,7 @@ int cam_hw_cdm_handle_error_info(
		}
		list_del_init(&node->entry);
		kfree(node);
		node = NULL;
	}

	cam_hw_cdm_reset_cleanup(cdm_hw, reset_hw_hdl);
@@ -1679,20 +1761,14 @@ int cam_hw_cdm_hang_detect(
	cdm_core = (struct cam_cdm *)cdm_hw->core_info;

	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++)
		mutex_lock(&cdm_core->bl_fifo[i].fifo_lock);

	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++)
		if (cdm_core->bl_fifo[i].work_record) {
		if (atomic_read(&cdm_core->bl_fifo[i].work_record)) {
			CAM_WARN(CAM_CDM,
				"workqueue got delayed, bl_fifo: %d, work_record :%u",
				i, cdm_core->bl_fifo[i].work_record);
				"workqueue got delayed, work_record :%u",
				atomic_read(&cdm_core->bl_fifo[i].work_record));
			rc = 0;
			break;
		}

	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++)
		mutex_unlock(&cdm_core->bl_fifo[i].fifo_lock);

	return rc;
}

@@ -1797,7 +1873,7 @@ int cam_hw_cdm_init(void *hw_priv,
	}
	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) {
		cdm_core->bl_fifo[i].last_bl_tag_done = -1;
		cdm_core->bl_fifo[i].work_record = 0;
		atomic_set(&cdm_core->bl_fifo[i].work_record, 0);
	}

	rc = cam_hw_cdm_reset_hw(cdm_hw, reset_hw_hdl);
@@ -1856,6 +1932,7 @@ int cam_hw_cdm_deinit(void *hw_priv,
			&cdm_core->bl_fifo[i].bl_request_list, entry) {
			list_del_init(&node->entry);
			kfree(node);
			node = NULL;
		}
	}

@@ -1931,13 +2008,16 @@ static int cam_hw_cdm_component_bind(struct device *dev,
	cdm_hw = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
	if (!cdm_hw) {
		kfree(cdm_hw_intf);
		cdm_hw_intf = NULL;
		return -ENOMEM;
	}

	cdm_hw->core_info = kzalloc(sizeof(struct cam_cdm), GFP_KERNEL);
	if (!cdm_hw->core_info) {
		kfree(cdm_hw);
		cdm_hw = NULL;
		kfree(cdm_hw_intf);
		cdm_hw_intf = NULL;
		return -ENOMEM;
	}

@@ -2174,11 +2254,15 @@ static int cam_hw_cdm_component_bind(struct device *dev,
	mutex_unlock(&cdm_hw->hw_mutex);
release_private_mem:
	kfree(cdm_hw->soc_info.soc_private);
	cdm_hw->soc_info.soc_private = NULL;
release_mem:
	mutex_destroy(&cdm_hw->hw_mutex);
	kfree(cdm_hw_intf);
	cdm_hw_intf = NULL;
	kfree(cdm_hw->core_info);
	cdm_hw->core_info = NULL;
	kfree(cdm_hw);
	cdm_hw = NULL;
	return rc;
}

@@ -2256,9 +2340,13 @@ static void cam_hw_cdm_component_unbind(struct device *dev,

	mutex_destroy(&cdm_hw->hw_mutex);
	kfree(cdm_hw->soc_info.soc_private);
	cdm_hw->soc_info.soc_private = NULL;
	kfree(cdm_hw_intf);
	cdm_hw_intf = NULL;
	kfree(cdm_hw->core_info);
	cdm_hw->core_info = NULL;
	kfree(cdm_hw);
	cdm_hw = NULL;
}

const static struct component_ops cam_hw_cdm_component_ops = {
+37 −0
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@
#include "cam_cdm_util.h"
#include "cam_soc_util.h"

#define CAM_CDM_BL_CMD_MAX  25

/* enum cam_cdm_id - Enum for possible CAM CDM hardwares */
enum cam_cdm_id {
	CAM_CDM_VIRTUAL,
@@ -151,6 +153,41 @@ struct cam_cdm_bl_request {
	struct cam_cdm_bl_cmd cmd[1];
};

/**
 * struct cam_cdm_bl_data - last submiited CDM BL data
 *
 * @mem_handle : Input mem handle of bl cmd
 * @hw_addr    : Hw address of submitted Bl command
 * @offset     : Input offset of the actual bl cmd in the memory pointed
 *               by mem_handle
 * @len        : length of submitted Bl command to CDM.
 * @input_len  : Input length of the BL command, Cannot be more than 1MB and
 *           this is will be validated with offset+size of the memory pointed
 *           by mem_handle
 * @type       :  CDM bl cmd addr types.
 */
struct cam_cdm_bl_data {
	int32_t mem_handle;
	dma_addr_t hw_addr;
	uint32_t offset;
	size_t len;
	uint32_t  input_len;
	enum cam_cdm_bl_cmd_addr_type type;
};

/**
 * struct cam_cdm_bl_info
 *
 * @bl_count   : No. of Bl commands submiited to CDM.
 * @cmd        : payload holding the BL cmd's arrary
 *               that is sumbitted.
 *
 */
struct cam_cdm_bl_info {
	int32_t bl_count;
	struct cam_cdm_bl_data cmd[CAM_CDM_BL_CMD_MAX];
};

/**
 * @brief : API to get the CDM capabilities for a camera device type
 *
+66 −12
Original line number Diff line number Diff line
@@ -689,25 +689,53 @@ int cam_cdm_util_cmd_buf_write(void __iomem **current_device_base,
	return ret;
}

static long cam_cdm_util_dump_dmi_cmd(uint32_t *cmd_buf_addr)
static long cam_cdm_util_dump_dmi_cmd(uint32_t *cmd_buf_addr,
	uint32_t *cmd_buf_addr_end)
{
	long ret = 0;
	struct cdm_dmi_cmd *p_dmi_cmd;
	uint32_t *temp_ptr = cmd_buf_addr;

	p_dmi_cmd = (struct cdm_dmi_cmd *)cmd_buf_addr;
	temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI];
	ret += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI];
	CAM_INFO(CAM_CDM, "DMI");

	if (temp_ptr > cmd_buf_addr_end)
		CAM_ERR(CAM_CDM,
			"Invalid cmd start addr:%pK end addr:%pK",
			temp_ptr, cmd_buf_addr_end);

	CAM_INFO(CAM_CDM,
		"DMI: LEN: %u DMIAddr: 0x%X DMISel: 0x%X LUT_addr: 0x%X",
		p_dmi_cmd->length, p_dmi_cmd->DMIAddr,
		p_dmi_cmd->DMISel, p_dmi_cmd->addr);
	return ret;
}

static long cam_cdm_util_dump_buff_indirect(uint32_t *cmd_buf_addr)
static long cam_cdm_util_dump_buff_indirect(uint32_t *cmd_buf_addr,
	uint32_t *cmd_buf_addr_end)
{
	long ret = 0;
	struct cdm_indirect_cmd *p_indirect_cmd;
	uint32_t *temp_ptr = cmd_buf_addr;

	p_indirect_cmd = (struct cdm_indirect_cmd *)cmd_buf_addr;
	temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT];
	ret += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT];
	CAM_INFO(CAM_CDM, "Buff Indirect");

	if (temp_ptr > cmd_buf_addr_end)
		CAM_ERR(CAM_CDM,
			"Invalid cmd start addr:%pK end addr:%pK",
			temp_ptr, cmd_buf_addr_end);

	CAM_INFO(CAM_CDM,
		"Buff Indirect: LEN: %u addr: 0x%X",
		p_indirect_cmd->length, p_indirect_cmd->addr);
	return ret;
}

static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr)
static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr,
	uint32_t *cmd_buf_addr_end)
{
	long ret = 0;
	struct cdm_regcontinuous_cmd *p_regcont_cmd;
@@ -722,6 +750,12 @@ static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr)
		p_regcont_cmd->count, p_regcont_cmd->offset);

	for (i = 0; i < p_regcont_cmd->count; i++) {
		if (temp_ptr > cmd_buf_addr_end) {
			CAM_ERR(CAM_CDM,
				"Invalid cmd(%d) start addr:%pK end addr:%pK",
				i, temp_ptr, cmd_buf_addr_end);
			break;
		}
		CAM_INFO(CAM_CDM, "DATA_%d: 0x%X", i,
			*temp_ptr);
		temp_ptr++;
@@ -731,7 +765,8 @@ static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr)
	return ret;
}

static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr)
static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr,
	uint32_t *cmd_buf_addr_end)
{
	struct cdm_regrandom_cmd *p_regrand_cmd;
	uint32_t *temp_ptr = cmd_buf_addr;
@@ -746,6 +781,12 @@ static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr)
		p_regrand_cmd->count);

	for (i = 0; i < p_regrand_cmd->count; i++) {
		if (temp_ptr > cmd_buf_addr_end) {
			CAM_ERR(CAM_CDM,
				"Invalid cmd(%d) start addr:%pK end addr:%pK",
				i, temp_ptr, cmd_buf_addr_end);
			break;
		}
		CAM_INFO(CAM_CDM, "OFFSET_%d: 0x%X DATA_%d: 0x%X",
			i, *temp_ptr & CAM_CDM_REG_OFFSET_MASK, i,
			*(temp_ptr + 1));
@@ -778,15 +819,22 @@ static long cam_cdm_util_dump_wait_event_cmd(uint32_t *cmd_buf_addr)
	return ret;
}

static long cam_cdm_util_dump_change_base_cmd(uint32_t *cmd_buf_addr)
static long cam_cdm_util_dump_change_base_cmd(uint32_t *cmd_buf_addr,
	uint32_t *cmd_buf_addr_end)
{
	long ret = 0;
	struct cdm_changebase_cmd *p_cbase_cmd;
	uint32_t *temp_ptr = cmd_buf_addr;

	p_cbase_cmd = (struct cdm_changebase_cmd *)temp_ptr;
	temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE];
	ret += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE];

	if (temp_ptr > cmd_buf_addr_end)
		CAM_ERR(CAM_CDM,
			"Invalid cmd start addr:%pK end addr:%pK",
			temp_ptr, cmd_buf_addr_end);

	CAM_INFO(CAM_CDM, "CHANGE_BASE: 0x%X",
		p_cbase_cmd->base);

@@ -819,6 +867,7 @@ void cam_cdm_util_dump_cmd_buf(
	uint32_t *cmd_buf_start, uint32_t *cmd_buf_end)
{
	uint32_t *buf_now = cmd_buf_start;
	uint32_t *buf_end = cmd_buf_end;
	uint32_t cmd = 0;

	if (!cmd_buf_start || !cmd_buf_end) {
@@ -834,16 +883,20 @@ void cam_cdm_util_dump_cmd_buf(
		case CAM_CDM_CMD_DMI:
		case CAM_CDM_CMD_DMI_32:
		case CAM_CDM_CMD_DMI_64:
			buf_now += cam_cdm_util_dump_dmi_cmd(buf_now);
			buf_now += cam_cdm_util_dump_dmi_cmd(buf_now,
				buf_end);
			break;
		case CAM_CDM_CMD_REG_CONT:
			buf_now += cam_cdm_util_dump_reg_cont_cmd(buf_now);
			buf_now += cam_cdm_util_dump_reg_cont_cmd(buf_now,
				buf_end);
			break;
		case CAM_CDM_CMD_REG_RANDOM:
			buf_now += cam_cdm_util_dump_reg_random_cmd(buf_now);
			buf_now += cam_cdm_util_dump_reg_random_cmd(buf_now,
				buf_end);
			break;
		case CAM_CDM_CMD_BUFF_INDIRECT:
			buf_now += cam_cdm_util_dump_buff_indirect(buf_now);
			buf_now += cam_cdm_util_dump_buff_indirect(buf_now,
				buf_end);
			break;
		case CAM_CDM_CMD_GEN_IRQ:
			buf_now += cam_cdm_util_dump_gen_irq_cmd(buf_now);
@@ -852,7 +905,8 @@ void cam_cdm_util_dump_cmd_buf(
			buf_now += cam_cdm_util_dump_wait_event_cmd(buf_now);
			break;
		case CAM_CDM_CMD_CHANGE_BASE:
			buf_now += cam_cdm_util_dump_change_base_cmd(buf_now);
			buf_now += cam_cdm_util_dump_change_base_cmd(buf_now,
				buf_end);
			break;
		case CAM_CDM_CMD_PERF_CTRL:
			buf_now += cam_cdm_util_dump_perf_ctrl_cmd(buf_now);
Loading