|
@@ -22,6 +22,7 @@
|
|
|
#include "cam_common_util.h"
|
|
|
#include "cam_req_mgr_debug.h"
|
|
|
#include "cam_cpas_api.h"
|
|
|
+#include "cam_ife_hw_mgr.h"
|
|
|
|
|
|
static const char isp_dev_name[] = "cam-isp";
|
|
|
|
|
@@ -39,6 +40,15 @@ static int cam_isp_context_hw_recovery(void *priv, void *data);
|
|
|
static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
|
|
|
struct cam_start_stop_dev_cmd *cmd);
|
|
|
|
|
|
+static void __cam_isp_ctx_dump_state_monitor_array(
|
|
|
+ struct cam_isp_context *ctx_isp);
|
|
|
+
|
|
|
+static const char *__cam_isp_hw_evt_val_to_type(
|
|
|
+ uint32_t evt_id);
|
|
|
+
|
|
|
+static const char *__cam_isp_ctx_substate_val_to_type(
|
|
|
+ enum cam_isp_ctx_activated_substate type);
|
|
|
+
|
|
|
static const char *__cam_isp_evt_val_to_type(
|
|
|
uint32_t evt_id)
|
|
|
{
|
|
@@ -101,29 +111,42 @@ static void __cam_isp_ctx_update_event_record(
|
|
|
ctx_isp->event_record[event][iterator].timestamp = cur_time;
|
|
|
}
|
|
|
|
|
|
+static void *cam_isp_ctx_user_dump_events(
|
|
|
+ void *dump_struct, uint8_t *addr_ptr)
|
|
|
+{
|
|
|
+ uint64_t *addr;
|
|
|
+ struct cam_isp_context_event_record *record;
|
|
|
+ struct timespec64 ts;
|
|
|
+
|
|
|
+ record = (struct cam_isp_context_event_record *)dump_struct;
|
|
|
+
|
|
|
+ addr = (uint64_t *)addr_ptr;
|
|
|
+ ts = ktime_to_timespec64(record->timestamp);
|
|
|
+ *addr++ = record->req_id;
|
|
|
+ *addr++ = ts.tv_sec;
|
|
|
+ *addr++ = ts.tv_nsec / NSEC_PER_USEC;
|
|
|
+
|
|
|
+ return addr;
|
|
|
+}
|
|
|
+
|
|
|
static int __cam_isp_ctx_dump_event_record(
|
|
|
struct cam_isp_context *ctx_isp,
|
|
|
- uintptr_t cpu_addr,
|
|
|
- size_t buf_len,
|
|
|
- size_t *offset)
|
|
|
+ struct cam_common_hw_dump_args *dump_args)
|
|
|
{
|
|
|
- int i, j;
|
|
|
+ int i, j, rc = 0;
|
|
|
int index;
|
|
|
size_t remain_len;
|
|
|
- uint8_t *dst;
|
|
|
uint32_t oldest_entry, num_entries;
|
|
|
uint32_t min_len;
|
|
|
- uint64_t *addr, *start;
|
|
|
uint64_t state_head;
|
|
|
- struct timespec64 ts;
|
|
|
- struct cam_isp_context_dump_header *hdr;
|
|
|
struct cam_isp_context_event_record *record;
|
|
|
|
|
|
- if (!cpu_addr || !buf_len || !offset || !ctx_isp) {
|
|
|
- CAM_ERR(CAM_ISP, "Invalid args %pK %zu %pK %pK",
|
|
|
- cpu_addr, buf_len, offset, ctx_isp);
|
|
|
+ if (!dump_args || !ctx_isp) {
|
|
|
+ CAM_ERR(CAM_ISP, "Invalid args %pK %pK",
|
|
|
+ dump_args, ctx_isp);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
+
|
|
|
for (i = 0; i < CAM_ISP_CTX_EVENT_MAX; i++) {
|
|
|
state_head = atomic64_read(&ctx_isp->event_record_head[i]);
|
|
|
|
|
@@ -140,17 +163,16 @@ static int __cam_isp_ctx_dump_event_record(
|
|
|
}
|
|
|
index = oldest_entry;
|
|
|
|
|
|
- if (buf_len <= *offset) {
|
|
|
- CAM_WARN(CAM_ISP,
|
|
|
- "Dump buffer overshoot len %zu offset %zu",
|
|
|
- buf_len, *offset);
|
|
|
+ if (dump_args->buf_len <= dump_args->offset) {
|
|
|
+ CAM_WARN(CAM_ISP, "Dump buffer overshoot len %zu offset %zu",
|
|
|
+ dump_args->buf_len, dump_args->offset);
|
|
|
return -ENOSPC;
|
|
|
}
|
|
|
|
|
|
min_len = sizeof(struct cam_isp_context_dump_header) +
|
|
|
((num_entries * CAM_ISP_CTX_DUMP_EVENT_NUM_WORDS) *
|
|
|
- sizeof(uint64_t));
|
|
|
- remain_len = buf_len - *offset;
|
|
|
+ sizeof(uint64_t));
|
|
|
+ remain_len = dump_args->buf_len - dump_args->offset;
|
|
|
|
|
|
if (remain_len < min_len) {
|
|
|
CAM_WARN(CAM_ISP,
|
|
@@ -158,29 +180,24 @@ static int __cam_isp_ctx_dump_event_record(
|
|
|
remain_len, min_len);
|
|
|
return -ENOSPC;
|
|
|
}
|
|
|
- dst = (uint8_t *)cpu_addr + *offset;
|
|
|
- hdr = (struct cam_isp_context_dump_header *)dst;
|
|
|
- scnprintf(hdr->tag,
|
|
|
- CAM_ISP_CONTEXT_DUMP_TAG_MAX_LEN, "ISP_EVT_%s:",
|
|
|
- __cam_isp_evt_val_to_type(i));
|
|
|
- hdr->word_size = sizeof(uint64_t);
|
|
|
- addr = (uint64_t *)(dst +
|
|
|
- sizeof(struct cam_isp_context_dump_header));
|
|
|
- start = addr;
|
|
|
- for (j = 0; j < num_entries; j++) {
|
|
|
- record = &ctx_isp->event_record[i][index];
|
|
|
- ts = ktime_to_timespec64(record->timestamp);
|
|
|
- *addr++ = record->req_id;
|
|
|
- *addr++ = ts.tv_sec;
|
|
|
- *addr++ = ts.tv_nsec/NSEC_PER_USEC;
|
|
|
+
|
|
|
+ for (j = 0; j < num_entries; j++) {
|
|
|
+ record = &ctx_isp->event_record[i][index];
|
|
|
+
|
|
|
+ rc = cam_common_user_dump_helper(dump_args, cam_isp_ctx_user_dump_events,
|
|
|
+ record, sizeof(uint64_t), "ISP_EVT_%s:",
|
|
|
+ __cam_isp_evt_val_to_type(i));
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP,
|
|
|
+ "CAM_ISP_CONTEXT DUMP_EVENT_RECORD: Dump failed, rc: %d",
|
|
|
+ rc);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
index = (index + 1) %
|
|
|
CAM_ISP_CTX_EVENT_RECORD_MAX_ENTRIES;
|
|
|
}
|
|
|
- hdr->size = hdr->word_size * (addr - start);
|
|
|
- *offset += hdr->size +
|
|
|
- sizeof(struct cam_isp_context_dump_header);
|
|
|
}
|
|
|
- return 0;
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
static void __cam_isp_ctx_req_mini_dump(struct cam_ctx_request *req,
|
|
@@ -483,6 +500,78 @@ static void __cam_isp_ctx_dump_state_monitor_array(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void *cam_isp_ctx_user_dump_state_monitor_array_info(
|
|
|
+ void *dump_struct, uint8_t *addr_ptr)
|
|
|
+{
|
|
|
+ struct cam_isp_context_state_monitor *evt = NULL;
|
|
|
+ uint64_t *addr;
|
|
|
+
|
|
|
+ evt = (struct cam_isp_context_state_monitor *)dump_struct;
|
|
|
+
|
|
|
+ addr = (uint64_t *)addr_ptr;
|
|
|
+
|
|
|
+ *addr++ = evt->evt_time_stamp;
|
|
|
+ *addr++ = evt->frame_id;
|
|
|
+ *addr++ = evt->req_id;
|
|
|
+ return addr;
|
|
|
+}
|
|
|
+
|
|
|
+static int __cam_isp_ctx_user_dump_state_monitor_array(
|
|
|
+ struct cam_isp_context *ctx_isp,
|
|
|
+ struct cam_common_hw_dump_args *dump_args)
|
|
|
+{
|
|
|
+ int i, rc = 0;
|
|
|
+ int index;
|
|
|
+ uint32_t oldest_entry;
|
|
|
+ uint32_t num_entries;
|
|
|
+ uint64_t state_head;
|
|
|
+
|
|
|
+ if (!dump_args || !ctx_isp) {
|
|
|
+ CAM_ERR(CAM_ISP, "Invalid args %pK %pK",
|
|
|
+ dump_args, ctx_isp);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ state_head = 0;
|
|
|
+ state_head = atomic64_read(&ctx_isp->state_monitor_head);
|
|
|
+
|
|
|
+ if (state_head == -1) {
|
|
|
+ return 0;
|
|
|
+ } else if (state_head < CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) {
|
|
|
+ num_entries = state_head;
|
|
|
+ oldest_entry = 0;
|
|
|
+ } else {
|
|
|
+ num_entries = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES;
|
|
|
+ div_u64_rem(state_head + 1,
|
|
|
+ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES, &oldest_entry);
|
|
|
+ }
|
|
|
+ CAM_ERR(CAM_ISP,
|
|
|
+ "Dumping state information for preceding requests");
|
|
|
+
|
|
|
+ index = oldest_entry;
|
|
|
+ __cam_isp_ctx_dump_state_monitor_array(ctx_isp);
|
|
|
+ for (i = 0; i < num_entries; i++) {
|
|
|
+
|
|
|
+ rc = cam_common_user_dump_helper(dump_args,
|
|
|
+ cam_isp_ctx_user_dump_state_monitor_array_info,
|
|
|
+ &ctx_isp->cam_isp_ctx_state_monitor[index],
|
|
|
+ sizeof(uint64_t), "ISP_STATE_MONITOR.%s.%s:",
|
|
|
+ __cam_isp_ctx_substate_val_to_type(
|
|
|
+ ctx_isp->cam_isp_ctx_state_monitor[index].curr_state),
|
|
|
+ __cam_isp_hw_evt_val_to_type(
|
|
|
+ ctx_isp->cam_isp_ctx_state_monitor[index].trigger));
|
|
|
+
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP, "CAM ISP CONTEXT: Event record dump failed, rc: %d", rc);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ index = (index + 1) % CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES;
|
|
|
+
|
|
|
+ }
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
static int cam_isp_context_info_dump(void *context,
|
|
|
enum cam_context_dump_id id)
|
|
|
{
|
|
@@ -4099,41 +4188,70 @@ static int __cam_isp_ctx_apply_default_req_settings(
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static void *cam_isp_ctx_user_dump_req_list(
|
|
|
+ void *dump_struct, uint8_t *addr_ptr)
|
|
|
+{
|
|
|
+ struct list_head *head = NULL;
|
|
|
+ uint64_t *addr;
|
|
|
+ struct cam_ctx_request *req, *req_temp;
|
|
|
+
|
|
|
+ head = (struct list_head *)dump_struct;
|
|
|
+
|
|
|
+ addr = (uint64_t *)addr_ptr;
|
|
|
+
|
|
|
+ if (!list_empty(head)) {
|
|
|
+ list_for_each_entry_safe(req, req_temp, head, list) {
|
|
|
+ *addr++ = req->request_id;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return addr;
|
|
|
+}
|
|
|
+
|
|
|
+static void *cam_isp_ctx_user_dump_active_requests(
|
|
|
+ void *dump_struct, uint8_t *addr_ptr)
|
|
|
+{
|
|
|
+ uint64_t *addr;
|
|
|
+ struct cam_ctx_request *req;
|
|
|
+
|
|
|
+ req = (struct cam_ctx_request *)dump_struct;
|
|
|
+
|
|
|
+ addr = (uint64_t *)addr_ptr;
|
|
|
+ *addr++ = req->request_id;
|
|
|
+ return addr;
|
|
|
+}
|
|
|
+
|
|
|
static int __cam_isp_ctx_dump_req_info(
|
|
|
struct cam_context *ctx,
|
|
|
struct cam_ctx_request *req,
|
|
|
- uintptr_t cpu_addr,
|
|
|
- size_t buf_len,
|
|
|
- size_t *offset)
|
|
|
+ struct cam_common_hw_dump_args *dump_args)
|
|
|
{
|
|
|
- int i, rc;
|
|
|
- uint8_t *dst;
|
|
|
- int32_t *addr, *start;
|
|
|
+ int i, rc = 0;
|
|
|
uint32_t min_len;
|
|
|
size_t remain_len;
|
|
|
struct cam_isp_ctx_req *req_isp;
|
|
|
struct cam_isp_context *ctx_isp;
|
|
|
- struct cam_isp_context_dump_header *hdr;
|
|
|
+ struct cam_ctx_request *req_temp;
|
|
|
|
|
|
- if (!req || !ctx || !offset || !cpu_addr || !buf_len) {
|
|
|
- CAM_ERR(CAM_ISP, "Invalid parameters %pK %pK %pK %zu",
|
|
|
- req, ctx, offset, buf_len);
|
|
|
+ if (!req || !ctx || !dump_args) {
|
|
|
+ CAM_ERR(CAM_ISP, "Invalid parameters %pK %pK %pK",
|
|
|
+ req, ctx, dump_args);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
req_isp = (struct cam_isp_ctx_req *)req->req_priv;
|
|
|
ctx_isp = (struct cam_isp_context *)ctx->ctx_priv;
|
|
|
|
|
|
- if (buf_len <= *offset) {
|
|
|
+ if (dump_args->buf_len <= dump_args->offset) {
|
|
|
CAM_WARN(CAM_ISP, "Dump buffer overshoot len %zu offset %zu",
|
|
|
- buf_len, *offset);
|
|
|
+ dump_args->buf_len, dump_args->offset);
|
|
|
return -ENOSPC;
|
|
|
}
|
|
|
|
|
|
- remain_len = buf_len - *offset;
|
|
|
+ remain_len = dump_args->buf_len - dump_args->offset;
|
|
|
min_len = sizeof(struct cam_isp_context_dump_header) +
|
|
|
(CAM_ISP_CTX_DUMP_REQUEST_NUM_WORDS *
|
|
|
- req_isp->num_fence_map_out *
|
|
|
- sizeof(int32_t));
|
|
|
+ req_isp->num_fence_map_out *
|
|
|
+ sizeof(uint64_t));
|
|
|
|
|
|
if (remain_len < min_len) {
|
|
|
CAM_WARN(CAM_ISP, "Dump buffer exhaust remain %zu min %u",
|
|
@@ -4141,24 +4259,133 @@ static int __cam_isp_ctx_dump_req_info(
|
|
|
return -ENOSPC;
|
|
|
}
|
|
|
|
|
|
- dst = (uint8_t *)cpu_addr + *offset;
|
|
|
- hdr = (struct cam_isp_context_dump_header *)dst;
|
|
|
- hdr->word_size = sizeof(int32_t);
|
|
|
- scnprintf(hdr->tag, CAM_ISP_CONTEXT_DUMP_TAG_MAX_LEN,
|
|
|
- "ISP_OUT_FENCE:");
|
|
|
- addr = (int32_t *)(dst + sizeof(struct cam_isp_context_dump_header));
|
|
|
- start = addr;
|
|
|
- for (i = 0; i < req_isp->num_fence_map_out; i++) {
|
|
|
- *addr++ = req_isp->fence_map_out[i].resource_handle;
|
|
|
- *addr++ = req_isp->fence_map_out[i].sync_id;
|
|
|
+ /* Dump pending request list */
|
|
|
+ rc = cam_common_user_dump_helper(dump_args, cam_isp_ctx_user_dump_req_list,
|
|
|
+ &ctx->pending_req_list, sizeof(uint64_t), "ISP_OUT_FENCE_PENDING_REQUESTS:");
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP, "CAM_ISP_CONTEXT: Pending request dump failed, rc: %d",
|
|
|
+ rc);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Dump applied request list */
|
|
|
+ rc = cam_common_user_dump_helper(dump_args, cam_isp_ctx_user_dump_req_list,
|
|
|
+ &ctx->wait_req_list, sizeof(uint64_t), "ISP_OUT_FENCE_APPLIED_REQUESTS:");
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP, "CAM_ISP_CONTEXT: Applied request dump failed, rc: %d",
|
|
|
+ rc);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Dump active request list */
|
|
|
+ rc = cam_common_user_dump_helper(dump_args, cam_isp_ctx_user_dump_req_list,
|
|
|
+ &ctx->active_req_list, sizeof(uint64_t), "ISP_OUT_FENCE_ACTIVE_REQUESTS:");
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP, "CAM_ISP_CONTEXT: Active request dump failed, rc: %d",
|
|
|
+ rc);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Dump active request fences */
|
|
|
+ if (!list_empty(&ctx->active_req_list)) {
|
|
|
+ list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) {
|
|
|
+ req_isp = (struct cam_isp_ctx_req *)req->req_priv;
|
|
|
+ for (i = 0; i < req_isp->num_fence_map_out; i++) {
|
|
|
+ rc = cam_common_user_dump_helper(dump_args,
|
|
|
+ cam_isp_ctx_user_dump_active_requests,
|
|
|
+ req, sizeof(uint64_t),
|
|
|
+ "ISP_OUT_FENCE_REQUEST_ACTIVE.%s.%u.%d:",
|
|
|
+ __cam_isp_ife_sfe_resource_handle_id_to_type(
|
|
|
+ req_isp->fence_map_out[i].resource_handle),
|
|
|
+ &(req_isp->fence_map_out[i].image_buf_addr),
|
|
|
+ req_isp->fence_map_out[i].sync_id);
|
|
|
+
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP,
|
|
|
+ "CAM_ISP_CONTEXT DUMP_REQ_INFO: Dump failed, rc: %d",
|
|
|
+ rc);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- hdr->size = hdr->word_size * (addr - start);
|
|
|
- *offset += hdr->size + sizeof(struct cam_isp_context_dump_header);
|
|
|
- rc = cam_isp_ctx_dump_req(req_isp, cpu_addr, buf_len,
|
|
|
- offset, true);
|
|
|
+
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static void *cam_isp_ctx_user_dump_timer(
|
|
|
+ void *dump_struct, uint8_t *addr_ptr)
|
|
|
+{
|
|
|
+ struct cam_ctx_request *req = NULL;
|
|
|
+ struct cam_isp_ctx_req *req_isp = NULL;
|
|
|
+ uint64_t *addr;
|
|
|
+ ktime_t cur_time;
|
|
|
+
|
|
|
+ req = (struct cam_ctx_request *)dump_struct;
|
|
|
+ req_isp = (struct cam_isp_ctx_req *)req->req_priv;
|
|
|
+ cur_time = ktime_get();
|
|
|
+
|
|
|
+ addr = (uint64_t *)addr_ptr;
|
|
|
+
|
|
|
+ *addr++ = req->request_id;
|
|
|
+ *addr++ = ktime_to_timespec64(
|
|
|
+ req_isp->event_timestamp[CAM_ISP_CTX_EVENT_APPLY]).tv_sec;
|
|
|
+ *addr++ = ktime_to_timespec64(
|
|
|
+ req_isp->event_timestamp[CAM_ISP_CTX_EVENT_APPLY]).tv_nsec / NSEC_PER_USEC;
|
|
|
+ *addr++ = ktime_to_timespec64(cur_time).tv_sec;
|
|
|
+ *addr++ = ktime_to_timespec64(cur_time).tv_nsec / NSEC_PER_USEC;
|
|
|
+ return addr;
|
|
|
+}
|
|
|
+
|
|
|
+static void *cam_isp_ctx_user_dump_stream_info(
|
|
|
+ void *dump_struct, uint8_t *addr_ptr)
|
|
|
+{
|
|
|
+ struct cam_context *ctx = NULL;
|
|
|
+ struct cam_ife_hw_mgr_ctx *hw_mgr_ctx = NULL;
|
|
|
+ struct cam_isp_hw_mgr_res *hw_mgr_res = NULL;
|
|
|
+ struct cam_isp_resource_node *hw_res = NULL;
|
|
|
+ int hw_idx[CAM_ISP_HW_SPLIT_MAX] = { -1, -1 };
|
|
|
+ int sfe_hw_idx[CAM_ISP_HW_SPLIT_MAX] = { -1, -1 };
|
|
|
+ int32_t *addr;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ ctx = (struct cam_context *)dump_struct;
|
|
|
+ hw_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)ctx->ctxt_to_hw_map;
|
|
|
+
|
|
|
+ if (!list_empty(&hw_mgr_ctx->res_list_ife_src)) {
|
|
|
+ hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_ife_src,
|
|
|
+ struct cam_isp_hw_mgr_res, list);
|
|
|
+
|
|
|
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
|
|
+ hw_res = hw_mgr_res->hw_res[i];
|
|
|
+ if (hw_res && hw_res->hw_intf)
|
|
|
+ hw_idx[i] = hw_res->hw_intf->hw_idx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!list_empty(&hw_mgr_ctx->res_list_sfe_src)) {
|
|
|
+ hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_sfe_src,
|
|
|
+ struct cam_isp_hw_mgr_res, list);
|
|
|
+
|
|
|
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
|
|
+ hw_res = hw_mgr_res->hw_res[i];
|
|
|
+ if (hw_res && hw_res->hw_intf)
|
|
|
+ sfe_hw_idx[i] = hw_res->hw_intf->hw_idx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ addr = (int32_t *)addr_ptr;
|
|
|
+
|
|
|
+ *addr++ = ctx->ctx_id;
|
|
|
+ *addr++ = ctx->dev_hdl;
|
|
|
+ *addr++ = ctx->link_hdl;
|
|
|
+ *addr++ = hw_idx[CAM_ISP_HW_SPLIT_LEFT];
|
|
|
+ *addr++ = sfe_hw_idx[CAM_ISP_HW_SPLIT_LEFT];
|
|
|
+ *addr++ = hw_mgr_ctx->flags.is_sfe_shdr;
|
|
|
+
|
|
|
+ return addr;
|
|
|
+}
|
|
|
+
|
|
|
static int __cam_isp_ctx_dump_in_top_state(
|
|
|
struct cam_context *ctx,
|
|
|
struct cam_req_mgr_dump_info *dump_info)
|
|
@@ -4167,19 +4394,16 @@ static int __cam_isp_ctx_dump_in_top_state(
|
|
|
bool dump_only_event_record = false;
|
|
|
size_t buf_len;
|
|
|
size_t remain_len;
|
|
|
- uint8_t *dst;
|
|
|
ktime_t cur_time;
|
|
|
uint32_t min_len;
|
|
|
uint64_t diff;
|
|
|
- uint64_t *addr, *start;
|
|
|
uintptr_t cpu_addr;
|
|
|
- struct timespec64 ts;
|
|
|
struct cam_isp_context *ctx_isp;
|
|
|
struct cam_ctx_request *req = NULL;
|
|
|
struct cam_isp_ctx_req *req_isp;
|
|
|
struct cam_ctx_request *req_temp;
|
|
|
- struct cam_hw_dump_args dump_args;
|
|
|
- struct cam_isp_context_dump_header *hdr;
|
|
|
+ struct cam_hw_dump_args ife_dump_args;
|
|
|
+ struct cam_common_hw_dump_args dump_args;
|
|
|
|
|
|
spin_lock_bh(&ctx->lock);
|
|
|
list_for_each_entry_safe(req, req_temp,
|
|
@@ -4198,16 +4422,14 @@ static int __cam_isp_ctx_dump_in_top_state(
|
|
|
goto hw_dump;
|
|
|
}
|
|
|
}
|
|
|
- spin_unlock_bh(&ctx->lock);
|
|
|
- return rc;
|
|
|
+ goto end;
|
|
|
hw_dump:
|
|
|
- rc = cam_mem_get_cpu_buf(dump_info->buf_handle,
|
|
|
+ rc = cam_mem_get_cpu_buf(dump_info->buf_handle,
|
|
|
&cpu_addr, &buf_len);
|
|
|
if (rc) {
|
|
|
CAM_ERR(CAM_ISP, "Invalid handle %u rc %d",
|
|
|
dump_info->buf_handle, rc);
|
|
|
- spin_unlock_bh(&ctx->lock);
|
|
|
- return rc;
|
|
|
+ goto end;
|
|
|
}
|
|
|
if (buf_len <= dump_info->offset) {
|
|
|
spin_unlock_bh(&ctx->lock);
|
|
@@ -4238,59 +4460,80 @@ hw_dump:
|
|
|
req->request_id);
|
|
|
dump_only_event_record = true;
|
|
|
}
|
|
|
- dst = (uint8_t *)cpu_addr + dump_info->offset;
|
|
|
- hdr = (struct cam_isp_context_dump_header *)dst;
|
|
|
- scnprintf(hdr->tag, CAM_ISP_CONTEXT_DUMP_TAG_MAX_LEN,
|
|
|
- "ISP_CTX_DUMP:");
|
|
|
- hdr->word_size = sizeof(uint64_t);
|
|
|
- addr = (uint64_t *)(dst +
|
|
|
- sizeof(struct cam_isp_context_dump_header));
|
|
|
- start = addr;
|
|
|
- *addr++ = req->request_id;
|
|
|
- ts = ktime_to_timespec64(
|
|
|
- req_isp->event_timestamp[CAM_ISP_CTX_EVENT_APPLY]);
|
|
|
- *addr++ = ts.tv_sec;
|
|
|
- *addr++ = ts.tv_nsec/NSEC_PER_USEC;
|
|
|
- ts = ktime_to_timespec64(cur_time);
|
|
|
- *addr++ = ts.tv_sec;
|
|
|
- *addr++ = ts.tv_nsec/NSEC_PER_USEC;
|
|
|
- hdr->size = hdr->word_size * (addr - start);
|
|
|
- dump_info->offset += hdr->size +
|
|
|
- sizeof(struct cam_isp_context_dump_header);
|
|
|
|
|
|
- rc = __cam_isp_ctx_dump_event_record(ctx_isp, cpu_addr,
|
|
|
- buf_len, &dump_info->offset);
|
|
|
+ dump_args.req_id = dump_info->req_id;
|
|
|
+ dump_args.cpu_addr = cpu_addr;
|
|
|
+ dump_args.buf_len = buf_len;
|
|
|
+ dump_args.offset = dump_info->offset;
|
|
|
+ dump_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
|
|
|
+
|
|
|
+ /* Dump time info */
|
|
|
+ rc = cam_common_user_dump_helper(&dump_args, cam_isp_ctx_user_dump_timer,
|
|
|
+ req, sizeof(uint64_t), "ISP_CTX_DUMP:");
|
|
|
if (rc) {
|
|
|
- CAM_ERR(CAM_ISP, "Dump event fail %lld",
|
|
|
- req->request_id);
|
|
|
- spin_unlock_bh(&ctx->lock);
|
|
|
- return rc;
|
|
|
+ CAM_ERR(CAM_ISP, "Time dump fail %lld, rc: %d",
|
|
|
+ req->request_id, rc);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ dump_info->offset = dump_args.offset;
|
|
|
+
|
|
|
+ /* Dump stream info */
|
|
|
+ ctx->ctxt_to_hw_map = ctx_isp->hw_ctx;
|
|
|
+ rc = cam_common_user_dump_helper(&dump_args, cam_isp_ctx_user_dump_stream_info,
|
|
|
+ ctx, sizeof(int32_t), "ISP_STREAM_INFO:");
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP, "Stream info dump fail %lld, rc: %d",
|
|
|
+ req->request_id, rc);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ dump_info->offset = dump_args.offset;
|
|
|
+
|
|
|
+ /* Dump event record */
|
|
|
+ rc = __cam_isp_ctx_dump_event_record(ctx_isp, &dump_args);
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP, "Event record dump fail %lld, rc: %d",
|
|
|
+ req->request_id, rc);
|
|
|
+ goto end;
|
|
|
}
|
|
|
+ dump_info->offset = dump_args.offset;
|
|
|
if (dump_only_event_record) {
|
|
|
- spin_unlock_bh(&ctx->lock);
|
|
|
- return rc;
|
|
|
+ goto end;
|
|
|
}
|
|
|
- rc = __cam_isp_ctx_dump_req_info(ctx, req, cpu_addr,
|
|
|
- buf_len, &dump_info->offset);
|
|
|
+
|
|
|
+ /* Dump state monitor array */
|
|
|
+ rc = __cam_isp_ctx_user_dump_state_monitor_array(ctx_isp, &dump_args);
|
|
|
if (rc) {
|
|
|
- CAM_ERR(CAM_ISP, "Dump Req info fail %lld",
|
|
|
- req->request_id);
|
|
|
- spin_unlock_bh(&ctx->lock);
|
|
|
- return rc;
|
|
|
+ CAM_ERR(CAM_ISP, "Dump event fail %lld, rc: %d",
|
|
|
+ req->request_id, rc);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Dump request info */
|
|
|
+ rc = __cam_isp_ctx_dump_req_info(ctx, req, &dump_args);
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_ISP, "Dump Req info fail %lld, rc: %d",
|
|
|
+ req->request_id, rc);
|
|
|
+ goto end;
|
|
|
}
|
|
|
spin_unlock_bh(&ctx->lock);
|
|
|
|
|
|
+ /* Dump CSID, VFE, and SFE info */
|
|
|
+ dump_info->offset = dump_args.offset;
|
|
|
if (ctx->hw_mgr_intf->hw_dump) {
|
|
|
- dump_args.offset = dump_info->offset;
|
|
|
- dump_args.request_id = dump_info->req_id;
|
|
|
- dump_args.buf_handle = dump_info->buf_handle;
|
|
|
- dump_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
|
|
|
+ ife_dump_args.offset = dump_args.offset;
|
|
|
+ ife_dump_args.request_id = dump_info->req_id;
|
|
|
+ ife_dump_args.buf_handle = dump_info->buf_handle;
|
|
|
+ ife_dump_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
|
|
|
rc = ctx->hw_mgr_intf->hw_dump(
|
|
|
ctx->hw_mgr_intf->hw_mgr_priv,
|
|
|
- &dump_args);
|
|
|
- dump_info->offset = dump_args.offset;
|
|
|
+ &ife_dump_args);
|
|
|
+ dump_info->offset = ife_dump_args.offset;
|
|
|
}
|
|
|
return rc;
|
|
|
+
|
|
|
+end:
|
|
|
+ spin_unlock_bh(&ctx->lock);
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
static int __cam_isp_ctx_flush_req_in_flushed_state(
|