From 72eb20af3d92c89eaa7f23c0dc25b43ad5ef47a4 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 21 Jul 2021 17:30:08 -0700 Subject: [PATCH] msm: eva: Add SSR counter Support configurable number of SSR tolerance before calling BUG_ON in SMMU fault scenario. Change-Id: I19dabbeaa1cf5be86f42a6ace62ef5da12743e79 Signed-off-by: George Shen --- msm/eva/cvp.c | 1 + msm/eva/cvp_hfi.c | 106 +++++++++++++++++++++++++----------- msm/eva/msm_cvp_buf.c | 63 +++++++++++++++++++-- msm/eva/msm_cvp_buf.h | 2 +- msm/eva/msm_cvp_common.c | 15 +++-- msm/eva/msm_cvp_debug.c | 35 +++++++++++- msm/eva/msm_cvp_internal.h | 66 +++++++++++++++++++++- msm/eva/msm_cvp_platform.c | 9 +-- msm/eva/msm_cvp_res_parse.c | 23 +++----- msm/eva/msm_cvp_resources.h | 2 +- 10 files changed, 256 insertions(+), 66 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 6f3c69215f..ea1a965ada 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -148,6 +148,7 @@ static int msm_cvp_initialize_core(struct platform_device *pdev, INIT_DELAYED_WORK(&core->fw_unload_work, msm_cvp_fw_unload_handler); INIT_WORK(&core->ssr_work, msm_cvp_ssr_handler); init_cycle_info(&core->dyn_clk); + core->ssr_count = 0; return rc; } diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 4f71bfbf66..2272f47526 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1889,7 +1889,7 @@ static int iris_hfi_core_release(void *dev) __func__, rc); } else { dprintk(CVP_PWR, - "%s: Succeed mmrm_client_deregister for mmrm_cvp:%p, type:%d, uid:%ld\n", + "%s: Succeed mmrm_client_deregister for mmrm_cvp:%pK, type:%d, uid:%ld\n", __func__, device->mmrm_cvp, device->mmrm_cvp->client_type, device->mmrm_cvp->client_uid); device->mmrm_cvp = NULL; @@ -2736,7 +2736,7 @@ static int __response_handler(struct iris_hfi_device *device) if (!raw_packet || !packets) { dprintk(CVP_ERR, - "%s: Invalid args : Res packet = %p, Raw packet = %p\n", + "%s: Invalid args : Res pkt = %pK, Raw pkt = %pK\n", __func__, packets, raw_packet); return 0; } @@ -4226,9 +4226,6 @@ static int iris_hfi_get_core_capabilities(void *dev) return 0; } -static u32 cvp_arp_test_regs[16]; -static u32 cvp_dma_test_regs[512]; - static const char * const mid_names[16] = { "CVP_FW", "ARP_DATA", @@ -4258,63 +4255,108 @@ static void __print_reg_details(u32 val) dprintk(CVP_ERR, "Sub-client:%s, SID: %d\n", mid_names[mid], sid); } +static void __err_log(bool logging, u32 *data, const char *name, u32 val) +{ + if (logging) + *data = val; + + dprintk(CVP_ERR, "%s: %#x\n", name, val); +} + static void __noc_error_info_iris2(struct iris_hfi_device *device) { + struct msm_cvp_core *core; + struct cvp_noc_log *noc_log; u32 val = 0, regi, i; + bool log_required = false; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + + if (!core->ssr_count && core->resources.max_ssr_allowed > 1) + log_required = true; + + noc_log = &core->log.noc_log; val = __read_register(device, CVP_NOC_ERR_SWID_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_SWID_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_swid_low, + "CVP_NOC_ERL_MAIN_SWID_LOW", val); val = __read_register(device, CVP_NOC_ERR_SWID_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_swid_high, + "CVP_NOC_ERL_MAIN_SWID_HIGH", val); val = __read_register(device, CVP_NOC_ERR_MAINCTL_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_mainctl_low, + "CVP_NOC_ERL_MAIN_MAINCTL_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRVLD_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errvld_low, + "CVP_NOC_ERL_MAIN_ERRVLD_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRCLR_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errclr_low, + "CVP_NOC_ERL_MAIN_ERRCLR_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG0_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog0_low, + "CVP_NOC_ERL_MAIN_ERRLOG0_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG0_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog0_high, + "CVP_NOC_ERL_MAIN_ERRLOG0_HIGH", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG1_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog1_low, + "CVP_NOC_ERL_MAIN_ERRLOG1_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG1_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog1_high, + "CVP_NOC_ERL_MAIN_ERRLOG1_HIGH", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG2_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog2_low, + "CVP_NOC_ERL_MAIN_ERRLOG2_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG2_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog2_high, + "CVP_NOC_ERL_MAIN_ERRLOG2_HIGH", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG3_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog3_low, + "CVP_NOC_ERL_MAIN_ERRLOG3_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG3_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog3_high, + "CVP_NOC_ERL_MAIN_ERRLOG3_HIGH", val); val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC__CORE_ERL_MAIN_SWID_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_swid_low, + "CVP_NOC__CORE_ERL_MAIN_SWID_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_SWID_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_core_swid_high, + "CVP_NOC_CORE_ERL_MAIN_SWID_HIGH", val); val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_mainctl_low, + "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errvld_low, + "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errclr_low, + "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog0_low, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog0_high, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog1_low, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog1_high, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog2_low, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog2_high, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS); + __err_log(log_required, &noc_log->err_core_errlog3_low, + "CORE ERRLOG3_LOW, below details", val); __print_reg_details(val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog3_high, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH", val); #define CVP_SS_CLK_HALT 0x8 #define CVP_SS_CLK_EN 0xC #define CVP_SS_ARP_TEST_BUS_CONTROL 0x700 @@ -4330,7 +4372,7 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) regi = 0xC0000000 + i; __write_register(device, CVP_SS_ARP_TEST_BUS_CONTROL, regi); val = __read_register(device, CVP_SS_ARP_TEST_BUS_REGISTER); - cvp_arp_test_regs[i] = val; + noc_log->arp_test_bus[i] = val; dprintk(CVP_ERR, "ARP_CTL:%x - %x\n", regi, val); } @@ -4338,7 +4380,7 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) regi = 0x40000000 + i; __write_register(device, CVP_DMA_TEST_BUS_CONTROL, regi); val = __read_register(device, CVP_DMA_TEST_BUS_REGISTER); - cvp_dma_test_regs[i] = val; + noc_log->dma_test_bus[i] = val; dprintk(CVP_ERR, "DMA_CTL:%x - %x\n", regi, val); } } diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index ff522503e4..eed7670272 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -74,6 +74,51 @@ void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, cbuf->smem->device_addr, cbuf->size); } +static void _log_smem(struct inst_snapshot *snapshot, struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem, bool logging) +{ + print_smem(CVP_ERR, "bufdump", inst, smem); + if (!logging || !snapshot) + return; + if (snapshot && snapshot->smem_index < MAX_ENTRIES) { + struct smem_data *s; + s = &snapshot->smem_log[snapshot->smem_index]; + snapshot->smem_index++; + s->size = smem->size; + s->flags = smem->flags; + s->device_addr = smem->device_addr; + s->bitmap_index = smem->bitmap_index; + s->refcount = atomic_read(&smem->refcount); + } +} + +static void _log_buf(struct inst_snapshot *snapshot, enum smem_prop prop, + struct msm_cvp_inst *inst, struct cvp_internal_buf *cbuf, + bool logging) +{ + struct cvp_buf_data *buf = NULL; + u32 index; + print_cvp_buffer(CVP_ERR, "bufdump", inst, cbuf); + if (!logging) + return; + if (snapshot) { + if (prop == SMEM_ADSP && snapshot->dsp_index < MAX_ENTRIES) { + index = snapshot->dsp_index; + buf = &snapshot->dsp_buf_log[index]; + snapshot->dsp_index++; + } else if (prop == SMEM_PERSIST && + snapshot->persist_index < MAX_ENTRIES) { + index = snapshot->persist_index; + buf = &snapshot->persist_buf_log[index]; + snapshot->persist_index++; + } + if (buf) { + buf->device_addr = cbuf->smem->device_addr; + buf->size = cbuf->size; + } + } +} + void print_client_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, struct eva_kmd_buffer *cbuf) { @@ -863,11 +908,20 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) return rc; } -void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst) +void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) { struct cvp_internal_buf *buf; + struct msm_cvp_core *core; + struct inst_snapshot *snap = NULL; int i; + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (log && core->log.snapshot_index < 16) { + snap = &core->log.snapshot[core->log.snapshot_index]; + snap->session = inst->session; + core->log.snapshot_index++; + } + if (!inst) { dprintk(CVP_ERR, "%s - invalid param %pK\n", __func__, inst); @@ -882,20 +936,19 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst) dprintk(CVP_ERR, "dma cache:\n"); if (inst->dma_cache.nr <= MAX_DMABUF_NUMS) for (i = 0; i < inst->dma_cache.nr; i++) - print_smem(CVP_ERR, "bufdump", inst, - inst->dma_cache.entries[i]); + _log_smem(snap, inst, inst->dma_cache.entries[i], log); mutex_unlock(&inst->dma_cache.lock); mutex_lock(&inst->cvpdspbufs.lock); dprintk(CVP_ERR, "dsp buffer list:\n"); list_for_each_entry(buf, &inst->cvpdspbufs.list, list) - print_cvp_buffer(CVP_ERR, "bufdump", inst, buf); + _log_buf(snap, SMEM_ADSP, inst, buf, log); mutex_unlock(&inst->cvpdspbufs.lock); mutex_lock(&inst->persistbufs.lock); dprintk(CVP_ERR, "persist buffer list:\n"); list_for_each_entry(buf, &inst->persistbufs.list, list) - print_cvp_buffer(CVP_ERR, "bufdump", inst, buf); + _log_buf(snap, SMEM_PERSIST, inst, buf, log); mutex_unlock(&inst->persistbufs.lock); } diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 29c6963476..1eaef46154 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -209,7 +209,7 @@ int msm_cvp_register_buffer(struct msm_cvp_inst *inst, int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf); int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst); -void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst); +void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log); int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, struct cvp_internal_buf *buf, u32 buffer_size, diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index f5537b1124..e3f5abb854 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -670,7 +670,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) } if (!core->trigger_ssr) - msm_cvp_print_inst_bufs(inst); + msm_cvp_print_inst_bufs(inst, false); } /* handle the hw error before core released to get full debug info */ @@ -1036,7 +1036,6 @@ static int msm_comm_init_core(struct msm_cvp_inst *inst) goto fail_core_init; } core->state = CVP_CORE_INIT; - core->smmu_fault_handled = false; core->trigger_ssr = false; core_already_inited: @@ -1304,6 +1303,7 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state) int msm_cvp_noc_error_info(struct msm_cvp_core *core) { struct cvp_hfi_device *hdev; + static u32 last_fault_count = 0; if (!core || !core->device) { dprintk(CVP_WARN, "%s: Invalid parameters: %pK\n", @@ -1311,13 +1311,20 @@ int msm_cvp_noc_error_info(struct msm_cvp_core *core) return -EINVAL; } - if (!core->smmu_fault_handled) + if (!core->smmu_fault_count || + core->smmu_fault_count == last_fault_count) return 0; + last_fault_count = core->smmu_fault_count; + core->ssr_count++; + dprintk(CVP_ERR, "cvp ssr count %d %d\n", core->ssr_count, + core->resources.max_ssr_allowed); hdev = core->device; call_hfi_op(hdev, noc_error_info, hdev->hfi_device_data); - BUG_ON(!core->resources.non_fatal_pagefaults); + if (core->ssr_count >= core->resources.max_ssr_allowed) + BUG_ON(!core->resources.non_fatal_pagefaults); + return 0; } diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index fb0f23d4af..099f9b0f40 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -358,6 +358,33 @@ static int _dsp_dbg_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(dsp_debug_fops, _dsp_dbg_get, _dsp_dbg_set, "%llu\n"); +static int _max_ssr_set(void *data, u64 val) +{ + struct msm_cvp_core *core; + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) { + if (val < 1) { + dprintk(CVP_WARN, + "Invalid max_ssr_allowed value %llx\n", val); + return 0; + } + + core->resources.max_ssr_allowed = (unsigned int)val; + } + return 0; +} + +static int _max_ssr_get(void *data, u64 *val) +{ + struct msm_cvp_core *core; + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) + *val = core->resources.max_ssr_allowed; + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(max_ssr_fops, _max_ssr_get, _max_ssr_set, "%llu\n"); struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, struct dentry *parent) @@ -397,6 +424,12 @@ struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, goto failed_create_dir; } + if (!debugfs_create_file("max_ssr_allowed", 0644, dir, + NULL, &max_ssr_fops)) { + dprintk(CVP_ERR, "debugfs_create: max_ssr_allowed fail\n"); + goto failed_create_dir; + } + failed_create_dir: return dir; } @@ -512,7 +545,7 @@ struct dentry *msm_cvp_debugfs_init_inst(struct msm_cvp_inst *inst, dprintk(CVP_ERR, "Invalid params, inst: %pK\n", inst); goto exit; } - snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst); + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst); idata = kzalloc(sizeof(*idata), GFP_KERNEL); if (!idata) { diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index e79a0d7965..a86c7e9cc6 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -270,6 +270,68 @@ struct cvp_session_event { wait_queue_head_t wq; }; +#define MAX_ENTRIES 64 + +struct smem_data { + u32 size; + u32 flags; + u32 device_addr; + u32 bitmap_index; + u32 refcount; +}; + +struct cvp_buf_data { + u32 device_addr; + u32 size; +}; + +struct inst_snapshot { + void *session; + u32 smem_index; + u32 dsp_index; + u32 persist_index; + struct smem_data smem_log[MAX_ENTRIES]; + struct cvp_buf_data dsp_buf_log[MAX_ENTRIES]; + struct cvp_buf_data persist_buf_log[MAX_ENTRIES]; +}; + +struct cvp_noc_log { + u32 err_ctrl_swid_low; + u32 err_ctrl_swid_high; + u32 err_ctrl_mainctl_low; + u32 err_ctrl_errvld_low; + u32 err_ctrl_errclr_low; + u32 err_ctrl_errlog0_low; + u32 err_ctrl_errlog0_high; + u32 err_ctrl_errlog1_low; + u32 err_ctrl_errlog1_high; + u32 err_ctrl_errlog2_low; + u32 err_ctrl_errlog2_high; + u32 err_ctrl_errlog3_low; + u32 err_ctrl_errlog3_high; + u32 err_core_swid_low; + u32 err_core_swid_high; + u32 err_core_mainctl_low; + u32 err_core_errvld_low; + u32 err_core_errclr_low; + u32 err_core_errlog0_low; + u32 err_core_errlog0_high; + u32 err_core_errlog1_low; + u32 err_core_errlog1_high; + u32 err_core_errlog2_low; + u32 err_core_errlog2_high; + u32 err_core_errlog3_low; + u32 err_core_errlog3_high; + u32 arp_test_bus[16]; + u32 dma_test_bus[512]; +}; + +struct cvp_debug_log { + struct cvp_noc_log noc_log; + u32 snapshot_index; + struct inst_snapshot snapshot[16]; +}; + struct msm_cvp_core { struct list_head list; struct mutex lock; @@ -291,12 +353,14 @@ struct msm_cvp_core { struct delayed_work fw_unload_work; struct work_struct ssr_work; enum hal_ssr_trigger_type ssr_type; - bool smmu_fault_handled; + u32 smmu_fault_count; u32 last_fault_addr; + u32 ssr_count; bool trigger_ssr; unsigned long curr_freq; struct cvp_cycle_info dyn_clk; atomic64_t kernel_trans_id; + struct cvp_debug_log log; }; struct msm_cvp_inst { diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 6670203fda..20c9702337 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -72,12 +72,9 @@ static struct msm_cvp_common_data sm8450_common_data[] = { */ }, { - .key = "qcom,max-hw-load", - .value = 3916800, /* - * 1920x1088/256 MBs@480fps. It is less - * any other usecases (ex: - * 3840x2160@120fps, 4096x2160@96ps, - * 7680x4320@30fps) + .key = "qcom,max-ssr-allowed", + .value = 1, /* + * Maxinum number of SSR before BUG_ON */ }, { diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 013088f988..e3a521b3f8 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -771,8 +771,8 @@ int cvp_read_platform_resources_from_drv_data( res->dsp_enabled = find_key_value(platform_data, "qcom,dsp-enabled"); - res->max_load = find_key_value(platform_data, - "qcom,max-hw-load"); + res->max_ssr_allowed = find_key_value(platform_data, + "qcom,max-ssr-allowed"); res->sw_power_collapsible = find_key_value(platform_data, "qcom,sw-power-collapse"); @@ -952,7 +952,7 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, { struct msm_cvp_core *core = token; struct msm_cvp_inst *inst; - u32 *pfaddr = &core->last_fault_addr; + bool log = false; if (!domain || !core) { dprintk(CVP_ERR, "%s - invalid param %pK %pK\n", @@ -960,22 +960,15 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, return -EINVAL; } - if (core->smmu_fault_handled) { - if (core->resources.non_fatal_pagefaults) { - WARN_ONCE(1, "%s: non-fatal pagefault address: %lx\n", - __func__, iova); - *pfaddr = (*pfaddr == 0) ? iova : (*pfaddr); - return 0; - } - } - - dprintk(CVP_ERR, "%s - faulting address: %lx\n", __func__, iova); + core->smmu_fault_count++; + dprintk(CVP_ERR, "%s - faulting address: %lx, %d\n", + __func__, iova, core->smmu_fault_count); mutex_lock(&core->lock); + log = (core->log.snapshot_index > 0)? false : true; list_for_each_entry(inst, &core->instances, list) { - msm_cvp_print_inst_bufs(inst); + msm_cvp_print_inst_bufs(inst, log); } - core->smmu_fault_handled = true; mutex_unlock(&core->lock); /* * Return -EINVAL to elicit the default behaviour of smmu driver. diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index c39f15706f..268f5baccf 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -152,7 +152,7 @@ struct msm_cvp_platform_resources { struct subcache_set subcache_set; struct reg_set reg_set; struct addr_set qdss_addr_set; - uint32_t max_load; + uint32_t max_ssr_allowed; struct platform_device *pdev; struct regulator_set regulator_set; struct clock_set clock_set;