msm: camera: isp: LDAR Dump ISP information
When user space detects an error or does not receive response for a request, Lets do a reset(LDAR) is triggered. Before LDAR, user space sends flush command to the kernel space. In order to debug the cause for this situation and to dump the information, user space sends a dump command to kernel space before sending flush. As a part of this command, it passes the culprit request id and the buffer into which the information can be dumped. Kernel space traverses across the drivers and find the culprit hw and dumps the relevant information in the buffer. This data is written to a file for offline processing. This commit dumps the IFE, CSID registers, LUT tables and context information, cmd buffers, timestamps information for submit, apply, RUP, epoch and buffdones of the last 20 requests. CRs-Fixed: 2612116 Change-Id: If83db59458c1e5ad778f3fa90cbc730122491c54 Signed-off-by: Gaurav Jindal <gjindal@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
2460a8e82a
commit
e3f5738e43
@@ -823,3 +823,171 @@ void cam_cdm_util_dump_cmd_buf(
|
||||
}
|
||||
} while (buf_now <= cmd_buf_end);
|
||||
}
|
||||
|
||||
static uint32_t cam_cdm_util_dump_reg_cont_cmd_v2(
|
||||
uint32_t *cmd_buf_addr,
|
||||
struct cam_cdm_cmd_buf_dump_info *dump_info)
|
||||
{
|
||||
int i;
|
||||
long ret;
|
||||
uint8_t *dst;
|
||||
size_t remain_len;
|
||||
uint32_t *temp_ptr = cmd_buf_addr;
|
||||
uint32_t *addr, *start;
|
||||
uint32_t min_len;
|
||||
struct cdm_regcontinuous_cmd *p_regcont_cmd;
|
||||
struct cam_cdm_cmd_dump_header *hdr;
|
||||
|
||||
p_regcont_cmd = (struct cdm_regcontinuous_cmd *)temp_ptr;
|
||||
temp_ptr += cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);
|
||||
ret = cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);
|
||||
|
||||
min_len = (sizeof(uint32_t) * p_regcont_cmd->count) +
|
||||
sizeof(struct cam_cdm_cmd_dump_header) +
|
||||
(2 * sizeof(uint32_t));
|
||||
remain_len = dump_info->dst_max_size - dump_info->dst_offset;
|
||||
|
||||
if (remain_len < min_len) {
|
||||
CAM_WARN_RATE_LIMIT(CAM_CDM,
|
||||
"Dump buffer exhaust remain %zu min %u",
|
||||
remain_len, min_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dst = (char *)dump_info->dst_start + dump_info->dst_offset;
|
||||
hdr = (struct cam_cdm_cmd_dump_header *)dst;
|
||||
scnprintf(hdr->tag, CAM_CDM_CMD_TAG_MAX_LEN, "CDM_REG_CONT:");
|
||||
hdr->word_size = sizeof(uint32_t);
|
||||
addr = (uint32_t *)(dst + sizeof(struct cam_cdm_cmd_dump_header));
|
||||
start = addr;
|
||||
*addr++ = p_regcont_cmd->offset;
|
||||
*addr++ = p_regcont_cmd->count;
|
||||
for (i = 0; i < p_regcont_cmd->count; i++) {
|
||||
*addr = *temp_ptr;
|
||||
temp_ptr++;
|
||||
addr++;
|
||||
ret++;
|
||||
}
|
||||
hdr->size = hdr->word_size * (addr - start);
|
||||
dump_info->dst_offset += hdr->size +
|
||||
sizeof(struct cam_cdm_cmd_dump_header);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t cam_cdm_util_dump_reg_random_cmd_v2(
|
||||
uint32_t *cmd_buf_addr,
|
||||
struct cam_cdm_cmd_buf_dump_info *dump_info)
|
||||
{
|
||||
int i;
|
||||
long ret;
|
||||
uint8_t *dst;
|
||||
uint32_t *temp_ptr = cmd_buf_addr;
|
||||
uint32_t *addr, *start;
|
||||
size_t remain_len;
|
||||
uint32_t min_len;
|
||||
struct cdm_regrandom_cmd *p_regrand_cmd;
|
||||
struct cam_cdm_cmd_dump_header *hdr;
|
||||
|
||||
p_regrand_cmd = (struct cdm_regrandom_cmd *)temp_ptr;
|
||||
temp_ptr += cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
|
||||
ret = cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
|
||||
|
||||
min_len = (2 * sizeof(uint32_t) * p_regrand_cmd->count) +
|
||||
sizeof(struct cam_cdm_cmd_dump_header) + sizeof(uint32_t);
|
||||
remain_len = dump_info->dst_max_size - dump_info->dst_offset;
|
||||
|
||||
if (remain_len < min_len) {
|
||||
CAM_WARN_RATE_LIMIT(CAM_CDM,
|
||||
"Dump buffer exhaust remain %zu min %u",
|
||||
remain_len, min_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dst = (char *)dump_info->dst_start + dump_info->dst_offset;
|
||||
hdr = (struct cam_cdm_cmd_dump_header *)dst;
|
||||
scnprintf(hdr->tag, CAM_CDM_CMD_TAG_MAX_LEN, "CDM_REG_RANDOM:");
|
||||
hdr->word_size = sizeof(uint32_t);
|
||||
addr = (uint32_t *)(dst + sizeof(struct cam_cdm_cmd_dump_header));
|
||||
start = addr;
|
||||
*addr++ = p_regrand_cmd->count;
|
||||
for (i = 0; i < p_regrand_cmd->count; i++) {
|
||||
addr[0] = temp_ptr[0] & CAM_CDM_REG_OFFSET_MASK;
|
||||
addr[1] = temp_ptr[1];
|
||||
temp_ptr += 2;
|
||||
addr += 2;
|
||||
ret += 2;
|
||||
}
|
||||
hdr->size = hdr->word_size * (addr - start);
|
||||
dump_info->dst_offset += hdr->size +
|
||||
sizeof(struct cam_cdm_cmd_dump_header);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cam_cdm_util_dump_cmd_bufs_v2(
|
||||
struct cam_cdm_cmd_buf_dump_info *dump_info)
|
||||
{
|
||||
uint32_t cmd;
|
||||
uint32_t *buf_now;
|
||||
int rc = 0;
|
||||
|
||||
if (!dump_info || !dump_info->src_start || !dump_info->src_end ||
|
||||
!dump_info->dst_start) {
|
||||
CAM_INFO(CAM_CDM, "Invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf_now = dump_info->src_start;
|
||||
do {
|
||||
if (dump_info->dst_offset >= dump_info->dst_max_size) {
|
||||
CAM_WARN(CAM_CDM,
|
||||
"Dump overshoot offset %zu size %zu",
|
||||
dump_info->dst_offset,
|
||||
dump_info->dst_max_size);
|
||||
return -ENOSPC;
|
||||
}
|
||||
cmd = *buf_now;
|
||||
cmd = cmd >> CAM_CDM_COMMAND_OFFSET;
|
||||
|
||||
switch (cmd) {
|
||||
case CAM_CDM_CMD_DMI:
|
||||
case CAM_CDM_CMD_DMI_32:
|
||||
case CAM_CDM_CMD_DMI_64:
|
||||
buf_now += cdm_get_cmd_header_size(CAM_CDM_CMD_DMI);
|
||||
break;
|
||||
case CAM_CDM_CMD_REG_CONT:
|
||||
buf_now += cam_cdm_util_dump_reg_cont_cmd_v2(buf_now,
|
||||
dump_info);
|
||||
break;
|
||||
case CAM_CDM_CMD_REG_RANDOM:
|
||||
buf_now += cam_cdm_util_dump_reg_random_cmd_v2(buf_now,
|
||||
dump_info);
|
||||
break;
|
||||
case CAM_CDM_CMD_BUFF_INDIRECT:
|
||||
buf_now += cdm_get_cmd_header_size(
|
||||
CAM_CDM_CMD_BUFF_INDIRECT);
|
||||
break;
|
||||
case CAM_CDM_CMD_GEN_IRQ:
|
||||
buf_now += cdm_get_cmd_header_size(
|
||||
CAM_CDM_CMD_GEN_IRQ);
|
||||
break;
|
||||
case CAM_CDM_CMD_WAIT_EVENT:
|
||||
buf_now += cdm_get_cmd_header_size(
|
||||
CAM_CDM_CMD_WAIT_EVENT);
|
||||
break;
|
||||
case CAM_CDM_CMD_CHANGE_BASE:
|
||||
buf_now += cdm_get_cmd_header_size(
|
||||
CAM_CDM_CMD_CHANGE_BASE);
|
||||
break;
|
||||
case CAM_CDM_CMD_PERF_CTRL:
|
||||
buf_now += cdm_get_cmd_header_size(
|
||||
CAM_CDM_CMD_PERF_CTRL);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_CDM, "Invalid CMD: 0x%x", cmd);
|
||||
buf_now++;
|
||||
break;
|
||||
}
|
||||
} while (buf_now <= dump_info->src_end);
|
||||
return rc;
|
||||
}
|
||||
|
Reference in New Issue
Block a user