File Index
Files and directories
Sign in
FILE

iris_hfi_gen1_response.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c C
  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
 15static 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
175static 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 && !(inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)) {
204
205		flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);
206		flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
207		flush_pkt.shdr.session_id = inst->session_id;
208		flush_pkt.flush_type = HFI_FLUSH_OUTPUT;
209		if (!iris_hfi_queue_cmd_write(inst->core, &flush_pkt, flush_pkt.shdr.hdr.size))
210			inst->flush_responses_pending++;
211	}
212
213	iris_vdec_src_change(inst);
214	iris_inst_sub_state_change_drc_last(inst);
215}
216
217static void
218iris_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
238static void
239iris_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
266static 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
282static 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
294static void
295iris_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
324static 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
343static 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	/* EOS buffer sent via drain won't be in v4l2 buffer list */
352	if (pkt->packet_buffer == 0xdeadb000)
353		return;
354
355	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) {
356		buf = to_iris_buffer(&m2m_buffer->vb);
357		if (buf->index == pkt->input_tag) {
358			found = true;
359			break;
360		}
361	}
362	if (!found)
363		goto error;
364
365	if (pkt->shdr.error_type == HFI_ERR_SESSION_UNSUPPORTED_STREAM) {
366		buf->flags = V4L2_BUF_FLAG_ERROR;
367		iris_vb2_queue_error(inst);
368		iris_inst_change_state(inst, IRIS_INST_ERROR);
369	}
370
371	if (!(buf->attr & BUF_ATTR_QUEUED))
372		return;
373
374	buf->attr &= ~BUF_ATTR_QUEUED;
375
376	if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
377		buf->attr |= BUF_ATTR_BUFFER_DONE;
378		iris_vb2_buffer_done(inst, buf);
379	}
380
381	return;
382
383error:
384	iris_inst_change_state(inst, IRIS_INST_ERROR);
385	dev_err(inst->core->dev, "error in etb done\n");
386}
387
388static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet)
389{
390	struct hfi_msg_session_fbd_uncompressed_plane0_pkt *uncom_pkt = packet;
391	struct hfi_msg_session_fbd_compressed_pkt *com_pkt = packet;
392	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
393	struct v4l2_m2m_buffer *m2m_buffer, *n;
394	struct hfi_session_flush_pkt flush_pkt;
395	u32 timestamp_hi;
396	u32 timestamp_lo;
397	struct iris_core *core = inst->core;
398	u32 filled_len;
399	u32 pic_type;
400	u32 output_tag;
401	struct iris_buffer *buf, *iter;
402	struct iris_buffers *buffers;
403	u32 hfi_flags;
404	u32 offset;
405	u64 timestamp_us = 0;
406	bool found = false;
407	u32 flags = 0;
408
409	if (inst->domain == DECODER) {
410		timestamp_hi = uncom_pkt->time_stamp_hi;
411		timestamp_lo = uncom_pkt->time_stamp_lo;
412		filled_len = uncom_pkt->filled_len;
413		pic_type = uncom_pkt->picture_type;
414		output_tag = uncom_pkt->output_tag;
415		hfi_flags = uncom_pkt->flags;
416		offset = uncom_pkt->offset;
417	} else {
418		timestamp_hi = com_pkt->time_stamp_hi;
419		timestamp_lo = com_pkt->time_stamp_lo;
420		filled_len = com_pkt->filled_len;
421		pic_type = com_pkt->picture_type;
422		output_tag = com_pkt->output_tag;
423		hfi_flags = com_pkt->flags;
424		offset = com_pkt->offset;
425	}
426
427	if ((hfi_flags & HFI_BUFFERFLAG_EOS) && !filled_len) {
428		reinit_completion(&inst->flush_completion);
429
430		flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);
431		flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
432		flush_pkt.shdr.session_id = inst->session_id;
433		flush_pkt.flush_type = HFI_FLUSH_OUTPUT;
434		if (!iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size))
435			inst->flush_responses_pending++;
436
437		iris_inst_sub_state_change_drain_last(inst);
438	}
439
440	if (iris_split_mode_enabled(inst) && inst->domain == DECODER &&
441	    uncom_pkt->stream_id == 0) {
442		buffers = &inst->buffers[BUF_DPB];
443		if (!buffers)
444			goto error;
445
446		found = false;
447		list_for_each_entry(iter, &buffers->list, list) {
448			if (!(iter->attr & BUF_ATTR_QUEUED))
449				continue;
450
451			found = (iter->index == output_tag &&
452				iter->data_offset == offset);
453
454			if (found) {
455				buf = iter;
456				break;
457			}
458		}
459	} else {
460		v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, m2m_buffer, n) {
461			buf = to_iris_buffer(&m2m_buffer->vb);
462			if (!(buf->attr & BUF_ATTR_QUEUED))
463				continue;
464
465			found = (buf->index == output_tag &&
466				 buf->data_offset == offset);
467
468			if (found)
469				break;
470		}
471	}
472	if (!found)
473		goto error;
474
475	buf->data_offset = offset;
476	buf->data_size = filled_len;
477
478	if (filled_len) {
479		timestamp_us = timestamp_hi;
480		timestamp_us = (timestamp_us << 32) | timestamp_lo;
481	} else {
482		if (inst->domain == DECODER && uncom_pkt->stream_id == 1 &&
483		    !inst->last_buffer_dequeued) {
484			if (iris_drc_pending(inst) || iris_drain_pending(inst)) {
485				flags |= V4L2_BUF_FLAG_LAST;
486				inst->last_buffer_dequeued = true;
487			}
488		} else if (inst->domain == ENCODER) {
489			if (!inst->last_buffer_dequeued && iris_drain_pending(inst)) {
490				flags |= V4L2_BUF_FLAG_LAST;
491				inst->last_buffer_dequeued = true;
492			}
493		}
494	}
495	buf->timestamp = timestamp_us;
496
497	switch (pic_type) {
498	case HFI_GEN1_PICTURE_IDR:
499	case HFI_GEN1_PICTURE_I:
500		flags |= V4L2_BUF_FLAG_KEYFRAME;
501		break;
502	case HFI_GEN1_PICTURE_P:
503		flags |= V4L2_BUF_FLAG_PFRAME;
504		break;
505	case HFI_GEN1_PICTURE_B:
506		flags |= V4L2_BUF_FLAG_BFRAME;
507		break;
508	case HFI_FRAME_NOTCODED:
509	case HFI_UNUSED_PICT:
510	case HFI_FRAME_YUV:
511	default:
512		break;
513	}
514
515	buf->attr &= ~BUF_ATTR_QUEUED;
516	buf->attr |= BUF_ATTR_DEQUEUED;
517	buf->attr |= BUF_ATTR_BUFFER_DONE;
518
519	if (hfi_flags & HFI_BUFFERFLAG_DATACORRUPT)
520		flags |= V4L2_BUF_FLAG_ERROR;
521
522	if (hfi_flags & HFI_BUFFERFLAG_DROP_FRAME)
523		flags |= V4L2_BUF_FLAG_ERROR;
524
525	buf->flags |= flags;
526
527	iris_vb2_buffer_done(inst, buf);
528
529	return;
530
531error:
532	iris_inst_change_state(inst, IRIS_INST_ERROR);
533	dev_err(core->dev, "error in ftb done\n");
534}
535
536struct iris_hfi_gen1_response_pkt_info {
537	u32 pkt;
538	u32 pkt_sz;
539};
540
541static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = {
542	{
543	 .pkt = HFI_MSG_EVENT_NOTIFY,
544	 .pkt_sz = sizeof(struct hfi_msg_event_notify_pkt),
545	},
546	{
547	 .pkt = HFI_MSG_SYS_INIT,
548	 .pkt_sz = sizeof(struct hfi_msg_sys_init_done_pkt),
549	},
550	{
551	 .pkt = HFI_MSG_SYS_PROPERTY_INFO,
552	 .pkt_sz = sizeof(struct hfi_msg_sys_property_info_pkt),
553	},
554	{
555	 .pkt = HFI_MSG_SYS_SESSION_INIT,
556	 .pkt_sz = sizeof(struct hfi_msg_session_init_done_pkt),
557	},
558	{
559	 .pkt = HFI_MSG_SYS_SESSION_END,
560	 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
561	},
562	{
563	 .pkt = HFI_MSG_SESSION_LOAD_RESOURCES,
564	 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
565	},
566	{
567	 .pkt = HFI_MSG_SESSION_START,
568	 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
569	},
570	{
571	 .pkt = HFI_MSG_SESSION_STOP,
572	 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
573	},
574	{
575	 .pkt = HFI_MSG_SESSION_EMPTY_BUFFER,
576	 .pkt_sz = sizeof(struct hfi_msg_session_empty_buffer_done_pkt),
577	},
578	{
579	 .pkt = HFI_MSG_SESSION_FILL_BUFFER,
580	 .pkt_sz = sizeof(struct hfi_msg_session_fbd_compressed_pkt),
581	},
582	{
583	 .pkt = HFI_MSG_SESSION_FLUSH,
584	 .pkt_sz = sizeof(struct hfi_msg_session_flush_done_pkt),
585	},
586	{
587	 .pkt = HFI_MSG_SESSION_RELEASE_RESOURCES,
588	 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
589	},
590	{
591	 .pkt = HFI_MSG_SESSION_RELEASE_BUFFERS,
592	 .pkt_sz = sizeof(struct hfi_msg_session_release_buffers_done_pkt),
593	},
594};
595
596static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response)
597{
598	struct hfi_pkt_hdr *hdr = (struct hfi_pkt_hdr *)response;
599	const struct iris_hfi_gen1_response_pkt_info *pkt_info;
600	struct device *dev = core->dev;
601	struct hfi_session_pkt *pkt;
602	struct iris_inst *inst;
603	bool found = false;
604	u32 i;
605
606	for (i = 0; i < ARRAY_SIZE(pkt_infos); i++) {
607		pkt_info = &pkt_infos[i];
608		if (pkt_info->pkt != hdr->pkt_type)
609			continue;
610		found = true;
611		break;
612	}
613
614	if (!found || hdr->size < pkt_info->pkt_sz) {
615		dev_err(dev, "bad packet size (%d should be %d, pkt type:%x, found %d)\n",
616			hdr->size, pkt_info->pkt_sz, hdr->pkt_type, found);
617
618		return;
619	}
620
621	switch (hdr->pkt_type) {
622	case HFI_MSG_SYS_INIT:
623		iris_hfi_gen1_sys_init_done(core, hdr);
624		break;
625	case HFI_MSG_SYS_PROPERTY_INFO:
626		iris_hfi_gen1_sys_property_info(core, hdr);
627		break;
628	case HFI_MSG_EVENT_NOTIFY:
629		pkt = (struct hfi_session_pkt *)hdr;
630		inst = iris_get_instance(core, pkt->shdr.session_id);
631		if (inst) {
632			mutex_lock(&inst->lock);
633			iris_hfi_gen1_session_event_notify(inst, hdr);
634			mutex_unlock(&inst->lock);
635		} else {
636			iris_hfi_gen1_sys_event_notify(core, hdr);
637		}
638
639		break;
640	default:
641		pkt = (struct hfi_session_pkt *)hdr;
642		inst = iris_get_instance(core, pkt->shdr.session_id);
643		if (!inst) {
644			dev_warn(dev, "no valid instance(pkt session_id:%x, pkt:%x)\n",
645				 pkt->shdr.session_id,
646				 pkt_info ? pkt_info->pkt : 0);
647			return;
648		}
649
650		mutex_lock(&inst->lock);
651		if (hdr->pkt_type == HFI_MSG_SESSION_EMPTY_BUFFER) {
652			iris_hfi_gen1_session_etb_done(inst, hdr);
653		} else if (hdr->pkt_type == HFI_MSG_SESSION_FILL_BUFFER) {
654			iris_hfi_gen1_session_ftb_done(inst, hdr);
655		} else {
656			struct hfi_msg_session_hdr_pkt *shdr;
657
658			shdr = (struct hfi_msg_session_hdr_pkt *)hdr;
659			if (shdr->error_type != HFI_ERR_NONE)
660				iris_inst_change_state(inst, IRIS_INST_ERROR);
661
662			if (pkt_info->pkt == HFI_MSG_SESSION_FLUSH) {
663				if (!(--inst->flush_responses_pending))
664					complete(&inst->flush_completion);
665			} else {
666				complete(&inst->completion);
667			}
668		}
669		mutex_unlock(&inst->lock);
670
671		break;
672	}
673}
674
675static void iris_hfi_gen1_flush_debug_queue(struct iris_core *core, u8 *packet)
676{
677	struct hfi_msg_sys_coverage_pkt *pkt;
678
679	while (!iris_hfi_queue_dbg_read(core, packet)) {
680		pkt = (struct hfi_msg_sys_coverage_pkt *)packet;
681
682		if (pkt->hdr.pkt_type != HFI_MSG_SYS_COV) {
683			struct hfi_msg_sys_debug_pkt *pkt =
684				(struct hfi_msg_sys_debug_pkt *)packet;
685
686			dev_dbg(core->dev, "%s", pkt->msg_data);
687		}
688	}
689}
690
691static void iris_hfi_gen1_response_handler(struct iris_core *core)
692{
693	memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr));
694	while (!iris_hfi_queue_msg_read(core, core->response_packet)) {
695		iris_hfi_gen1_handle_response(core, core->response_packet);
696		memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr));
697	}
698
699	iris_hfi_gen1_flush_debug_queue(core, core->response_packet);
700}
701
702static const struct iris_hfi_response_ops iris_hfi_gen1_response_ops = {
703	.hfi_response_handler = iris_hfi_gen1_response_handler,
704};
705
706void iris_hfi_gen1_response_ops_init(struct iris_core *core)
707{
708	core->hfi_response_ops = &iris_hfi_gen1_response_ops;
709}
~/ Read-only file preview.