brintos

brintos / linux-shallow public Read only

0
0
Text · 21.2 KiB · 0a041b4 Raw
821 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.4 * Copyright (C) 2017 Linaro Ltd.5 */6#include <linux/hash.h>7#include <linux/list.h>8#include <linux/slab.h>9#include <linux/soc/qcom/smem.h>10#include <media/videobuf2-v4l2.h>11 12#include "core.h"13#include "hfi.h"14#include "hfi_helper.h"15#include "hfi_msgs.h"16#include "hfi_parser.h"17 18#define SMEM_IMG_VER_TBL	46919#define VER_STR_SZ		12820#define SMEM_IMG_OFFSET_VENUS	(14 * 128)21 22static void event_seq_changed(struct venus_core *core, struct venus_inst *inst,23			      struct hfi_msg_event_notify_pkt *pkt)24{25	enum hfi_version ver = core->res->hfi_version;26	struct hfi_event_data event = {0};27	int num_properties_changed;28	struct hfi_framesize *frame_sz;29	struct hfi_profile_level *profile_level;30	struct hfi_bit_depth *pixel_depth;31	struct hfi_pic_struct *pic_struct;32	struct hfi_colour_space *colour_info;33	struct hfi_buffer_requirements *bufreq;34	struct hfi_extradata_input_crop *crop;35	struct hfi_dpb_counts *dpb_count;36	u8 *data_ptr;37	u32 ptype;38 39	inst->error = HFI_ERR_NONE;40 41	switch (pkt->event_data1) {42	case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES:43	case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES:44		break;45	default:46		inst->error = HFI_ERR_SESSION_INVALID_PARAMETER;47		goto done;48	}49 50	event.event_type = pkt->event_data1;51 52	num_properties_changed = pkt->event_data2;53	if (!num_properties_changed) {54		inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;55		goto done;56	}57 58	data_ptr = (u8 *)&pkt->ext_event_data[0];59	do {60		ptype = *((u32 *)data_ptr);61		switch (ptype) {62		case HFI_PROPERTY_PARAM_FRAME_SIZE:63			data_ptr += sizeof(u32);64			frame_sz = (struct hfi_framesize *)data_ptr;65			event.width = frame_sz->width;66			event.height = frame_sz->height;67			data_ptr += sizeof(*frame_sz);68			break;69		case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:70			data_ptr += sizeof(u32);71			profile_level = (struct hfi_profile_level *)data_ptr;72			event.profile = profile_level->profile;73			event.level = profile_level->level;74			data_ptr += sizeof(*profile_level);75			break;76		case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:77			data_ptr += sizeof(u32);78			pixel_depth = (struct hfi_bit_depth *)data_ptr;79			event.bit_depth = pixel_depth->bit_depth;80			data_ptr += sizeof(*pixel_depth);81			break;82		case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:83			data_ptr += sizeof(u32);84			pic_struct = (struct hfi_pic_struct *)data_ptr;85			event.pic_struct = pic_struct->progressive_only;86			data_ptr += sizeof(*pic_struct);87			break;88		case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:89			data_ptr += sizeof(u32);90			colour_info = (struct hfi_colour_space *)data_ptr;91			event.colour_space = colour_info->colour_space;92			data_ptr += sizeof(*colour_info);93			break;94		case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:95			data_ptr += sizeof(u32);96			event.entropy_mode = *(u32 *)data_ptr;97			data_ptr += sizeof(u32);98			break;99		case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:100			data_ptr += sizeof(u32);101			bufreq = (struct hfi_buffer_requirements *)data_ptr;102			event.buf_count = hfi_bufreq_get_count_min(bufreq, ver);103			data_ptr += sizeof(*bufreq);104			break;105		case HFI_INDEX_EXTRADATA_INPUT_CROP:106			data_ptr += sizeof(u32);107			crop = (struct hfi_extradata_input_crop *)data_ptr;108			event.input_crop.left = crop->left;109			event.input_crop.top = crop->top;110			event.input_crop.width = crop->width;111			event.input_crop.height = crop->height;112			data_ptr += sizeof(*crop);113			break;114		case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS:115			data_ptr += sizeof(u32);116			dpb_count = (struct hfi_dpb_counts *)data_ptr;117			event.buf_count = dpb_count->fw_min_cnt;118			data_ptr += sizeof(*dpb_count);119			break;120		default:121			break;122		}123		num_properties_changed--;124	} while (num_properties_changed > 0);125 126done:127	inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);128}129 130static void event_release_buffer_ref(struct venus_core *core,131				     struct venus_inst *inst,132				     struct hfi_msg_event_notify_pkt *pkt)133{134	struct hfi_event_data event = {0};135	struct hfi_msg_event_release_buffer_ref_pkt *data;136 137	data = (struct hfi_msg_event_release_buffer_ref_pkt *)138		pkt->ext_event_data;139 140	event.event_type = HFI_EVENT_RELEASE_BUFFER_REFERENCE;141	event.packet_buffer = data->packet_buffer;142	event.extradata_buffer = data->extradata_buffer;143	event.tag = data->output_tag;144 145	inst->error = HFI_ERR_NONE;146	inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);147}148 149static void event_sys_error(struct venus_core *core, u32 event,150			    struct hfi_msg_event_notify_pkt *pkt)151{152	if (pkt)153		dev_dbg(core->dev, VDBGH154			"sys error (session id:%x, data1:%x, data2:%x)\n",155			pkt->shdr.session_id, pkt->event_data1,156			pkt->event_data2);157 158	core->core_ops->event_notify(core, event);159}160 161static void162event_session_error(struct venus_core *core, struct venus_inst *inst,163		    struct hfi_msg_event_notify_pkt *pkt)164{165	struct device *dev = core->dev;166 167	dev_dbg(dev, VDBGH "session error: event id:%x, session id:%x\n",168		pkt->event_data1, pkt->shdr.session_id);169 170	if (!inst)171		return;172 173	switch (pkt->event_data1) {174	/* non fatal session errors */175	case HFI_ERR_SESSION_INVALID_SCALE_FACTOR:176	case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE:177	case HFI_ERR_SESSION_UNSUPPORTED_SETTING:178	case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED:179		inst->error = HFI_ERR_NONE;180		break;181	default:182		dev_err(dev, "session error: event id:%x (%x), session id:%x\n",183			pkt->event_data1, pkt->event_data2,184			pkt->shdr.session_id);185 186		inst->error = pkt->event_data1;187		inst->ops->event_notify(inst, EVT_SESSION_ERROR, NULL);188		break;189	}190}191 192static void hfi_event_notify(struct venus_core *core, struct venus_inst *inst,193			     void *packet)194{195	struct hfi_msg_event_notify_pkt *pkt = packet;196 197	if (!packet)198		return;199 200	switch (pkt->event_id) {201	case HFI_EVENT_SYS_ERROR:202		event_sys_error(core, EVT_SYS_ERROR, pkt);203		break;204	case HFI_EVENT_SESSION_ERROR:205		event_session_error(core, inst, pkt);206		break;207	case HFI_EVENT_SESSION_SEQUENCE_CHANGED:208		event_seq_changed(core, inst, pkt);209		break;210	case HFI_EVENT_RELEASE_BUFFER_REFERENCE:211		event_release_buffer_ref(core, inst, pkt);212		break;213	case HFI_EVENT_SESSION_PROPERTY_CHANGED:214		break;215	default:216		break;217	}218}219 220static void hfi_sys_init_done(struct venus_core *core, struct venus_inst *inst,221			      void *packet)222{223	struct hfi_msg_sys_init_done_pkt *pkt = packet;224	int rem_bytes;225	u32 error;226 227	error = pkt->error_type;228	if (error != HFI_ERR_NONE)229		goto done;230 231	if (!pkt->num_properties) {232		error = HFI_ERR_SYS_INVALID_PARAMETER;233		goto done;234	}235 236	rem_bytes = pkt->hdr.size - sizeof(*pkt);237	if (rem_bytes <= 0) {238		/* missing property data */239		error = HFI_ERR_SYS_INSUFFICIENT_RESOURCES;240		goto done;241	}242 243	error = hfi_parser(core, inst, pkt->data, rem_bytes);244 245done:246	core->error = error;247	complete(&core->done);248}249 250static void251sys_get_prop_image_version(struct venus_core *core,252			   struct hfi_msg_sys_property_info_pkt *pkt)253{254	struct device *dev = core->dev;255	u8 *smem_tbl_ptr;256	u8 *img_ver;257	int req_bytes;258	size_t smem_blk_sz;259	int ret;260 261	req_bytes = pkt->hdr.size - sizeof(*pkt);262 263	if (req_bytes < VER_STR_SZ || !pkt->data[0] || pkt->num_properties > 1)264		/* bad packet */265		return;266 267	img_ver = pkt->data;268	if (!img_ver)269		return;270 271	ret = sscanf(img_ver, "14:video-firmware.%u.%u-%u",272		     &core->venus_ver.major, &core->venus_ver.minor, &core->venus_ver.rev);273	if (ret)274		goto done;275 276	ret = sscanf(img_ver, "14:VIDEO.VPU.%u.%u-%u",277		     &core->venus_ver.major, &core->venus_ver.minor, &core->venus_ver.rev);278	if (ret)279		goto done;280 281	ret = sscanf(img_ver, "14:VIDEO.VE.%u.%u-%u",282		     &core->venus_ver.major, &core->venus_ver.minor, &core->venus_ver.rev);283	if (ret)284		goto done;285 286	dev_err(dev, VDBGL "error reading F/W version\n");287	return;288 289done:290	dev_dbg(dev, VDBGL "F/W version: %s, major %u, minor %u, revision %u\n",291		img_ver, core->venus_ver.major, core->venus_ver.minor, core->venus_ver.rev);292 293	smem_tbl_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY,294		SMEM_IMG_VER_TBL, &smem_blk_sz);295	if (!IS_ERR(smem_tbl_ptr) && smem_blk_sz >= SMEM_IMG_OFFSET_VENUS + VER_STR_SZ)296		memcpy(smem_tbl_ptr + SMEM_IMG_OFFSET_VENUS,297		       img_ver, VER_STR_SZ);298}299 300static void hfi_sys_property_info(struct venus_core *core,301				  struct venus_inst *inst, void *packet)302{303	struct hfi_msg_sys_property_info_pkt *pkt = packet;304	struct device *dev = core->dev;305 306	if (!pkt->num_properties) {307		dev_dbg(dev, VDBGL "no properties\n");308		return;309	}310 311	switch (pkt->property) {312	case HFI_PROPERTY_SYS_IMAGE_VERSION:313		sys_get_prop_image_version(core, pkt);314		break;315	default:316		dev_dbg(dev, VDBGL "unknown property data\n");317		break;318	}319}320 321static void hfi_sys_rel_resource_done(struct venus_core *core,322				      struct venus_inst *inst,323				      void *packet)324{325	struct hfi_msg_sys_release_resource_done_pkt *pkt = packet;326 327	core->error = pkt->error_type;328	complete(&core->done);329}330 331static void hfi_sys_ping_done(struct venus_core *core, struct venus_inst *inst,332			      void *packet)333{334	struct hfi_msg_sys_ping_ack_pkt *pkt = packet;335 336	core->error = HFI_ERR_NONE;337 338	if (pkt->client_data != 0xbeef)339		core->error = HFI_ERR_SYS_FATAL;340 341	complete(&core->done);342}343 344static void hfi_sys_idle_done(struct venus_core *core, struct venus_inst *inst,345			      void *packet)346{347	dev_dbg(core->dev, VDBGL "sys idle\n");348}349 350static void hfi_sys_pc_prepare_done(struct venus_core *core,351				    struct venus_inst *inst, void *packet)352{353	struct hfi_msg_sys_pc_prep_done_pkt *pkt = packet;354 355	dev_dbg(core->dev, VDBGL "pc prepare done (error %x)\n",356		pkt->error_type);357}358 359static unsigned int360session_get_prop_profile_level(struct hfi_msg_session_property_info_pkt *pkt,361			       struct hfi_profile_level *profile_level)362{363	struct hfi_profile_level *hfi;364	u32 req_bytes;365 366	req_bytes = pkt->shdr.hdr.size - sizeof(*pkt);367 368	if (!req_bytes || req_bytes % sizeof(struct hfi_profile_level))369		/* bad packet */370		return HFI_ERR_SESSION_INVALID_PARAMETER;371 372	hfi = (struct hfi_profile_level *)&pkt->data[0];373	profile_level->profile = hfi->profile;374	profile_level->level = hfi->level;375 376	return HFI_ERR_NONE;377}378 379static unsigned int380session_get_prop_buf_req(struct hfi_msg_session_property_info_pkt *pkt,381			 struct hfi_buffer_requirements *bufreq)382{383	struct hfi_buffer_requirements *buf_req;384	u32 req_bytes;385	unsigned int idx = 0;386 387	req_bytes = pkt->shdr.hdr.size - sizeof(*pkt);388 389	if (!req_bytes || req_bytes % sizeof(*buf_req) || !pkt->data[0])390		/* bad packet */391		return HFI_ERR_SESSION_INVALID_PARAMETER;392 393	buf_req = (struct hfi_buffer_requirements *)&pkt->data[0];394	if (!buf_req)395		return HFI_ERR_SESSION_INVALID_PARAMETER;396 397	while (req_bytes) {398		memcpy(&bufreq[idx], buf_req, sizeof(*bufreq));399		idx++;400 401		if (idx >= HFI_BUFFER_TYPE_MAX)402			return HFI_ERR_SESSION_INVALID_PARAMETER;403 404		req_bytes -= sizeof(struct hfi_buffer_requirements);405		buf_req++;406	}407 408	return HFI_ERR_NONE;409}410 411static void hfi_session_prop_info(struct venus_core *core,412				  struct venus_inst *inst, void *packet)413{414	struct hfi_msg_session_property_info_pkt *pkt = packet;415	struct device *dev = core->dev;416	union hfi_get_property *hprop = &inst->hprop;417	unsigned int error = HFI_ERR_NONE;418 419	if (!pkt->num_properties) {420		error = HFI_ERR_SESSION_INVALID_PARAMETER;421		dev_err(dev, "%s: no properties\n", __func__);422		goto done;423	}424 425	switch (pkt->property) {426	case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:427		memset(hprop->bufreq, 0, sizeof(hprop->bufreq));428		error = session_get_prop_buf_req(pkt, hprop->bufreq);429		break;430	case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:431		memset(&hprop->profile_level, 0, sizeof(hprop->profile_level));432		error = session_get_prop_profile_level(pkt,433						       &hprop->profile_level);434		break;435	case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:436		break;437	default:438		dev_dbg(dev, VDBGM "unknown property id:%x\n", pkt->property);439		return;440	}441 442done:443	inst->error = error;444	complete(&inst->done);445}446 447static void hfi_session_init_done(struct venus_core *core,448				  struct venus_inst *inst, void *packet)449{450	struct hfi_msg_session_init_done_pkt *pkt = packet;451	int rem_bytes;452	u32 error;453 454	error = pkt->error_type;455	if (error != HFI_ERR_NONE)456		goto done;457 458	if (!IS_V1(core))459		goto done;460 461	rem_bytes = pkt->shdr.hdr.size - sizeof(*pkt);462	if (rem_bytes <= 0) {463		error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;464		goto done;465	}466 467	error = hfi_parser(core, inst, pkt->data, rem_bytes);468done:469	inst->error = error;470	complete(&inst->done);471}472 473static void hfi_session_load_res_done(struct venus_core *core,474				      struct venus_inst *inst, void *packet)475{476	struct hfi_msg_session_load_resources_done_pkt *pkt = packet;477 478	inst->error = pkt->error_type;479	complete(&inst->done);480}481 482static void hfi_session_flush_done(struct venus_core *core,483				   struct venus_inst *inst, void *packet)484{485	struct hfi_msg_session_flush_done_pkt *pkt = packet;486 487	inst->error = pkt->error_type;488	complete(&inst->done);489	if (inst->ops->flush_done)490		inst->ops->flush_done(inst);491}492 493static void hfi_session_etb_done(struct venus_core *core,494				 struct venus_inst *inst, void *packet)495{496	struct hfi_msg_session_empty_buffer_done_pkt *pkt = packet;497 498	inst->error = pkt->error_type;499	inst->ops->buf_done(inst, HFI_BUFFER_INPUT, pkt->input_tag,500			    pkt->filled_len, pkt->offset, 0, 0, 0);501}502 503static void hfi_session_ftb_done(struct venus_core *core,504				 struct venus_inst *inst, void *packet)505{506	u32 session_type = inst->session_type;507	u64 timestamp_us = 0;508	u32 timestamp_hi = 0, timestamp_lo = 0;509	unsigned int error;510	u32 flags = 0, hfi_flags = 0, offset = 0, filled_len = 0;511	u32 pic_type = 0, buffer_type = 0, output_tag = -1;512 513	if (session_type == VIDC_SESSION_TYPE_ENC) {514		struct hfi_msg_session_fbd_compressed_pkt *pkt = packet;515 516		timestamp_hi = pkt->time_stamp_hi;517		timestamp_lo = pkt->time_stamp_lo;518		hfi_flags = pkt->flags;519		offset = pkt->offset;520		filled_len = pkt->filled_len;521		pic_type = pkt->picture_type;522		output_tag = pkt->output_tag;523		buffer_type = HFI_BUFFER_OUTPUT;524 525		error = pkt->error_type;526	} else if (session_type == VIDC_SESSION_TYPE_DEC) {527		struct hfi_msg_session_fbd_uncompressed_plane0_pkt *pkt =528			packet;529 530		timestamp_hi = pkt->time_stamp_hi;531		timestamp_lo = pkt->time_stamp_lo;532		hfi_flags = pkt->flags;533		offset = pkt->offset;534		filled_len = pkt->filled_len;535		pic_type = pkt->picture_type;536		output_tag = pkt->output_tag;537 538		if (pkt->stream_id == 0)539			buffer_type = HFI_BUFFER_OUTPUT;540		else if (pkt->stream_id == 1)541			buffer_type = HFI_BUFFER_OUTPUT2;542 543		error = pkt->error_type;544	} else {545		error = HFI_ERR_SESSION_INVALID_PARAMETER;546	}547 548	if (buffer_type != HFI_BUFFER_OUTPUT &&549	    buffer_type != HFI_BUFFER_OUTPUT2)550		goto done;551 552	if (hfi_flags & HFI_BUFFERFLAG_EOS)553		flags |= V4L2_BUF_FLAG_LAST;554 555	switch (pic_type) {556	case HFI_PICTURE_IDR:557	case HFI_PICTURE_I:558		flags |= V4L2_BUF_FLAG_KEYFRAME;559		break;560	case HFI_PICTURE_P:561		flags |= V4L2_BUF_FLAG_PFRAME;562		break;563	case HFI_PICTURE_B:564		flags |= V4L2_BUF_FLAG_BFRAME;565		break;566	case HFI_FRAME_NOTCODED:567	case HFI_UNUSED_PICT:568	case HFI_FRAME_YUV:569	default:570		break;571	}572 573	if (!(hfi_flags & HFI_BUFFERFLAG_TIMESTAMPINVALID) && filled_len) {574		timestamp_us = timestamp_hi;575		timestamp_us = (timestamp_us << 32) | timestamp_lo;576	}577 578done:579	inst->error = error;580	inst->ops->buf_done(inst, buffer_type, output_tag, filled_len,581			    offset, flags, hfi_flags, timestamp_us);582}583 584static void hfi_session_start_done(struct venus_core *core,585				   struct venus_inst *inst, void *packet)586{587	struct hfi_msg_session_start_done_pkt *pkt = packet;588 589	inst->error = pkt->error_type;590	complete(&inst->done);591}592 593static void hfi_session_stop_done(struct venus_core *core,594				  struct venus_inst *inst, void *packet)595{596	struct hfi_msg_session_stop_done_pkt *pkt = packet;597 598	inst->error = pkt->error_type;599	complete(&inst->done);600}601 602static void hfi_session_rel_res_done(struct venus_core *core,603				     struct venus_inst *inst, void *packet)604{605	struct hfi_msg_session_release_resources_done_pkt *pkt = packet;606 607	inst->error = pkt->error_type;608	complete(&inst->done);609}610 611static void hfi_session_rel_buf_done(struct venus_core *core,612				     struct venus_inst *inst, void *packet)613{614	struct hfi_msg_session_release_buffers_done_pkt *pkt = packet;615 616	inst->error = pkt->error_type;617	complete(&inst->done);618}619 620static void hfi_session_end_done(struct venus_core *core,621				 struct venus_inst *inst, void *packet)622{623	struct hfi_msg_session_end_done_pkt *pkt = packet;624 625	inst->error = pkt->error_type;626	complete(&inst->done);627}628 629static void hfi_session_abort_done(struct venus_core *core,630				   struct venus_inst *inst, void *packet)631{632	struct hfi_msg_sys_session_abort_done_pkt *pkt = packet;633 634	inst->error = pkt->error_type;635	complete(&inst->done);636}637 638static void hfi_session_get_seq_hdr_done(struct venus_core *core,639					 struct venus_inst *inst, void *packet)640{641	struct hfi_msg_session_get_sequence_hdr_done_pkt *pkt = packet;642 643	inst->error = pkt->error_type;644	complete(&inst->done);645}646 647struct hfi_done_handler {648	u32 pkt;649	u32 pkt_sz;650	u32 pkt_sz2;651	void (*done)(struct venus_core *, struct venus_inst *, void *);652	bool is_sys_pkt;653};654 655static const struct hfi_done_handler handlers[] = {656	{.pkt = HFI_MSG_EVENT_NOTIFY,657	 .pkt_sz = sizeof(struct hfi_msg_event_notify_pkt),658	 .done = hfi_event_notify,659	},660	{.pkt = HFI_MSG_SYS_INIT,661	 .pkt_sz = sizeof(struct hfi_msg_sys_init_done_pkt),662	 .done = hfi_sys_init_done,663	 .is_sys_pkt = true,664	},665	{.pkt = HFI_MSG_SYS_PROPERTY_INFO,666	 .pkt_sz = sizeof(struct hfi_msg_sys_property_info_pkt),667	 .done = hfi_sys_property_info,668	 .is_sys_pkt = true,669	},670	{.pkt = HFI_MSG_SYS_RELEASE_RESOURCE,671	 .pkt_sz = sizeof(struct hfi_msg_sys_release_resource_done_pkt),672	 .done = hfi_sys_rel_resource_done,673	 .is_sys_pkt = true,674	},675	{.pkt = HFI_MSG_SYS_PING_ACK,676	 .pkt_sz = sizeof(struct hfi_msg_sys_ping_ack_pkt),677	 .done = hfi_sys_ping_done,678	 .is_sys_pkt = true,679	},680	{.pkt = HFI_MSG_SYS_IDLE,681	 .pkt_sz = sizeof(struct hfi_msg_sys_idle_pkt),682	 .done = hfi_sys_idle_done,683	 .is_sys_pkt = true,684	},685	{.pkt = HFI_MSG_SYS_PC_PREP,686	 .pkt_sz = sizeof(struct hfi_msg_sys_pc_prep_done_pkt),687	 .done = hfi_sys_pc_prepare_done,688	 .is_sys_pkt = true,689	},690	{.pkt = HFI_MSG_SYS_SESSION_INIT,691	 .pkt_sz = sizeof(struct hfi_msg_session_init_done_pkt),692	 .done = hfi_session_init_done,693	},694	{.pkt = HFI_MSG_SYS_SESSION_END,695	 .pkt_sz = sizeof(struct hfi_msg_session_end_done_pkt),696	 .done = hfi_session_end_done,697	},698	{.pkt = HFI_MSG_SESSION_LOAD_RESOURCES,699	 .pkt_sz = sizeof(struct hfi_msg_session_load_resources_done_pkt),700	 .done = hfi_session_load_res_done,701	},702	{.pkt = HFI_MSG_SESSION_START,703	 .pkt_sz = sizeof(struct hfi_msg_session_start_done_pkt),704	 .done = hfi_session_start_done,705	},706	{.pkt = HFI_MSG_SESSION_STOP,707	 .pkt_sz = sizeof(struct hfi_msg_session_stop_done_pkt),708	 .done = hfi_session_stop_done,709	},710	{.pkt = HFI_MSG_SYS_SESSION_ABORT,711	 .pkt_sz = sizeof(struct hfi_msg_sys_session_abort_done_pkt),712	 .done = hfi_session_abort_done,713	},714	{.pkt = HFI_MSG_SESSION_EMPTY_BUFFER,715	 .pkt_sz = sizeof(struct hfi_msg_session_empty_buffer_done_pkt),716	 .done = hfi_session_etb_done,717	},718	{.pkt = HFI_MSG_SESSION_FILL_BUFFER,719	 .pkt_sz = sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_pkt),720	 .pkt_sz2 = sizeof(struct hfi_msg_session_fbd_compressed_pkt),721	 .done = hfi_session_ftb_done,722	},723	{.pkt = HFI_MSG_SESSION_FLUSH,724	 .pkt_sz = sizeof(struct hfi_msg_session_flush_done_pkt),725	 .done = hfi_session_flush_done,726	},727	{.pkt = HFI_MSG_SESSION_PROPERTY_INFO,728	 .pkt_sz = sizeof(struct hfi_msg_session_property_info_pkt),729	 .done = hfi_session_prop_info,730	},731	{.pkt = HFI_MSG_SESSION_RELEASE_RESOURCES,732	 .pkt_sz = sizeof(struct hfi_msg_session_release_resources_done_pkt),733	 .done = hfi_session_rel_res_done,734	},735	{.pkt = HFI_MSG_SESSION_GET_SEQUENCE_HEADER,736	 .pkt_sz = sizeof(struct hfi_msg_session_get_sequence_hdr_done_pkt),737	 .done = hfi_session_get_seq_hdr_done,738	},739	{.pkt = HFI_MSG_SESSION_RELEASE_BUFFERS,740	 .pkt_sz = sizeof(struct hfi_msg_session_release_buffers_done_pkt),741	 .done = hfi_session_rel_buf_done,742	},743};744 745void hfi_process_watchdog_timeout(struct venus_core *core)746{747	event_sys_error(core, EVT_SYS_WATCHDOG_TIMEOUT, NULL);748}749 750static struct venus_inst *to_instance(struct venus_core *core, u32 session_id)751{752	struct venus_inst *inst;753 754	mutex_lock(&core->lock);755	list_for_each_entry(inst, &core->instances, list)756		if (hash32_ptr(inst) == session_id) {757			mutex_unlock(&core->lock);758			return inst;759		}760	mutex_unlock(&core->lock);761 762	return NULL;763}764 765u32 hfi_process_msg_packet(struct venus_core *core, struct hfi_pkt_hdr *hdr)766{767	const struct hfi_done_handler *handler;768	struct device *dev = core->dev;769	struct venus_inst *inst;770	bool found = false;771	unsigned int i;772 773	for (i = 0; i < ARRAY_SIZE(handlers); i++) {774		handler = &handlers[i];775		if (handler->pkt != hdr->pkt_type)776			continue;777		found = true;778		break;779	}780 781	if (!found)782		return hdr->pkt_type;783 784	if (hdr->size && hdr->size < handler->pkt_sz &&785	    hdr->size < handler->pkt_sz2) {786		dev_err(dev, "bad packet size (%d should be %d, pkt type:%x)\n",787			hdr->size, handler->pkt_sz, hdr->pkt_type);788 789		return hdr->pkt_type;790	}791 792	if (handler->is_sys_pkt) {793		inst = NULL;794	} else {795		struct hfi_session_pkt *pkt;796 797		pkt = (struct hfi_session_pkt *)hdr;798		inst = to_instance(core, pkt->shdr.session_id);799 800		if (!inst)801			dev_warn(dev, "no valid instance(pkt session_id:%x, pkt:%x)\n",802				 pkt->shdr.session_id,803				 handler ? handler->pkt : 0);804 805		/*806		 * Event of type HFI_EVENT_SYS_ERROR will not have any session807		 * associated with it808		 */809		if (!inst && hdr->pkt_type != HFI_MSG_EVENT_NOTIFY) {810			dev_err(dev, "got invalid session id:%x\n",811				pkt->shdr.session_id);812			goto invalid_session;813		}814	}815 816	handler->done(core, inst, hdr);817 818invalid_session:819	return hdr->pkt_type;820}821