瀏覽代碼

video: drive: add support to dump FW region

Add support to dump video FW region during FW crash
using devcoredump helpers.

Change-Id: I64c47160f04644223f4e831c35f7a059d38f7d83
Signed-off-by: Dikshita Agarwal <[email protected]>
Signed-off-by: Govindaraj Rajagopal <[email protected]>
Dikshita Agarwal 4 年之前
父節點
當前提交
b08d4769f8
共有 3 個文件被更改,包括 56 次插入0 次删除
  1. 1 0
      driver/vidc/inc/msm_vidc_debug.h
  2. 5 0
      driver/vidc/src/msm_vidc_debug.c
  3. 50 0
      driver/vidc/src/venus_hfi_response.c

+ 1 - 0
driver/vidc/inc/msm_vidc_debug.h

@@ -33,6 +33,7 @@ extern unsigned int msm_vidc_debug;
 extern bool msm_vidc_lossless_encode;
 extern bool msm_vidc_syscache_disable;
 extern int msm_vidc_clock_voting;
+extern bool msm_vidc_fw_dump;
 
 /* To enable messages OR these values and
  * echo the result to debugfs file.

+ 5 - 0
driver/vidc/src/msm_vidc_debug.c

@@ -83,6 +83,9 @@ EXPORT_SYMBOL(msm_vidc_syscache_disable);
 
 int msm_vidc_clock_voting = !1;
 
+bool msm_vidc_fw_dump = !true;
+EXPORT_SYMBOL(msm_vidc_fw_dump);
+
 #define MAX_DBG_BUF_SIZE 4096
 
 struct core_inst_pair {
@@ -244,6 +247,8 @@ struct dentry* msm_vidc_debugfs_init_drv()
 			&msm_vidc_syscache_disable);
 	debugfs_create_bool("lossless_encoding", 0644, dir,
 			&msm_vidc_lossless_encode);
+	debugfs_create_bool("msm_vidc_fw_dump", 0644, dir,
+			&msm_vidc_fw_dump);
 
 	return dir;
 

+ 50 - 0
driver/vidc/src/venus_hfi_response.c

@@ -3,6 +3,8 @@
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  */
 
+#include <linux/devcoredump.h>
+#include <linux/of_address.h>
 #include "hfi_packet.h"
 #include "venus_hfi.h"
 #include "venus_hfi_response.h"
@@ -372,13 +374,61 @@ static int handle_session_error(struct msm_vidc_inst *inst,
 	return rc;
 }
 
+static void fw_coredump(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct device_node *node = NULL;
+	struct resource res = {0};
+	phys_addr_t mem_phys = 0;
+	size_t res_size = 0;
+	void *mem_va = NULL;
+	void *data = NULL;
+
+	node = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
+	if (!node) {
+		d_vpr_e("%s: DT error getting \"memory-region\" property\n",
+			__func__);
+		return;
+	}
+
+	rc = of_address_to_resource(node, 0, &res);
+	if (rc) {
+		d_vpr_e("%s: error %d while getting \"memory-region\" resource\n",
+			__func__, rc);
+		return;
+	}
+
+	mem_phys = res.start;
+	res_size = (size_t)resource_size(&res);
+
+	mem_va = memremap(mem_phys, res_size, MEMREMAP_WC);
+	if (!mem_va) {
+		d_vpr_e("%s: unable to remap firmware memory\n", __func__);
+		return;
+	}
+
+	data = vmalloc(res_size);
+	if (!data) {
+		memunmap(mem_va);
+		return;
+	}
+
+	memcpy(data, mem_va, res_size);
+	memunmap(mem_va);
+	dev_coredumpv(&pdev->dev, data, res_size, GFP_KERNEL);
+}
+
 int handle_system_error(struct msm_vidc_core *core,
 	struct hfi_packet *pkt)
 {
 	d_vpr_e("%s: system error received\n", __func__);
+
 	print_sfr_message(core);
 	venus_hfi_noc_error_info(core);
 	msm_vidc_core_deinit(core, true);
+	if (msm_vidc_fw_dump)
+		fw_coredump(core->pdev);
+
 	return 0;
 }