1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  */
5 
6 #include <linux/bitfield.h>
7 #include <media/v4l2-mem2mem.h>
8 
9 #include "iris_hfi_gen1.h"
10 #include "iris_hfi_gen1_defines.h"
11 #include "iris_instance.h"
12 #include "iris_vdec.h"
13 #include "iris_vpu_buffer.h"
14 
iris_hfi_gen1_read_changed_params(struct iris_inst * inst,struct hfi_msg_event_notify_pkt * pkt)15 static void iris_hfi_gen1_read_changed_params(struct iris_inst *inst,
16 					      struct hfi_msg_event_notify_pkt *pkt)
17 {
18 	struct v4l2_pix_format_mplane *pixmp_ip = &inst->fmt_src->fmt.pix_mp;
19 	struct v4l2_pix_format_mplane *pixmp_op = &inst->fmt_dst->fmt.pix_mp;
20 	u32 num_properties_changed = pkt->event_data2;
21 	u8 *data_ptr = (u8 *)&pkt->ext_event_data[0];
22 	u32 primaries, matrix_coeff, transfer_char;
23 	struct hfi_dpb_counts *iris_vpu_dpb_count;
24 	struct hfi_profile_level *profile_level;
25 	struct hfi_buffer_requirements *bufreq;
26 	struct hfi_extradata_input_crop *crop;
27 	struct hfi_colour_space *colour_info;
28 	struct iris_core *core = inst->core;
29 	u32 colour_description_present_flag;
30 	u32 video_signal_type_present_flag;
31 	struct hfi_event_data event = {0};
32 	struct hfi_bit_depth *pixel_depth;
33 	struct hfi_pic_struct *pic_struct;
34 	struct hfi_framesize *frame_sz;
35 	struct vb2_queue *dst_q;
36 	struct v4l2_ctrl *ctrl;
37 	u32 full_range, ptype;
38 
39 	do {
40 		ptype = *((u32 *)data_ptr);
41 		switch (ptype) {
42 		case HFI_PROPERTY_PARAM_FRAME_SIZE:
43 			data_ptr += sizeof(u32);
44 			frame_sz = (struct hfi_framesize *)data_ptr;
45 			event.width = frame_sz->width;
46 			event.height = frame_sz->height;
47 			data_ptr += sizeof(*frame_sz);
48 			break;
49 		case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
50 			data_ptr += sizeof(u32);
51 			profile_level = (struct hfi_profile_level *)data_ptr;
52 			event.profile = profile_level->profile;
53 			event.level = profile_level->level;
54 			data_ptr += sizeof(*profile_level);
55 			break;
56 		case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
57 			data_ptr += sizeof(u32);
58 			pixel_depth = (struct hfi_bit_depth *)data_ptr;
59 			event.bit_depth = pixel_depth->bit_depth;
60 			data_ptr += sizeof(*pixel_depth);
61 			break;
62 		case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
63 			data_ptr += sizeof(u32);
64 			pic_struct = (struct hfi_pic_struct *)data_ptr;
65 			event.pic_struct = pic_struct->progressive_only;
66 			data_ptr += sizeof(*pic_struct);
67 			break;
68 		case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
69 			data_ptr += sizeof(u32);
70 			colour_info = (struct hfi_colour_space *)data_ptr;
71 			event.colour_space = colour_info->colour_space;
72 			data_ptr += sizeof(*colour_info);
73 			break;
74 		case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
75 			data_ptr += sizeof(u32);
76 			event.entropy_mode = *(u32 *)data_ptr;
77 			data_ptr += sizeof(u32);
78 			break;
79 		case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
80 			data_ptr += sizeof(u32);
81 			bufreq = (struct hfi_buffer_requirements *)data_ptr;
82 			event.buf_count = bufreq->count_min;
83 			data_ptr += sizeof(*bufreq);
84 			break;
85 		case HFI_INDEX_EXTRADATA_INPUT_CROP:
86 			data_ptr += sizeof(u32);
87 			crop = (struct hfi_extradata_input_crop *)data_ptr;
88 			event.input_crop.left = crop->left;
89 			event.input_crop.top = crop->top;
90 			event.input_crop.width = crop->width;
91 			event.input_crop.height = crop->height;
92 			data_ptr += sizeof(*crop);
93 			break;
94 		case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS:
95 			data_ptr += sizeof(u32);
96 			iris_vpu_dpb_count = (struct hfi_dpb_counts *)data_ptr;
97 			event.buf_count = iris_vpu_dpb_count->fw_min_count;
98 			data_ptr += sizeof(*iris_vpu_dpb_count);
99 			break;
100 		default:
101 			break;
102 		}
103 		num_properties_changed--;
104 	} while (num_properties_changed > 0);
105 
106 	pixmp_ip->width = event.width;
107 	pixmp_ip->height = event.height;
108 
109 	pixmp_op->width = ALIGN(event.width, 128);
110 	pixmp_op->height = ALIGN(event.height, 32);
111 	pixmp_op->plane_fmt[0].bytesperline = ALIGN(event.width, 128);
112 	pixmp_op->plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
113 
114 	matrix_coeff =  FIELD_GET(GENMASK(7, 0), event.colour_space);
115 	transfer_char = FIELD_GET(GENMASK(15, 8), event.colour_space);
116 	primaries = FIELD_GET(GENMASK(23, 16), event.colour_space);
117 	colour_description_present_flag = FIELD_GET(GENMASK(24, 24), event.colour_space);
118 	full_range = FIELD_GET(GENMASK(25, 25), event.colour_space);
119 	video_signal_type_present_flag = FIELD_GET(GENMASK(29, 29), event.colour_space);
120 
121 	pixmp_op->colorspace = V4L2_COLORSPACE_DEFAULT;
122 	pixmp_op->xfer_func = V4L2_XFER_FUNC_DEFAULT;
123 	pixmp_op->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
124 	pixmp_op->quantization = V4L2_QUANTIZATION_DEFAULT;
125 
126 	if (video_signal_type_present_flag) {
127 		pixmp_op->quantization =
128 			full_range ?
129 			V4L2_QUANTIZATION_FULL_RANGE :
130 			V4L2_QUANTIZATION_LIM_RANGE;
131 		if (colour_description_present_flag) {
132 			pixmp_op->colorspace =
133 				iris_hfi_get_v4l2_color_primaries(primaries);
134 			pixmp_op->xfer_func =
135 				iris_hfi_get_v4l2_transfer_char(transfer_char);
136 			pixmp_op->ycbcr_enc =
137 				iris_hfi_get_v4l2_matrix_coefficients(matrix_coeff);
138 		}
139 	}
140 
141 	pixmp_ip->colorspace = pixmp_op->colorspace;
142 	pixmp_ip->xfer_func = pixmp_op->xfer_func;
143 	pixmp_ip->ycbcr_enc = pixmp_op->ycbcr_enc;
144 	pixmp_ip->quantization = pixmp_op->quantization;
145 
146 	if (event.input_crop.width > 0 && event.input_crop.height > 0) {
147 		inst->crop.left = event.input_crop.left;
148 		inst->crop.top = event.input_crop.top;
149 		inst->crop.width = event.input_crop.width;
150 		inst->crop.height = event.input_crop.height;
151 	} else {
152 		inst->crop.left = 0;
153 		inst->crop.top = 0;
154 		inst->crop.width = event.width;
155 		inst->crop.height = event.height;
156 	}
157 
158 	inst->fw_min_count = event.buf_count;
159 	inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
160 	inst->buffers[BUF_OUTPUT].size = pixmp_op->plane_fmt[0].sizeimage;
161 	ctrl = v4l2_ctrl_find(&inst->ctrl_handler, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE);
162 	if (ctrl)
163 		v4l2_ctrl_s_ctrl(ctrl, inst->buffers[BUF_OUTPUT].min_count);
164 
165 	dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
166 	dst_q->min_reqbufs_allocation = inst->buffers[BUF_OUTPUT].min_count;
167 
168 	if (event.bit_depth || !event.pic_struct) {
169 		dev_err(core->dev, "unsupported content, bit depth: %x, pic_struct = %x\n",
170 			event.bit_depth, event.pic_struct);
171 		iris_inst_change_state(inst, IRIS_INST_ERROR);
172 	}
173 }
174 
iris_hfi_gen1_event_seq_changed(struct iris_inst * inst,struct hfi_msg_event_notify_pkt * pkt)175 static void iris_hfi_gen1_event_seq_changed(struct iris_inst *inst,
176 					    struct hfi_msg_event_notify_pkt *pkt)
177 {
178 	struct hfi_session_flush_pkt flush_pkt;
179 	u32 num_properties_changed;
180 	int ret;
181 
182 	ret = iris_inst_sub_state_change_drc(inst);
183 	if (ret)
184 		return;
185 
186 	switch (pkt->event_data1) {
187 	case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES:
188 	case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES:
189 		break;
190 	default:
191 		iris_inst_change_state(inst, IRIS_INST_ERROR);
192 		return;
193 	}
194 
195 	num_properties_changed = pkt->event_data2;
196 	if (!num_properties_changed) {
197 		iris_inst_change_state(inst, IRIS_INST_ERROR);
198 		return;
199 	}
200 
201 	iris_hfi_gen1_read_changed_params(inst, pkt);
202 
203 	if (inst->state != IRIS_INST_ERROR) {
204 		reinit_completion(&inst->flush_completion);
205 
206 		flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);
207 		flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
208 		flush_pkt.shdr.session_id = inst->session_id;
209 		flush_pkt.flush_type = HFI_FLUSH_OUTPUT;
210 		iris_hfi_queue_cmd_write(inst->core, &flush_pkt, flush_pkt.shdr.hdr.size);
211 	}
212 
213 	iris_vdec_src_change(inst);
214 	iris_inst_sub_state_change_drc_last(inst);
215 }
216 
217 static void
iris_hfi_gen1_sys_event_notify(struct iris_core * core,void * packet)218 iris_hfi_gen1_sys_event_notify(struct iris_core *core, void *packet)
219 {
220 	struct hfi_msg_event_notify_pkt *pkt = packet;
221 	struct iris_inst *instance;
222 
223 	if (pkt->event_id == HFI_EVENT_SYS_ERROR)
224 		dev_err(core->dev, "sys error (type: %x, session id:%x, data1:%x, data2:%x)\n",
225 			pkt->event_id, pkt->shdr.session_id, pkt->event_data1,
226 			pkt->event_data2);
227 
228 	core->state = IRIS_CORE_ERROR;
229 
230 	mutex_lock(&core->lock);
231 	list_for_each_entry(instance, &core->instances, list)
232 		iris_inst_change_state(instance, IRIS_INST_ERROR);
233 	mutex_unlock(&core->lock);
234 
235 	schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10));
236 }
237 
238 static void
iris_hfi_gen1_event_session_error(struct iris_inst * inst,struct hfi_msg_event_notify_pkt * pkt)239 iris_hfi_gen1_event_session_error(struct iris_inst *inst, struct hfi_msg_event_notify_pkt *pkt)
240 {
241 	switch (pkt->event_data1) {
242 	/* non fatal session errors */
243 	case HFI_ERR_SESSION_INVALID_SCALE_FACTOR:
244 	case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE:
245 	case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
246 	case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED:
247 		dev_dbg(inst->core->dev, "session error: event id:%x, session id:%x\n",
248 			pkt->event_data1, pkt->shdr.session_id);
249 		break;
250 	/* fatal session errors */
251 	default:
252 		/*
253 		 * firmware fills event_data2 as an additional information about the
254 		 * hfi command for which session error has ouccured.
255 		 */
256 		dev_err(inst->core->dev,
257 			"session error for command: %x, event id:%x, session id:%x\n",
258 			pkt->event_data2, pkt->event_data1,
259 			pkt->shdr.session_id);
260 		iris_vb2_queue_error(inst);
261 		iris_inst_change_state(inst, IRIS_INST_ERROR);
262 		break;
263 	}
264 }
265 
iris_hfi_gen1_session_event_notify(struct iris_inst * inst,void * packet)266 static void iris_hfi_gen1_session_event_notify(struct iris_inst *inst, void *packet)
267 {
268 	struct hfi_msg_event_notify_pkt *pkt = packet;
269 
270 	switch (pkt->event_id) {
271 	case HFI_EVENT_SESSION_ERROR:
272 		iris_hfi_gen1_event_session_error(inst, pkt);
273 		break;
274 	case HFI_EVENT_SESSION_SEQUENCE_CHANGED:
275 		iris_hfi_gen1_event_seq_changed(inst, pkt);
276 		break;
277 	default:
278 		break;
279 	}
280 }
281 
iris_hfi_gen1_sys_init_done(struct iris_core * core,void * packet)282 static void iris_hfi_gen1_sys_init_done(struct iris_core *core, void *packet)
283 {
284 	struct hfi_msg_sys_init_done_pkt *pkt = packet;
285 
286 	if (pkt->error_type != HFI_ERR_NONE) {
287 		core->state = IRIS_CORE_ERROR;
288 		return;
289 	}
290 
291 	complete(&core->core_init_done);
292 }
293 
294 static void
iris_hfi_gen1_sys_get_prop_image_version(struct iris_core * core,struct hfi_msg_sys_property_info_pkt * pkt)295 iris_hfi_gen1_sys_get_prop_image_version(struct iris_core *core,
296 					 struct hfi_msg_sys_property_info_pkt *pkt)
297 {
298 	int req_bytes = pkt->hdr.size - sizeof(*pkt);
299 	char fw_version[IRIS_FW_VERSION_LENGTH];
300 	u8 *str_image_version;
301 	u32 i;
302 
303 	if (req_bytes < IRIS_FW_VERSION_LENGTH - 1 || !pkt->data[0] || pkt->num_properties > 1) {
304 		dev_err(core->dev, "bad packet\n");
305 		return;
306 	}
307 
308 	str_image_version = pkt->data;
309 	if (!str_image_version) {
310 		dev_err(core->dev, "firmware version not available\n");
311 		return;
312 	}
313 
314 	for (i = 0; i < IRIS_FW_VERSION_LENGTH - 1; i++) {
315 		if (str_image_version[i] != '\0')
316 			fw_version[i] = str_image_version[i];
317 		else
318 			fw_version[i] = ' ';
319 	}
320 	fw_version[i] = '\0';
321 	dev_dbg(core->dev, "firmware version: %s\n", fw_version);
322 }
323 
iris_hfi_gen1_sys_property_info(struct iris_core * core,void * packet)324 static void iris_hfi_gen1_sys_property_info(struct iris_core *core, void *packet)
325 {
326 	struct hfi_msg_sys_property_info_pkt *pkt = packet;
327 
328 	if (!pkt->num_properties) {
329 		dev_dbg(core->dev, "no properties\n");
330 		return;
331 	}
332 
333 	switch (pkt->property) {
334 	case HFI_PROPERTY_SYS_IMAGE_VERSION:
335 		iris_hfi_gen1_sys_get_prop_image_version(core, pkt);
336 		break;
337 	default:
338 		dev_dbg(core->dev, "unknown property data\n");
339 		break;
340 	}
341 }
342 
iris_hfi_gen1_session_etb_done(struct iris_inst * inst,void * packet)343 static void iris_hfi_gen1_session_etb_done(struct iris_inst *inst, void *packet)
344 {
345 	struct hfi_msg_session_empty_buffer_done_pkt *pkt = packet;
346 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
347 	struct v4l2_m2m_buffer *m2m_buffer, *n;
348 	struct iris_buffer *buf = NULL;
349 	bool found = false;
350 
351 	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) {
352 		buf = to_iris_buffer(&m2m_buffer->vb);
353 		if (buf->index == pkt->input_tag) {
354 			found = true;
355 			break;
356 		}
357 	}
358 	if (!found)
359 		goto error;
360 
361 	if (pkt->shdr.error_type == HFI_ERR_SESSION_UNSUPPORTED_STREAM) {
362 		buf->flags = V4L2_BUF_FLAG_ERROR;
363 		iris_vb2_queue_error(inst);
364 		iris_inst_change_state(inst, IRIS_INST_ERROR);
365 	}
366 
367 	if (!(buf->attr & BUF_ATTR_QUEUED))
368 		return;
369 
370 	buf->attr &= ~BUF_ATTR_QUEUED;
371 
372 	if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
373 		buf->attr |= BUF_ATTR_BUFFER_DONE;
374 		iris_vb2_buffer_done(inst, buf);
375 	}
376 
377 	return;
378 
379 error:
380 	iris_inst_change_state(inst, IRIS_INST_ERROR);
381 	dev_err(inst->core->dev, "error in etb done\n");
382 }
383 
iris_hfi_gen1_session_ftb_done(struct iris_inst * inst,void * packet)384 static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet)
385 {
386 	struct hfi_msg_session_fbd_uncompressed_plane0_pkt *pkt = packet;
387 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
388 	struct v4l2_m2m_buffer *m2m_buffer, *n;
389 	struct hfi_session_flush_pkt flush_pkt;
390 	u32 timestamp_hi = pkt->time_stamp_hi;
391 	u32 timestamp_lo = pkt->time_stamp_lo;
392 	struct iris_core *core = inst->core;
393 	u32 filled_len = pkt->filled_len;
394 	u32 pic_type = pkt->picture_type;
395 	u32 output_tag = pkt->output_tag;
396 	struct iris_buffer *buf, *iter;
397 	struct iris_buffers *buffers;
398 	u32 hfi_flags = pkt->flags;
399 	u32 offset = pkt->offset;
400 	u64 timestamp_us = 0;
401 	bool found = false;
402 	u32 flags = 0;
403 
404 	if ((hfi_flags & HFI_BUFFERFLAG_EOS) && !filled_len) {
405 		reinit_completion(&inst->flush_completion);
406 
407 		flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);
408 		flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
409 		flush_pkt.shdr.session_id = inst->session_id;
410 		flush_pkt.flush_type = HFI_FLUSH_OUTPUT;
411 		iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size);
412 		iris_inst_sub_state_change_drain_last(inst);
413 
414 		return;
415 	}
416 
417 	if (iris_split_mode_enabled(inst) && pkt->stream_id == 0) {
418 		buffers = &inst->buffers[BUF_DPB];
419 		if (!buffers)
420 			goto error;
421 
422 		found = false;
423 		list_for_each_entry(iter, &buffers->list, list) {
424 			if (!(iter->attr & BUF_ATTR_QUEUED))
425 				continue;
426 
427 			found = (iter->index == output_tag &&
428 				iter->data_offset == offset);
429 
430 			if (found) {
431 				buf = iter;
432 				break;
433 			}
434 		}
435 	} else {
436 		v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, m2m_buffer, n) {
437 			buf = to_iris_buffer(&m2m_buffer->vb);
438 			if (!(buf->attr & BUF_ATTR_QUEUED))
439 				continue;
440 
441 			found = (buf->index == output_tag &&
442 				 buf->data_offset == offset);
443 
444 			if (found)
445 				break;
446 		}
447 	}
448 	if (!found)
449 		goto error;
450 
451 	buf->data_offset = offset;
452 	buf->data_size = filled_len;
453 
454 	if (filled_len) {
455 		timestamp_us = timestamp_hi;
456 		timestamp_us = (timestamp_us << 32) | timestamp_lo;
457 	} else {
458 		flags |= V4L2_BUF_FLAG_LAST;
459 	}
460 	buf->timestamp = timestamp_us;
461 
462 	switch (pic_type) {
463 	case HFI_PICTURE_IDR:
464 	case HFI_PICTURE_I:
465 		flags |= V4L2_BUF_FLAG_KEYFRAME;
466 		break;
467 	case HFI_PICTURE_P:
468 		flags |= V4L2_BUF_FLAG_PFRAME;
469 		break;
470 	case HFI_PICTURE_B:
471 		flags |= V4L2_BUF_FLAG_BFRAME;
472 		break;
473 	case HFI_FRAME_NOTCODED:
474 	case HFI_UNUSED_PICT:
475 	case HFI_FRAME_YUV:
476 	default:
477 		break;
478 	}
479 
480 	buf->attr &= ~BUF_ATTR_QUEUED;
481 	buf->attr |= BUF_ATTR_DEQUEUED;
482 	buf->attr |= BUF_ATTR_BUFFER_DONE;
483 
484 	buf->flags |= flags;
485 
486 	iris_vb2_buffer_done(inst, buf);
487 
488 	return;
489 
490 error:
491 	iris_inst_change_state(inst, IRIS_INST_ERROR);
492 	dev_err(core->dev, "error in ftb done\n");
493 }
494 
495 struct iris_hfi_gen1_response_pkt_info {
496 	u32 pkt;
497 	u32 pkt_sz;
498 };
499 
500 static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = {
501 	{
502 	 .pkt = HFI_MSG_EVENT_NOTIFY,
503 	 .pkt_sz = sizeof(struct hfi_msg_event_notify_pkt),
504 	},
505 	{
506 	 .pkt = HFI_MSG_SYS_INIT,
507 	 .pkt_sz = sizeof(struct hfi_msg_sys_init_done_pkt),
508 	},
509 	{
510 	 .pkt = HFI_MSG_SYS_PROPERTY_INFO,
511 	 .pkt_sz = sizeof(struct hfi_msg_sys_property_info_pkt),
512 	},
513 	{
514 	 .pkt = HFI_MSG_SYS_SESSION_INIT,
515 	 .pkt_sz = sizeof(struct hfi_msg_session_init_done_pkt),
516 	},
517 	{
518 	 .pkt = HFI_MSG_SYS_SESSION_END,
519 	 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
520 	},
521 	{
522 	 .pkt = HFI_MSG_SESSION_LOAD_RESOURCES,
523 	 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
524 	},
525 	{
526 	 .pkt = HFI_MSG_SESSION_START,
527 	 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
528 	},
529 	{
530 	 .pkt = HFI_MSG_SESSION_STOP,
531 	 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
532 	},
533 	{
534 	 .pkt = HFI_MSG_SESSION_EMPTY_BUFFER,
535 	 .pkt_sz = sizeof(struct hfi_msg_session_empty_buffer_done_pkt),
536 	},
537 	{
538 	 .pkt = HFI_MSG_SESSION_FILL_BUFFER,
539 	 .pkt_sz = sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_pkt),
540 	},
541 	{
542 	 .pkt = HFI_MSG_SESSION_FLUSH,
543 	 .pkt_sz = sizeof(struct hfi_msg_session_flush_done_pkt),
544 	},
545 	{
546 	 .pkt = HFI_MSG_SESSION_RELEASE_RESOURCES,
547 	 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
548 	},
549 	{
550 	 .pkt = HFI_MSG_SESSION_RELEASE_BUFFERS,
551 	 .pkt_sz = sizeof(struct hfi_msg_session_release_buffers_done_pkt),
552 	},
553 };
554 
iris_hfi_gen1_handle_response(struct iris_core * core,void * response)555 static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response)
556 {
557 	struct hfi_pkt_hdr *hdr = (struct hfi_pkt_hdr *)response;
558 	const struct iris_hfi_gen1_response_pkt_info *pkt_info;
559 	struct device *dev = core->dev;
560 	struct hfi_session_pkt *pkt;
561 	struct completion *done;
562 	struct iris_inst *inst;
563 	bool found = false;
564 	u32 i;
565 
566 	for (i = 0; i < ARRAY_SIZE(pkt_infos); i++) {
567 		pkt_info = &pkt_infos[i];
568 		if (pkt_info->pkt != hdr->pkt_type)
569 			continue;
570 		found = true;
571 		break;
572 	}
573 
574 	if (!found || hdr->size < pkt_info->pkt_sz) {
575 		dev_err(dev, "bad packet size (%d should be %d, pkt type:%x, found %d)\n",
576 			hdr->size, pkt_info->pkt_sz, hdr->pkt_type, found);
577 
578 		return;
579 	}
580 
581 	switch (hdr->pkt_type) {
582 	case HFI_MSG_SYS_INIT:
583 		iris_hfi_gen1_sys_init_done(core, hdr);
584 		break;
585 	case HFI_MSG_SYS_PROPERTY_INFO:
586 		iris_hfi_gen1_sys_property_info(core, hdr);
587 		break;
588 	case HFI_MSG_EVENT_NOTIFY:
589 		pkt = (struct hfi_session_pkt *)hdr;
590 		inst = iris_get_instance(core, pkt->shdr.session_id);
591 		if (inst) {
592 			mutex_lock(&inst->lock);
593 			iris_hfi_gen1_session_event_notify(inst, hdr);
594 			mutex_unlock(&inst->lock);
595 		} else {
596 			iris_hfi_gen1_sys_event_notify(core, hdr);
597 		}
598 
599 		break;
600 	default:
601 		pkt = (struct hfi_session_pkt *)hdr;
602 		inst = iris_get_instance(core, pkt->shdr.session_id);
603 		if (!inst) {
604 			dev_warn(dev, "no valid instance(pkt session_id:%x, pkt:%x)\n",
605 				 pkt->shdr.session_id,
606 				 pkt_info ? pkt_info->pkt : 0);
607 			return;
608 		}
609 
610 		mutex_lock(&inst->lock);
611 		if (hdr->pkt_type == HFI_MSG_SESSION_EMPTY_BUFFER) {
612 			iris_hfi_gen1_session_etb_done(inst, hdr);
613 		} else if (hdr->pkt_type == HFI_MSG_SESSION_FILL_BUFFER) {
614 			iris_hfi_gen1_session_ftb_done(inst, hdr);
615 		} else {
616 			struct hfi_msg_session_hdr_pkt *shdr;
617 
618 			shdr = (struct hfi_msg_session_hdr_pkt *)hdr;
619 			if (shdr->error_type != HFI_ERR_NONE)
620 				iris_inst_change_state(inst, IRIS_INST_ERROR);
621 
622 			done = pkt_info->pkt == HFI_MSG_SESSION_FLUSH ?
623 				&inst->flush_completion : &inst->completion;
624 			complete(done);
625 		}
626 		mutex_unlock(&inst->lock);
627 
628 		break;
629 	}
630 }
631 
iris_hfi_gen1_flush_debug_queue(struct iris_core * core,u8 * packet)632 static void iris_hfi_gen1_flush_debug_queue(struct iris_core *core, u8 *packet)
633 {
634 	struct hfi_msg_sys_coverage_pkt *pkt;
635 
636 	while (!iris_hfi_queue_dbg_read(core, packet)) {
637 		pkt = (struct hfi_msg_sys_coverage_pkt *)packet;
638 
639 		if (pkt->hdr.pkt_type != HFI_MSG_SYS_COV) {
640 			struct hfi_msg_sys_debug_pkt *pkt =
641 				(struct hfi_msg_sys_debug_pkt *)packet;
642 
643 			dev_dbg(core->dev, "%s", pkt->msg_data);
644 		}
645 	}
646 }
647 
iris_hfi_gen1_response_handler(struct iris_core * core)648 static void iris_hfi_gen1_response_handler(struct iris_core *core)
649 {
650 	memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr));
651 	while (!iris_hfi_queue_msg_read(core, core->response_packet)) {
652 		iris_hfi_gen1_handle_response(core, core->response_packet);
653 		memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr));
654 	}
655 
656 	iris_hfi_gen1_flush_debug_queue(core, core->response_packet);
657 }
658 
659 static const struct iris_hfi_response_ops iris_hfi_gen1_response_ops = {
660 	.hfi_response_handler = iris_hfi_gen1_response_handler,
661 };
662 
iris_hfi_gen1_response_ops_init(struct iris_core * core)663 void iris_hfi_gen1_response_ops_init(struct iris_core *core)
664 {
665 	core->hfi_response_ops = &iris_hfi_gen1_response_ops;
666 }
667