Loading drivers/media/platform/msm/camera/cam_cdm/cam_cdm_util.c +148 −1 Original line number Diff line number Diff line /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -714,3 +714,150 @@ void cam_cdm_util_dump_cmd_buf( } } while (buf_now <= cmd_buf_end); } static long cam_cdm_util_dump_reg_cont_cmd_v2( uint32_t *cmd_buf_addr, struct cam_cdm_cmd_buf_dump_info *dump_info) { long ret = 0; struct cdm_regcontinuous_cmd *p_regcont_cmd; uint32_t *temp_ptr = cmd_buf_addr; int i = 0; struct cam_cdm_cmd_dump_header *hdr; uint32_t *addr, *start; uint8_t *dst; uint32_t min_len, remain_len; p_regcont_cmd = (struct cdm_regcontinuous_cmd *)temp_ptr; temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_CONT]; ret += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_CONT]; CAM_DBG(CAM_CDM, "REG_CONT: COUNT: %u OFFSET: 0x%X", p_regcont_cmd->count, p_regcont_cmd->offset); min_len = (sizeof(uint32_t) * p_regcont_cmd->count) + sizeof(struct cam_cdm_cmd_dump_header); remain_len = dump_info->dst_max_size - dump_info->dst_offset; if (remain_len < min_len) { CAM_ERR_RATE_LIMIT(CAM_CDM, "Dump buffer exhaust %d %d", remain_len, min_len); return ret; } dst = (char *)dump_info->dst_start + dump_info->dst_offset; hdr = (struct cam_cdm_cmd_dump_header *)dst; snprintf(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 long cam_cdm_util_dump_reg_random_cmd_v2( uint32_t *cmd_buf_addr, struct cam_cdm_cmd_buf_dump_info *dump_info) { struct cdm_regrandom_cmd *p_regrand_cmd; uint32_t *temp_ptr = cmd_buf_addr; long ret = 0; int i = 0; uint32_t *addr, *start; struct cam_cdm_cmd_dump_header *hdr; uint8_t *dst; uint32_t min_len, remain_len; p_regrand_cmd = (struct cdm_regrandom_cmd *)temp_ptr; temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_RANDOM]; ret += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_RANDOM]; min_len = (2 * sizeof(uint32_t) * p_regrand_cmd->count) + sizeof(struct cam_cdm_cmd_dump_header); remain_len = dump_info->dst_max_size - dump_info->dst_offset; if (remain_len < min_len) { CAM_ERR_RATE_LIMIT(CAM_CDM, "Dump buffer exhaust %d %d", remain_len, min_len); return ret; } dst = (char *)dump_info->dst_start + dump_info->dst_offset; hdr = (struct cam_cdm_cmd_dump_header *)dst; snprintf(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; } void cam_cdm_util_dump_cmd_bufs_v2( struct cam_cdm_cmd_buf_dump_info *dump_info) { uint32_t cmd = 0; uint32_t *buf_now; if (!dump_info || !dump_info->src_start || !dump_info->src_end || !dump_info->dst_start) { CAM_INFO(CAM_CDM, "Invalid args"); return; } buf_now = dump_info->src_start; do { cmd = *dump_info->src_start; 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 += CDMCmdHeaderSizes[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 += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT]; break; case CAM_CDM_CMD_GEN_IRQ: buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_GEN_IRQ]; break; case CAM_CDM_CMD_WAIT_EVENT: buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_WAIT_EVENT]; break; case CAM_CDM_CMD_CHANGE_BASE: buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE]; break; case CAM_CDM_CMD_PERF_CTRL: buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_PERF_CTRL]; break; default: CAM_INFO(CAM_CDM, "Invalid CMD: 0x%x buf 0x%x", cmd, *buf_now); buf_now++; break; } } while (buf_now <= dump_info->src_end); } drivers/media/platform/msm/camera/cam_cdm/cam_cdm_util.h +43 −1 Original line number Diff line number Diff line /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -13,6 +13,9 @@ #ifndef _CAM_CDM_UTIL_H_ #define _CAM_CDM_UTIL_H_ /* Max len for tag name for header while dumping cmd buffer*/ #define CAM_CDM_CMD_TAG_MAX_LEN 32 enum cam_cdm_command { CAM_CDM_CMD_UNUSED = 0x0, CAM_CDM_CMD_DMI = 0x1, Loading Loading @@ -151,6 +154,34 @@ void (*cdm_write_genirq)( uint32_t userdata); }; /** * struct cam_cdm_cmd_buf_dump_info; - Camera CDM dump info * @src_start: source start address * @src_end: source end address * @dst_start: dst start address * @dst_offset: dst offset * @dst_max_size max size of destination buffer */ struct cam_cdm_cmd_buf_dump_info { uint32_t *src_start; uint32_t *src_end; uintptr_t dst_start; uint32_t dst_offset; uint32_t dst_max_size; }; /** * struct cam_cdm_cmd_dump_header- Camera CDM dump header * @tag: tag name for header * @size: size of data * @word_size: size of each word */ struct cam_cdm_cmd_dump_header { char tag[CAM_CDM_CMD_TAG_MAX_LEN]; uint64_t size; uint32_t word_size; }; /** * cam_cdm_util_log_cmd_bufs() * Loading @@ -163,6 +194,17 @@ void (*cdm_write_genirq)( void cam_cdm_util_dump_cmd_buf( uint32_t *cmd_buffer_start, uint32_t *cmd_buffer_end); /** * cam_cdm_util_dump_cmd_bufs_v2() * * @brief: Util function to log cdm command buffers * to a buffer * * @dump_info: Information about source and destination buffers * */ void cam_cdm_util_dump_cmd_bufs_v2( struct cam_cdm_cmd_buf_dump_info *dump_info); #endif /* _CAM_CDM_UTIL_H_ */ drivers/media/platform/msm/camera/cam_core/cam_context.h +16 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ struct cam_context; /* max device name string length*/ #define CAM_CTX_DEV_NAME_MAX_LENGTH 20 /* max tag dump header string length*/ #define CAM_CONTEXT_DUMP_TAG_MAX_LEN 32 /* max request number */ #define CAM_CTX_REQ_MAX 20 #define CAM_CTX_CFG_MAX 20 Loading Loading @@ -229,6 +232,19 @@ struct cam_context { uint32_t last_flush_req; }; /** * struct cam_context_dump_header - Function for context dump header * * @tag : Tag for context dump header * @size : Size of data * @word_size : Word size of data */ struct cam_context_dump_header { char tag[CAM_CONTEXT_DUMP_TAG_MAX_LEN]; uint64_t size; uint32_t word_size; }; /** * cam_context_shutdown() * Loading drivers/media/platform/msm/camera/cam_core/cam_context_utils.c +74 −5 Original line number Diff line number Diff line Loading @@ -1045,6 +1045,72 @@ int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx, return rc; } static int cam_context_dump_context(struct cam_context *ctx, struct cam_hw_dump_args *dump_args) { int rc = 0; struct cam_context_dump_header *hdr; char *dst; uint64_t *addr, *start; uintptr_t cpu_addr; size_t buf_len; uint32_t min_len, remain_len; struct cam_ctx_request *req; int i; if (list_empty(&ctx->active_req_list)) { CAM_ERR(CAM_CTXT, "[%s][%d] no active request", ctx->dev_name, ctx->ctx_id); return -EIO; } rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &cpu_addr, &buf_len); if (!cpu_addr || !buf_len || rc) { CAM_ERR(CAM_CTXT, "lnvalid addr %u len %zu rc %d", dump_args->buf_handle, buf_len, rc); return rc; } remain_len = buf_len - dump_args->offset; min_len = 2 * (sizeof(struct cam_context_dump_header) + CAM_CONTEXT_DUMP_TAG_MAX_LEN); if (remain_len < min_len) { CAM_ERR(CAM_CTXT, "dump buffer exhaust %d %d", remain_len, min_len); goto end; } dst = (char *)cpu_addr + dump_args->offset; hdr = (struct cam_context_dump_header *)dst; snprintf(hdr->tag, CAM_CONTEXT_DUMP_TAG_MAX_LEN, "%s_CTXT_DUMP:", ctx->dev_name); hdr->word_size = sizeof(uint64_t); addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header)); start = addr; req = list_first_entry(&ctx->active_req_list, struct cam_ctx_request, list); *addr++ = ctx->ctx_id; *addr++ = refcount_read(&(ctx->refcount.refcount)); *addr++ = ctx->last_flush_req; *addr++ = ctx->state; *addr++ = req->num_out_map_entries; for (i = 0; i < req->num_out_map_entries; i++) if (req->out_map_entries[i].sync_id != -1) *addr++ = req->out_map_entries[i].sync_id; for (i = 0; i < req->num_in_map_entries; i++) if (req->in_map_entries[i].sync_id != -1) *addr++ = req->in_map_entries[i].sync_id; *addr++ = req->num_in_map_entries; hdr->size = hdr->word_size * (addr - start); dump_args->offset += hdr->size + sizeof(struct cam_context_dump_header); end: rc = cam_mem_put_cpu_buf(dump_args->buf_handle); if (rc) CAM_ERR(CAM_CTXT, "Cpu put failed handle %u", dump_args->buf_handle); return rc; } int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx, struct cam_dump_req_cmd *cmd) { Loading Loading @@ -1074,11 +1140,14 @@ int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx, ctx->dev_name, ctx->ctx_id, dump_args.buf_handle); return rc; } if (dump_args.offset != cmd->offset) { cam_context_dump_context(ctx, &dump_args); CAM_INFO(CAM_CTXT, "[%s] ctx: %d Filled Length %d", ctx->dev_name, ctx->ctx_id, dump_args.offset - cmd->offset); /* Drivers update offest upto which the buffer is written*/ /* Drivers update the offest */ cmd->offset = dump_args.offset; } } else { CAM_INFO(CAM_CTXT, "%s hw dump not registered", ctx->dev_name); } Loading drivers/media/platform/msm/camera/cam_fd/cam_fd_context.c +13 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,18 @@ static int __cam_fd_ctx_release_dev_in_activated(struct cam_context *ctx, return rc; } static int __cam_fd_ctx_dump_dev_in_activated(struct cam_context *ctx, struct cam_dump_req_cmd *cmd) { int rc; rc = cam_context_dump_dev_to_hw(ctx, cmd); if (rc) CAM_ERR(CAM_FD, "Failed to dump device, rc=%d", rc); return rc; } static int __cam_fd_ctx_flush_dev_in_activated(struct cam_context *ctx, struct cam_flush_dev_cmd *cmd) { Loading Loading @@ -203,6 +215,7 @@ static struct cam_ctx_ops .release_dev = __cam_fd_ctx_release_dev_in_activated, .config_dev = __cam_fd_ctx_config_dev_in_activated, .flush_dev = __cam_fd_ctx_flush_dev_in_activated, .dump_dev = __cam_fd_ctx_dump_dev_in_activated, }, .crm_ops = {}, .irq_ops = __cam_fd_ctx_handle_irq_in_activated, Loading Loading
drivers/media/platform/msm/camera/cam_cdm/cam_cdm_util.c +148 −1 Original line number Diff line number Diff line /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -714,3 +714,150 @@ void cam_cdm_util_dump_cmd_buf( } } while (buf_now <= cmd_buf_end); } static long cam_cdm_util_dump_reg_cont_cmd_v2( uint32_t *cmd_buf_addr, struct cam_cdm_cmd_buf_dump_info *dump_info) { long ret = 0; struct cdm_regcontinuous_cmd *p_regcont_cmd; uint32_t *temp_ptr = cmd_buf_addr; int i = 0; struct cam_cdm_cmd_dump_header *hdr; uint32_t *addr, *start; uint8_t *dst; uint32_t min_len, remain_len; p_regcont_cmd = (struct cdm_regcontinuous_cmd *)temp_ptr; temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_CONT]; ret += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_CONT]; CAM_DBG(CAM_CDM, "REG_CONT: COUNT: %u OFFSET: 0x%X", p_regcont_cmd->count, p_regcont_cmd->offset); min_len = (sizeof(uint32_t) * p_regcont_cmd->count) + sizeof(struct cam_cdm_cmd_dump_header); remain_len = dump_info->dst_max_size - dump_info->dst_offset; if (remain_len < min_len) { CAM_ERR_RATE_LIMIT(CAM_CDM, "Dump buffer exhaust %d %d", remain_len, min_len); return ret; } dst = (char *)dump_info->dst_start + dump_info->dst_offset; hdr = (struct cam_cdm_cmd_dump_header *)dst; snprintf(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 long cam_cdm_util_dump_reg_random_cmd_v2( uint32_t *cmd_buf_addr, struct cam_cdm_cmd_buf_dump_info *dump_info) { struct cdm_regrandom_cmd *p_regrand_cmd; uint32_t *temp_ptr = cmd_buf_addr; long ret = 0; int i = 0; uint32_t *addr, *start; struct cam_cdm_cmd_dump_header *hdr; uint8_t *dst; uint32_t min_len, remain_len; p_regrand_cmd = (struct cdm_regrandom_cmd *)temp_ptr; temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_RANDOM]; ret += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_RANDOM]; min_len = (2 * sizeof(uint32_t) * p_regrand_cmd->count) + sizeof(struct cam_cdm_cmd_dump_header); remain_len = dump_info->dst_max_size - dump_info->dst_offset; if (remain_len < min_len) { CAM_ERR_RATE_LIMIT(CAM_CDM, "Dump buffer exhaust %d %d", remain_len, min_len); return ret; } dst = (char *)dump_info->dst_start + dump_info->dst_offset; hdr = (struct cam_cdm_cmd_dump_header *)dst; snprintf(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; } void cam_cdm_util_dump_cmd_bufs_v2( struct cam_cdm_cmd_buf_dump_info *dump_info) { uint32_t cmd = 0; uint32_t *buf_now; if (!dump_info || !dump_info->src_start || !dump_info->src_end || !dump_info->dst_start) { CAM_INFO(CAM_CDM, "Invalid args"); return; } buf_now = dump_info->src_start; do { cmd = *dump_info->src_start; 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 += CDMCmdHeaderSizes[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 += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT]; break; case CAM_CDM_CMD_GEN_IRQ: buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_GEN_IRQ]; break; case CAM_CDM_CMD_WAIT_EVENT: buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_WAIT_EVENT]; break; case CAM_CDM_CMD_CHANGE_BASE: buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE]; break; case CAM_CDM_CMD_PERF_CTRL: buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_PERF_CTRL]; break; default: CAM_INFO(CAM_CDM, "Invalid CMD: 0x%x buf 0x%x", cmd, *buf_now); buf_now++; break; } } while (buf_now <= dump_info->src_end); }
drivers/media/platform/msm/camera/cam_cdm/cam_cdm_util.h +43 −1 Original line number Diff line number Diff line /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -13,6 +13,9 @@ #ifndef _CAM_CDM_UTIL_H_ #define _CAM_CDM_UTIL_H_ /* Max len for tag name for header while dumping cmd buffer*/ #define CAM_CDM_CMD_TAG_MAX_LEN 32 enum cam_cdm_command { CAM_CDM_CMD_UNUSED = 0x0, CAM_CDM_CMD_DMI = 0x1, Loading Loading @@ -151,6 +154,34 @@ void (*cdm_write_genirq)( uint32_t userdata); }; /** * struct cam_cdm_cmd_buf_dump_info; - Camera CDM dump info * @src_start: source start address * @src_end: source end address * @dst_start: dst start address * @dst_offset: dst offset * @dst_max_size max size of destination buffer */ struct cam_cdm_cmd_buf_dump_info { uint32_t *src_start; uint32_t *src_end; uintptr_t dst_start; uint32_t dst_offset; uint32_t dst_max_size; }; /** * struct cam_cdm_cmd_dump_header- Camera CDM dump header * @tag: tag name for header * @size: size of data * @word_size: size of each word */ struct cam_cdm_cmd_dump_header { char tag[CAM_CDM_CMD_TAG_MAX_LEN]; uint64_t size; uint32_t word_size; }; /** * cam_cdm_util_log_cmd_bufs() * Loading @@ -163,6 +194,17 @@ void (*cdm_write_genirq)( void cam_cdm_util_dump_cmd_buf( uint32_t *cmd_buffer_start, uint32_t *cmd_buffer_end); /** * cam_cdm_util_dump_cmd_bufs_v2() * * @brief: Util function to log cdm command buffers * to a buffer * * @dump_info: Information about source and destination buffers * */ void cam_cdm_util_dump_cmd_bufs_v2( struct cam_cdm_cmd_buf_dump_info *dump_info); #endif /* _CAM_CDM_UTIL_H_ */
drivers/media/platform/msm/camera/cam_core/cam_context.h +16 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ struct cam_context; /* max device name string length*/ #define CAM_CTX_DEV_NAME_MAX_LENGTH 20 /* max tag dump header string length*/ #define CAM_CONTEXT_DUMP_TAG_MAX_LEN 32 /* max request number */ #define CAM_CTX_REQ_MAX 20 #define CAM_CTX_CFG_MAX 20 Loading Loading @@ -229,6 +232,19 @@ struct cam_context { uint32_t last_flush_req; }; /** * struct cam_context_dump_header - Function for context dump header * * @tag : Tag for context dump header * @size : Size of data * @word_size : Word size of data */ struct cam_context_dump_header { char tag[CAM_CONTEXT_DUMP_TAG_MAX_LEN]; uint64_t size; uint32_t word_size; }; /** * cam_context_shutdown() * Loading
drivers/media/platform/msm/camera/cam_core/cam_context_utils.c +74 −5 Original line number Diff line number Diff line Loading @@ -1045,6 +1045,72 @@ int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx, return rc; } static int cam_context_dump_context(struct cam_context *ctx, struct cam_hw_dump_args *dump_args) { int rc = 0; struct cam_context_dump_header *hdr; char *dst; uint64_t *addr, *start; uintptr_t cpu_addr; size_t buf_len; uint32_t min_len, remain_len; struct cam_ctx_request *req; int i; if (list_empty(&ctx->active_req_list)) { CAM_ERR(CAM_CTXT, "[%s][%d] no active request", ctx->dev_name, ctx->ctx_id); return -EIO; } rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &cpu_addr, &buf_len); if (!cpu_addr || !buf_len || rc) { CAM_ERR(CAM_CTXT, "lnvalid addr %u len %zu rc %d", dump_args->buf_handle, buf_len, rc); return rc; } remain_len = buf_len - dump_args->offset; min_len = 2 * (sizeof(struct cam_context_dump_header) + CAM_CONTEXT_DUMP_TAG_MAX_LEN); if (remain_len < min_len) { CAM_ERR(CAM_CTXT, "dump buffer exhaust %d %d", remain_len, min_len); goto end; } dst = (char *)cpu_addr + dump_args->offset; hdr = (struct cam_context_dump_header *)dst; snprintf(hdr->tag, CAM_CONTEXT_DUMP_TAG_MAX_LEN, "%s_CTXT_DUMP:", ctx->dev_name); hdr->word_size = sizeof(uint64_t); addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header)); start = addr; req = list_first_entry(&ctx->active_req_list, struct cam_ctx_request, list); *addr++ = ctx->ctx_id; *addr++ = refcount_read(&(ctx->refcount.refcount)); *addr++ = ctx->last_flush_req; *addr++ = ctx->state; *addr++ = req->num_out_map_entries; for (i = 0; i < req->num_out_map_entries; i++) if (req->out_map_entries[i].sync_id != -1) *addr++ = req->out_map_entries[i].sync_id; for (i = 0; i < req->num_in_map_entries; i++) if (req->in_map_entries[i].sync_id != -1) *addr++ = req->in_map_entries[i].sync_id; *addr++ = req->num_in_map_entries; hdr->size = hdr->word_size * (addr - start); dump_args->offset += hdr->size + sizeof(struct cam_context_dump_header); end: rc = cam_mem_put_cpu_buf(dump_args->buf_handle); if (rc) CAM_ERR(CAM_CTXT, "Cpu put failed handle %u", dump_args->buf_handle); return rc; } int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx, struct cam_dump_req_cmd *cmd) { Loading Loading @@ -1074,11 +1140,14 @@ int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx, ctx->dev_name, ctx->ctx_id, dump_args.buf_handle); return rc; } if (dump_args.offset != cmd->offset) { cam_context_dump_context(ctx, &dump_args); CAM_INFO(CAM_CTXT, "[%s] ctx: %d Filled Length %d", ctx->dev_name, ctx->ctx_id, dump_args.offset - cmd->offset); /* Drivers update offest upto which the buffer is written*/ /* Drivers update the offest */ cmd->offset = dump_args.offset; } } else { CAM_INFO(CAM_CTXT, "%s hw dump not registered", ctx->dev_name); } Loading
drivers/media/platform/msm/camera/cam_fd/cam_fd_context.c +13 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,18 @@ static int __cam_fd_ctx_release_dev_in_activated(struct cam_context *ctx, return rc; } static int __cam_fd_ctx_dump_dev_in_activated(struct cam_context *ctx, struct cam_dump_req_cmd *cmd) { int rc; rc = cam_context_dump_dev_to_hw(ctx, cmd); if (rc) CAM_ERR(CAM_FD, "Failed to dump device, rc=%d", rc); return rc; } static int __cam_fd_ctx_flush_dev_in_activated(struct cam_context *ctx, struct cam_flush_dev_cmd *cmd) { Loading Loading @@ -203,6 +215,7 @@ static struct cam_ctx_ops .release_dev = __cam_fd_ctx_release_dev_in_activated, .config_dev = __cam_fd_ctx_config_dev_in_activated, .flush_dev = __cam_fd_ctx_flush_dev_in_activated, .dump_dev = __cam_fd_ctx_dump_dev_in_activated, }, .crm_ops = {}, .irq_ops = __cam_fd_ctx_handle_irq_in_activated, Loading