Browse Source

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 <[email protected]>
George Shen 3 years ago
parent
commit
72eb20af3d

+ 1 - 0
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;
 }

+ 74 - 32
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);
 	}
 }

+ 58 - 5
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);
 }
 

+ 1 - 1
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,

+ 11 - 4
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;
 }
 

+ 34 - 1
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) {

+ 65 - 1
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 {

+ 3 - 6
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
 					 */
 	},
 	{

+ 8 - 15
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.

+ 1 - 1
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;