Browse Source

msm: eva: Enable hangdump mode in EVA

Include new hfi packets and enable the pipeline to
dump hangdump buffers in UMD.

Change-Id: Id66538c69d3080c09c5a140dadcb0dfe87d9efc7
Signed-off-by: Karthik Nagarajan <karnagar@codeaurora.org>
Karthik Nagarajan 3 years ago
parent
commit
322bbdeaa3

+ 2 - 0
include/uapi/eva/media/msm_eva_private.h

@@ -133,6 +133,8 @@ struct eva_kmd_hfi_packet {
 #define EVA_KMD_PROP_SESSION_PRIORITY	4
 #define EVA_KMD_PROP_SESSION_SECURITY	5
 #define EVA_KMD_PROP_SESSION_DSPMASK	6
+#define EVA_KMD_PROP_SESSION_DUMPOFFSET	7
+#define EVA_KMD_PROP_SESSION_DUMPSIZE	8
 
 #define EVA_KMD_PROP_PWR_FDU	0x10
 #define EVA_KMD_PROP_PWR_ICA	0x11

+ 3 - 0
msm/eva/cvp.c

@@ -70,6 +70,9 @@ static unsigned int cvp_poll(struct file *filp, struct poll_table_struct *p)
 	spin_lock_irqsave(&inst->event_handler.lock, flags);
 	if (inst->event_handler.event == CVP_SSR_EVENT)
 		rc |= POLLPRI;
+	if (inst->event_handler.event == CVP_DUMP_EVENT)
+		rc |= POLLIN;
+	inst->event_handler.event = CVP_NO_EVENT;
 	spin_unlock_irqrestore(&inst->event_handler.lock, flags);
 
 	return rc;

+ 1 - 0
msm/eva/cvp_hfi.c

@@ -2653,6 +2653,7 @@ static void **get_session_id(struct msm_cvp_cb_info *info)
 	case HAL_SESSION_UNREGISTER_BUFFER_DONE:
 	case HAL_SESSION_PROPERTY_INFO:
 	case HAL_SESSION_EVENT_CHANGE:
+	case HAL_SESSION_DUMP_NOTIFY:
 		session_id = &info->response.cmd.session_id;
 		break;
 	case HAL_SESSION_ERROR:

+ 18 - 2
msm/eva/cvp_hfi.h

@@ -131,7 +131,14 @@
 	(HFI_CMD_SESSION_CVP_START + 0x064)
 #define  HFI_CMD_SESSION_CVP_WARP_DS_PARAMS\
 	(HFI_CMD_SESSION_CVP_START + 0x065)
-
+#define HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS\
+	(HFI_CMD_SESSION_CVP_START + 0x070)
+#define HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS\
+	(HFI_CMD_SESSION_CVP_START + 0x071)
+#define HFI_CMD_SESSION_CVP_SNAPSHOT_WRITE_DONE\
+	(HFI_CMD_SESSION_CVP_START + 0x072)
+#define HFI_CMD_SESSION_CVP_SET_SNAPSHOT_MODE\
+	(HFI_CMD_SESSION_CVP_START + 0x073)
 #define  HFI_CMD_SESSION_CVP_ICA_FRAME\
 	(HFI_CMD_SESSION_CVP_START + 0x100)
 #define  HFI_CMD_SESSION_CVP_ICA_CONFIG\
@@ -196,6 +203,12 @@
 	(HFI_MSG_SESSION_CVP_START + 0x040)
 #define  HFI_MSG_SESSION_CVP_WARP_DS_PARAMS\
 	(HFI_MSG_SESSION_CVP_START + 0x041)
+#define  HFI_MSG_SESSION_CVP_SET_SNAPSHOT_BUFFERS\
+	(HFI_MSG_SESSION_CVP_START + 0x042)
+#define  HFI_MSG_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS\
+	(HFI_MSG_SESSION_CVP_START + 0x043)
+#define  HFI_MSG_EVENT_NOTIFY_SNAPSHOT_READY\
+	(HFI_MSG_SESSION_CVP_START + 0x044)
 
 #define HFI_MSG_SESSION_CVP_FLUSH\
 	(HFI_MSG_SESSION_CVP_START + 0x004A)
@@ -299,9 +312,12 @@ static inline enum buf_map_type cvp_find_map_type(int pkt_type)
 	if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS ||
 			pkt_type == HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS ||
 			pkt_type == HFI_CMD_SESSION_CVP_DMM_PARAMS ||
+			pkt_type == HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS ||
 			pkt_type == HFI_CMD_SESSION_CVP_WARP_DS_PARAMS)
 		return MAP_PERSIST;
-	else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS)
+	else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS ||
+			pkt_type ==
+				HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS)
 		return UNMAP_PERSIST;
 	else
 		return MAP_FRAME;

+ 1 - 0
msm/eva/cvp_hfi_api.h

@@ -143,6 +143,7 @@ enum hal_command_response {
 	HAL_SESSION_UNREGISTER_BUFFER_DONE,
 	HAL_SESSION_RELEASE_RESOURCE_DONE,
 	HAL_SESSION_PROPERTY_INFO,
+	HAL_SESSION_DUMP_NOTIFY,
 	HAL_SESSION_ERROR,
 	HAL_RESPONSE_UNUSED = 0x10000000,
 };

+ 10 - 0
msm/eva/cvp_hfi_helper.h

@@ -329,6 +329,16 @@ struct cvp_hfi_msg_session_hdr {
 	u32 stream_idx;
 } __packed;
 
+struct cvp_hfi_dumpmsg_session_hdr {
+	u32 size;
+	u32 packet_type;
+	u32 session_id;
+	u32 error_type;
+	struct cvp_hfi_client client_data;
+	u32 dump_offset;
+	u32 dump_size;
+} __packed;
+
 #define HFI_MAX_HW_ACTIVATIONS_PER_FRAME (6)
 #define HFI_MAX_HW_THREADS (4)
 

+ 45 - 0
msm/eva/hfi_response_handler.c

@@ -424,6 +424,48 @@ retry:
 
 }
 
+static int hfi_process_session_dump_notify(u32 device_id,
+		void *hdr, struct msm_cvp_cb_info *info)
+{
+	struct msm_cvp_inst *inst = NULL;
+	struct msm_cvp_core *core;
+	struct cvp_session_prop *session_prop;
+	unsigned int session_id;
+	struct msm_cvp_cb_cmd_done cmd_done = {0};
+	struct cvp_hfi_dumpmsg_session_hdr *pkt =
+			(struct cvp_hfi_dumpmsg_session_hdr *)hdr;
+
+	if (!pkt) {
+		dprintk(CVP_ERR, "%s: invalid param\n", __func__);
+		return -EINVAL;
+	} else if (pkt->size > sizeof(struct cvp_hfi_dumpmsg_session_hdr)) {
+		dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size);
+		return -E2BIG;
+	}
+	session_id = get_msg_session_id(pkt);
+	core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
+	inst = cvp_get_inst_from_id(core, session_id);
+	if (!inst) {
+		dprintk(CVP_ERR, "%s: invalid session\n", __func__);
+		return -EINVAL;
+	}
+	session_prop = &inst->prop;
+	session_prop->dump_offset = pkt->dump_offset;
+	session_prop->dump_size = pkt->dump_size;
+
+	dprintk(CVP_SESS, "RECEIVED: SESSION_DUMP[%x]\n", session_id);
+
+	cmd_done.device_id = device_id;
+	cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
+	cmd_done.status = hfi_map_err_status(pkt->error_type);
+	cmd_done.size = 0;
+
+	info->response_type = HAL_SESSION_DUMP_NOTIFY;
+	info->response.cmd = cmd_done;
+
+	return 0;
+}
+
 static int hfi_process_session_cvp_msg(u32 device_id,
 		void *hdr, struct msm_cvp_cb_info *info)
 {
@@ -598,6 +640,9 @@ int cvp_hfi_process_msg_packet(u32 device_id, void *hdr,
 	case HFI_MSG_SESSION_CVP_FLUSH:
 		pkt_func = (pkt_func_def)hfi_process_session_flush_done;
 		break;
+	case HFI_MSG_EVENT_NOTIFY_SNAPSHOT_READY:
+		pkt_func = (pkt_func_def)hfi_process_session_dump_notify;
+		break;
 	default:
 		dprintk(CVP_HFI, "Use default msg handler: %#x\n",
 				msg_hdr->packet);

+ 27 - 0
msm/eva/msm_cvp.c

@@ -1302,6 +1302,7 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst,
 	struct eva_kmd_sys_properties *props = &arg->data.sys_properties;
 	struct cvp_hfi_device *hdev;
 	struct iris_hfi_device *hfi;
+	struct cvp_session_prop *session_prop;
 	int i, rc = 0;
 
 	if (!inst || !inst->core || !inst->core->device) {
@@ -1312,6 +1313,14 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst,
 	hdev = inst->core->device;
 	hfi = hdev->hfi_device_data;
 
+	if (props->prop_num > MAX_KMD_PROP_NUM_PER_PACKET) {
+		dprintk(CVP_ERR, "Too many properties %d to get\n",
+			props->prop_num);
+		return -E2BIG;
+	}
+
+	session_prop = &inst->prop;
+
 	for (i = 0; i < props->prop_num; i++) {
 		switch (props->prop_data[i].prop_type) {
 		case EVA_KMD_PROP_HFI_VERSION:
@@ -1319,6 +1328,18 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst,
 			props->prop_data[i].data = hfi->version;
 			break;
 		}
+		case EVA_KMD_PROP_SESSION_DUMPOFFSET:
+		{
+			props->prop_data[i].data =
+				session_prop->dump_offset;
+			break;
+		}
+		case EVA_KMD_PROP_SESSION_DUMPSIZE:
+		{
+			props->prop_data[i].data =
+				session_prop->dump_size;
+			break;
+		}
 		case EVA_KMD_PROP_PWR_FDU:
 		{
 			props->prop_data[i].data =
@@ -1449,6 +1470,12 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst,
 		case EVA_KMD_PROP_PWR_FPS_ICA:
 			session_prop->fps[HFI_HW_ICA] = prop_array[i].data;
 			break;
+		case EVA_KMD_PROP_SESSION_DUMPOFFSET:
+			session_prop->dump_offset = prop_array[i].data;
+			break;
+		case EVA_KMD_PROP_SESSION_DUMPSIZE:
+			session_prop->dump_size = prop_array[i].data;
+			break;
 		default:
 			dprintk(CVP_ERR,
 				"unrecognized sys property to set %d\n",

+ 31 - 0
msm/eva/msm_cvp_common.c

@@ -463,6 +463,34 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
 	dprintk(CVP_WARN, "%s is not supported on CVP!\n", __func__);
 }
 
+static void handle_session_dump_notify(enum hal_command_response cmd,
+	void *data)
+{
+	struct msm_cvp_cb_cmd_done *response = data;
+	struct msm_cvp_inst *inst;
+	unsigned long flags = 0;
+
+	if (!response) {
+		dprintk(CVP_ERR,
+			"Failed to get valid response during dump notify\n");
+		return;
+	}
+
+	inst = cvp_get_inst(get_cvp_core(response->device_id),
+			response->session_id);
+	if (!inst) {
+		dprintk(CVP_WARN, "%s:Got a response for an inactive session\n",
+				__func__);
+		return;
+	}
+	spin_lock_irqsave(&inst->event_handler.lock, flags);
+	inst->event_handler.event = CVP_DUMP_EVENT;
+	spin_unlock_irqrestore(&inst->event_handler.lock, flags);
+	wake_up_all(&inst->event_handler.wq);
+	dprintk(CVP_ERR,"Event_handler woken up\n");
+	cvp_put_inst(inst);
+}
+
 static void handle_release_res_done(enum hal_command_response cmd, void *data)
 {
 	struct msm_cvp_cb_cmd_done *response = data;
@@ -756,6 +784,9 @@ void cvp_handle_cmd_response(enum hal_command_response cmd, void *data)
 	case HAL_SESSION_RELEASE_BUFFER_DONE:
 		handle_session_release_buf_done(cmd, data);
 		break;
+        case HAL_SESSION_DUMP_NOTIFY:
+		handle_session_dump_notify(cmd, data);
+		break;
 	default:
 		dprintk(CVP_HFI, "response unhandled: %d\n", cmd);
 		break;

+ 3 - 0
msm/eva/msm_cvp_internal.h

@@ -250,6 +250,8 @@ struct cvp_session_prop {
 	u32 ddr_cache;
 	u32 ddr_op_cache;
 	u32 fps[HFI_MAX_HW_THREADS];
+	u32 dump_offset;
+	u32 dump_size;
 };
 
 enum cvp_event_t {
@@ -259,6 +261,7 @@ enum cvp_event_t {
 	CVP_MAX_CLIENTS_EVENT,
 	CVP_HW_UNSUPPORTED_EVENT,
 	CVP_INVALID_EVENT,
+	CVP_DUMP_EVENT,
 };
 
 struct cvp_session_event {

+ 24 - 0
msm/eva/msm_cvp_platform.c

@@ -340,6 +340,30 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[] = {
 		.is_config_pkt = true,
 		.resp = HAL_NO_RESP,
 	},
+	{
+		.size = 0xFFFFFFFF,
+		.type = HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS,
+		.is_config_pkt = true,
+		.resp = HAL_NO_RESP,
+	},
+	{
+		.size = 0xFFFFFFFF,
+		.type = HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS,
+		.is_config_pkt = true,
+		.resp = HAL_NO_RESP,
+	},
+	{
+		.size = 0xFFFFFFFF,
+		.type = HFI_CMD_SESSION_CVP_SET_SNAPSHOT_MODE,
+		.is_config_pkt = true,
+		.resp = HAL_NO_RESP,
+	},
+	{
+		.size = 0xFFFFFFFF,
+		.type = HFI_CMD_SESSION_CVP_SNAPSHOT_WRITE_DONE,
+		.is_config_pkt = true,
+		.resp = HAL_NO_RESP,
+	},
 	{
 		.size = 0xFFFFFFFF,
 		.type = HFI_CMD_SESSION_CVP_FD_CONFIG,