1 /*
2  * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
3  * Copyright (C) 2017 Linaro Ltd.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 and
7  * only version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15 #include <linux/errno.h>
16 #include <linux/hash.h>
17 
18 #include "hfi_cmds.h"
19 
20 static enum hfi_version hfi_ver;
21 
22 void pkt_sys_init(struct hfi_sys_init_pkt *pkt, u32 arch_type)
23 {
24 	pkt->hdr.size = sizeof(*pkt);
25 	pkt->hdr.pkt_type = HFI_CMD_SYS_INIT;
26 	pkt->arch_type = arch_type;
27 }
28 
29 void pkt_sys_pc_prep(struct hfi_sys_pc_prep_pkt *pkt)
30 {
31 	pkt->hdr.size = sizeof(*pkt);
32 	pkt->hdr.pkt_type = HFI_CMD_SYS_PC_PREP;
33 }
34 
35 void pkt_sys_idle_indicator(struct hfi_sys_set_property_pkt *pkt, u32 enable)
36 {
37 	struct hfi_enable *hfi = (struct hfi_enable *)&pkt->data[1];
38 
39 	pkt->hdr.size = sizeof(*pkt) + sizeof(*hfi) + sizeof(u32);
40 	pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY;
41 	pkt->num_properties = 1;
42 	pkt->data[0] = HFI_PROPERTY_SYS_IDLE_INDICATOR;
43 	hfi->enable = enable;
44 }
45 
46 void pkt_sys_debug_config(struct hfi_sys_set_property_pkt *pkt, u32 mode,
47 			  u32 config)
48 {
49 	struct hfi_debug_config *hfi;
50 
51 	pkt->hdr.size = sizeof(*pkt) + sizeof(*hfi) + sizeof(u32);
52 	pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY;
53 	pkt->num_properties = 1;
54 	pkt->data[0] = HFI_PROPERTY_SYS_DEBUG_CONFIG;
55 	hfi = (struct hfi_debug_config *)&pkt->data[1];
56 	hfi->config = config;
57 	hfi->mode = mode;
58 }
59 
60 void pkt_sys_coverage_config(struct hfi_sys_set_property_pkt *pkt, u32 mode)
61 {
62 	pkt->hdr.size = sizeof(*pkt) + sizeof(u32);
63 	pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY;
64 	pkt->num_properties = 1;
65 	pkt->data[0] = HFI_PROPERTY_SYS_CONFIG_COVERAGE;
66 	pkt->data[1] = mode;
67 }
68 
69 int pkt_sys_set_resource(struct hfi_sys_set_resource_pkt *pkt, u32 id, u32 size,
70 			 u32 addr, void *cookie)
71 {
72 	pkt->hdr.size = sizeof(*pkt);
73 	pkt->hdr.pkt_type = HFI_CMD_SYS_SET_RESOURCE;
74 	pkt->resource_handle = hash32_ptr(cookie);
75 
76 	switch (id) {
77 	case VIDC_RESOURCE_OCMEM:
78 	case VIDC_RESOURCE_VMEM: {
79 		struct hfi_resource_ocmem *res =
80 			(struct hfi_resource_ocmem *)&pkt->resource_data[0];
81 
82 		res->size = size;
83 		res->mem = addr;
84 		pkt->resource_type = HFI_RESOURCE_OCMEM;
85 		pkt->hdr.size += sizeof(*res) - sizeof(u32);
86 		break;
87 	}
88 	case VIDC_RESOURCE_NONE:
89 	default:
90 		return -ENOTSUPP;
91 	}
92 
93 	return 0;
94 }
95 
96 int pkt_sys_unset_resource(struct hfi_sys_release_resource_pkt *pkt, u32 id,
97 			   u32 size, void *cookie)
98 {
99 	pkt->hdr.size = sizeof(*pkt);
100 	pkt->hdr.pkt_type = HFI_CMD_SYS_RELEASE_RESOURCE;
101 	pkt->resource_handle = hash32_ptr(cookie);
102 
103 	switch (id) {
104 	case VIDC_RESOURCE_OCMEM:
105 	case VIDC_RESOURCE_VMEM:
106 		pkt->resource_type = HFI_RESOURCE_OCMEM;
107 		break;
108 	case VIDC_RESOURCE_NONE:
109 		break;
110 	default:
111 		return -ENOTSUPP;
112 	}
113 
114 	return 0;
115 }
116 
117 void pkt_sys_ping(struct hfi_sys_ping_pkt *pkt, u32 cookie)
118 {
119 	pkt->hdr.size = sizeof(*pkt);
120 	pkt->hdr.pkt_type = HFI_CMD_SYS_PING;
121 	pkt->client_data = cookie;
122 }
123 
124 void pkt_sys_power_control(struct hfi_sys_set_property_pkt *pkt, u32 enable)
125 {
126 	struct hfi_enable *hfi = (struct hfi_enable *)&pkt->data[1];
127 
128 	pkt->hdr.size = sizeof(*pkt) + sizeof(*hfi) + sizeof(u32);
129 	pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY;
130 	pkt->num_properties = 1;
131 	pkt->data[0] = HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL;
132 	hfi->enable = enable;
133 }
134 
135 int pkt_sys_ssr_cmd(struct hfi_sys_test_ssr_pkt *pkt, u32 trigger_type)
136 {
137 	switch (trigger_type) {
138 	case HFI_TEST_SSR_SW_ERR_FATAL:
139 	case HFI_TEST_SSR_SW_DIV_BY_ZERO:
140 	case HFI_TEST_SSR_HW_WDOG_IRQ:
141 		break;
142 	default:
143 		return -EINVAL;
144 	}
145 
146 	pkt->hdr.size = sizeof(*pkt);
147 	pkt->hdr.pkt_type = HFI_CMD_SYS_TEST_SSR;
148 	pkt->trigger_type = trigger_type;
149 
150 	return 0;
151 }
152 
153 void pkt_sys_image_version(struct hfi_sys_get_property_pkt *pkt)
154 {
155 	pkt->hdr.size = sizeof(*pkt);
156 	pkt->hdr.pkt_type = HFI_CMD_SYS_GET_PROPERTY;
157 	pkt->num_properties = 1;
158 	pkt->data[0] = HFI_PROPERTY_SYS_IMAGE_VERSION;
159 }
160 
161 int pkt_session_init(struct hfi_session_init_pkt *pkt, void *cookie,
162 		     u32 session_type, u32 codec)
163 {
164 	if (!pkt || !cookie || !codec)
165 		return -EINVAL;
166 
167 	pkt->shdr.hdr.size = sizeof(*pkt);
168 	pkt->shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT;
169 	pkt->shdr.session_id = hash32_ptr(cookie);
170 	pkt->session_domain = session_type;
171 	pkt->session_codec = codec;
172 
173 	return 0;
174 }
175 
176 void pkt_session_cmd(struct hfi_session_pkt *pkt, u32 pkt_type, void *cookie)
177 {
178 	pkt->shdr.hdr.size = sizeof(*pkt);
179 	pkt->shdr.hdr.pkt_type = pkt_type;
180 	pkt->shdr.session_id = hash32_ptr(cookie);
181 }
182 
183 int pkt_session_set_buffers(struct hfi_session_set_buffers_pkt *pkt,
184 			    void *cookie, struct hfi_buffer_desc *bd)
185 {
186 	unsigned int i;
187 
188 	if (!cookie || !pkt || !bd)
189 		return -EINVAL;
190 
191 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_BUFFERS;
192 	pkt->shdr.session_id = hash32_ptr(cookie);
193 	pkt->buffer_size = bd->buffer_size;
194 	pkt->min_buffer_size = bd->buffer_size;
195 	pkt->num_buffers = bd->num_buffers;
196 
197 	if (bd->buffer_type == HFI_BUFFER_OUTPUT ||
198 	    bd->buffer_type == HFI_BUFFER_OUTPUT2) {
199 		struct hfi_buffer_info *bi;
200 
201 		pkt->extradata_size = bd->extradata_size;
202 		pkt->shdr.hdr.size = sizeof(*pkt) - sizeof(u32) +
203 			(bd->num_buffers * sizeof(*bi));
204 		bi = (struct hfi_buffer_info *)pkt->buffer_info;
205 		for (i = 0; i < pkt->num_buffers; i++) {
206 			bi->buffer_addr = bd->device_addr;
207 			bi->extradata_addr = bd->extradata_addr;
208 		}
209 	} else {
210 		pkt->extradata_size = 0;
211 		pkt->shdr.hdr.size = sizeof(*pkt) +
212 			((bd->num_buffers - 1) * sizeof(u32));
213 		for (i = 0; i < pkt->num_buffers; i++)
214 			pkt->buffer_info[i] = bd->device_addr;
215 	}
216 
217 	pkt->buffer_type = bd->buffer_type;
218 
219 	return 0;
220 }
221 
222 int pkt_session_unset_buffers(struct hfi_session_release_buffer_pkt *pkt,
223 			      void *cookie, struct hfi_buffer_desc *bd)
224 {
225 	unsigned int i;
226 
227 	if (!cookie || !pkt || !bd)
228 		return -EINVAL;
229 
230 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_RELEASE_BUFFERS;
231 	pkt->shdr.session_id = hash32_ptr(cookie);
232 	pkt->buffer_size = bd->buffer_size;
233 	pkt->num_buffers = bd->num_buffers;
234 
235 	if (bd->buffer_type == HFI_BUFFER_OUTPUT ||
236 	    bd->buffer_type == HFI_BUFFER_OUTPUT2) {
237 		struct hfi_buffer_info *bi;
238 
239 		bi = (struct hfi_buffer_info *)pkt->buffer_info;
240 		for (i = 0; i < pkt->num_buffers; i++) {
241 			bi->buffer_addr = bd->device_addr;
242 			bi->extradata_addr = bd->extradata_addr;
243 		}
244 		pkt->shdr.hdr.size =
245 				sizeof(struct hfi_session_set_buffers_pkt) -
246 				sizeof(u32) + (bd->num_buffers * sizeof(*bi));
247 	} else {
248 		for (i = 0; i < pkt->num_buffers; i++)
249 			pkt->buffer_info[i] = bd->device_addr;
250 
251 		pkt->extradata_size = 0;
252 		pkt->shdr.hdr.size =
253 				sizeof(struct hfi_session_set_buffers_pkt) +
254 				((bd->num_buffers - 1) * sizeof(u32));
255 	}
256 
257 	pkt->response_req = bd->response_required;
258 	pkt->buffer_type = bd->buffer_type;
259 
260 	return 0;
261 }
262 
263 int pkt_session_etb_decoder(struct hfi_session_empty_buffer_compressed_pkt *pkt,
264 			    void *cookie, struct hfi_frame_data *in_frame)
265 {
266 	if (!cookie || !in_frame->device_addr)
267 		return -EINVAL;
268 
269 	pkt->shdr.hdr.size = sizeof(*pkt);
270 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
271 	pkt->shdr.session_id = hash32_ptr(cookie);
272 	pkt->time_stamp_hi = upper_32_bits(in_frame->timestamp);
273 	pkt->time_stamp_lo = lower_32_bits(in_frame->timestamp);
274 	pkt->flags = in_frame->flags;
275 	pkt->mark_target = in_frame->mark_target;
276 	pkt->mark_data = in_frame->mark_data;
277 	pkt->offset = in_frame->offset;
278 	pkt->alloc_len = in_frame->alloc_len;
279 	pkt->filled_len = in_frame->filled_len;
280 	pkt->input_tag = in_frame->clnt_data;
281 	pkt->packet_buffer = in_frame->device_addr;
282 
283 	return 0;
284 }
285 
286 int pkt_session_etb_encoder(
287 		struct hfi_session_empty_buffer_uncompressed_plane0_pkt *pkt,
288 		void *cookie, struct hfi_frame_data *in_frame)
289 {
290 	if (!cookie || !in_frame->device_addr)
291 		return -EINVAL;
292 
293 	pkt->shdr.hdr.size = sizeof(*pkt);
294 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
295 	pkt->shdr.session_id = hash32_ptr(cookie);
296 	pkt->view_id = 0;
297 	pkt->time_stamp_hi = upper_32_bits(in_frame->timestamp);
298 	pkt->time_stamp_lo = lower_32_bits(in_frame->timestamp);
299 	pkt->flags = in_frame->flags;
300 	pkt->mark_target = in_frame->mark_target;
301 	pkt->mark_data = in_frame->mark_data;
302 	pkt->offset = in_frame->offset;
303 	pkt->alloc_len = in_frame->alloc_len;
304 	pkt->filled_len = in_frame->filled_len;
305 	pkt->input_tag = in_frame->clnt_data;
306 	pkt->packet_buffer = in_frame->device_addr;
307 	pkt->extradata_buffer = in_frame->extradata_addr;
308 
309 	return 0;
310 }
311 
312 int pkt_session_ftb(struct hfi_session_fill_buffer_pkt *pkt, void *cookie,
313 		    struct hfi_frame_data *out_frame)
314 {
315 	if (!cookie || !out_frame || !out_frame->device_addr)
316 		return -EINVAL;
317 
318 	pkt->shdr.hdr.size = sizeof(*pkt);
319 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_FILL_BUFFER;
320 	pkt->shdr.session_id = hash32_ptr(cookie);
321 
322 	if (out_frame->buffer_type == HFI_BUFFER_OUTPUT)
323 		pkt->stream_id = 0;
324 	else if (out_frame->buffer_type == HFI_BUFFER_OUTPUT2)
325 		pkt->stream_id = 1;
326 
327 	pkt->output_tag = out_frame->clnt_data;
328 	pkt->packet_buffer = out_frame->device_addr;
329 	pkt->extradata_buffer = out_frame->extradata_addr;
330 	pkt->alloc_len = out_frame->alloc_len;
331 	pkt->filled_len = out_frame->filled_len;
332 	pkt->offset = out_frame->offset;
333 	pkt->data[0] = out_frame->extradata_size;
334 
335 	return 0;
336 }
337 
338 int pkt_session_parse_seq_header(
339 		struct hfi_session_parse_sequence_header_pkt *pkt,
340 		void *cookie, u32 seq_hdr, u32 seq_hdr_len)
341 {
342 	if (!cookie || !seq_hdr || !seq_hdr_len)
343 		return -EINVAL;
344 
345 	pkt->shdr.hdr.size = sizeof(*pkt);
346 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_PARSE_SEQUENCE_HEADER;
347 	pkt->shdr.session_id = hash32_ptr(cookie);
348 	pkt->header_len = seq_hdr_len;
349 	pkt->packet_buffer = seq_hdr;
350 
351 	return 0;
352 }
353 
354 int pkt_session_get_seq_hdr(struct hfi_session_get_sequence_header_pkt *pkt,
355 			    void *cookie, u32 seq_hdr, u32 seq_hdr_len)
356 {
357 	if (!cookie || !seq_hdr || !seq_hdr_len)
358 		return -EINVAL;
359 
360 	pkt->shdr.hdr.size = sizeof(*pkt);
361 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_GET_SEQUENCE_HEADER;
362 	pkt->shdr.session_id = hash32_ptr(cookie);
363 	pkt->buffer_len = seq_hdr_len;
364 	pkt->packet_buffer = seq_hdr;
365 
366 	return 0;
367 }
368 
369 int pkt_session_flush(struct hfi_session_flush_pkt *pkt, void *cookie, u32 type)
370 {
371 	switch (type) {
372 	case HFI_FLUSH_INPUT:
373 	case HFI_FLUSH_OUTPUT:
374 	case HFI_FLUSH_OUTPUT2:
375 	case HFI_FLUSH_ALL:
376 		break;
377 	default:
378 		return -EINVAL;
379 	}
380 
381 	pkt->shdr.hdr.size = sizeof(*pkt);
382 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
383 	pkt->shdr.session_id = hash32_ptr(cookie);
384 	pkt->flush_type = type;
385 
386 	return 0;
387 }
388 
389 static int pkt_session_get_property_1x(struct hfi_session_get_property_pkt *pkt,
390 				       void *cookie, u32 ptype)
391 {
392 	switch (ptype) {
393 	case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
394 	case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
395 		break;
396 	default:
397 		return -EINVAL;
398 	}
399 
400 	pkt->shdr.hdr.size = sizeof(*pkt);
401 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_GET_PROPERTY;
402 	pkt->shdr.session_id = hash32_ptr(cookie);
403 	pkt->num_properties = 1;
404 	pkt->data[0] = ptype;
405 
406 	return 0;
407 }
408 
409 static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
410 				       void *cookie, u32 ptype, void *pdata)
411 {
412 	void *prop_data;
413 	int ret = 0;
414 
415 	if (!pkt || !cookie || !pdata)
416 		return -EINVAL;
417 
418 	prop_data = &pkt->data[1];
419 
420 	pkt->shdr.hdr.size = sizeof(*pkt);
421 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
422 	pkt->shdr.session_id = hash32_ptr(cookie);
423 	pkt->num_properties = 1;
424 	pkt->data[0] = ptype;
425 
426 	switch (ptype) {
427 	case HFI_PROPERTY_CONFIG_FRAME_RATE: {
428 		struct hfi_framerate *in = pdata, *frate = prop_data;
429 
430 		frate->buffer_type = in->buffer_type;
431 		frate->framerate = in->framerate;
432 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*frate);
433 		break;
434 	}
435 	case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT: {
436 		struct hfi_uncompressed_format_select *in = pdata;
437 		struct hfi_uncompressed_format_select *hfi = prop_data;
438 
439 		hfi->buffer_type = in->buffer_type;
440 		hfi->format = in->format;
441 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hfi);
442 		break;
443 	}
444 	case HFI_PROPERTY_PARAM_FRAME_SIZE: {
445 		struct hfi_framesize *in = pdata, *fsize = prop_data;
446 
447 		fsize->buffer_type = in->buffer_type;
448 		fsize->height = in->height;
449 		fsize->width = in->width;
450 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*fsize);
451 		break;
452 	}
453 	case HFI_PROPERTY_CONFIG_REALTIME: {
454 		struct hfi_enable *in = pdata, *en = prop_data;
455 
456 		en->enable = in->enable;
457 		pkt->shdr.hdr.size += sizeof(u32) * 2;
458 		break;
459 	}
460 	case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: {
461 		struct hfi_buffer_count_actual *in = pdata, *count = prop_data;
462 
463 		count->count_actual = in->count_actual;
464 		count->type = in->type;
465 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
466 		break;
467 	}
468 	case HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL: {
469 		struct hfi_buffer_size_actual *in = pdata, *sz = prop_data;
470 
471 		sz->size = in->size;
472 		sz->type = in->type;
473 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*sz);
474 		break;
475 	}
476 	case HFI_PROPERTY_PARAM_BUFFER_DISPLAY_HOLD_COUNT_ACTUAL: {
477 		struct hfi_buffer_display_hold_count_actual *in = pdata;
478 		struct hfi_buffer_display_hold_count_actual *count = prop_data;
479 
480 		count->hold_count = in->hold_count;
481 		count->type = in->type;
482 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
483 		break;
484 	}
485 	case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT: {
486 		struct hfi_nal_stream_format_select *in = pdata;
487 		struct hfi_nal_stream_format_select *fmt = prop_data;
488 
489 		fmt->format = in->format;
490 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*fmt);
491 		break;
492 	}
493 	case HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER: {
494 		u32 *in = pdata;
495 
496 		switch (*in) {
497 		case HFI_OUTPUT_ORDER_DECODE:
498 		case HFI_OUTPUT_ORDER_DISPLAY:
499 			break;
500 		default:
501 			ret = -EINVAL;
502 			break;
503 		}
504 
505 		pkt->data[1] = *in;
506 		pkt->shdr.hdr.size += sizeof(u32) * 2;
507 		break;
508 	}
509 	case HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE: {
510 		struct hfi_enable_picture *in = pdata, *en = prop_data;
511 
512 		en->picture_type = in->picture_type;
513 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
514 		break;
515 	}
516 	case HFI_PROPERTY_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO: {
517 		struct hfi_enable *in = pdata, *en = prop_data;
518 
519 		en->enable = in->enable;
520 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
521 		break;
522 	}
523 	case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: {
524 		struct hfi_enable *in = pdata;
525 		struct hfi_enable *en = prop_data;
526 
527 		en->enable = in->enable;
528 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
529 		break;
530 	}
531 	case HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM: {
532 		struct hfi_multi_stream *in = pdata, *multi = prop_data;
533 
534 		multi->buffer_type = in->buffer_type;
535 		multi->enable = in->enable;
536 		multi->width = in->width;
537 		multi->height = in->height;
538 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*multi);
539 		break;
540 	}
541 	case HFI_PROPERTY_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT: {
542 		struct hfi_display_picture_buffer_count *in = pdata;
543 		struct hfi_display_picture_buffer_count *count = prop_data;
544 
545 		count->count = in->count;
546 		count->enable = in->enable;
547 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
548 		break;
549 	}
550 	case HFI_PROPERTY_PARAM_DIVX_FORMAT: {
551 		u32 *in = pdata;
552 
553 		switch (*in) {
554 		case HFI_DIVX_FORMAT_4:
555 		case HFI_DIVX_FORMAT_5:
556 		case HFI_DIVX_FORMAT_6:
557 			break;
558 		default:
559 			ret = -EINVAL;
560 			break;
561 		}
562 
563 		pkt->data[1] = *in;
564 		pkt->shdr.hdr.size += sizeof(u32) * 2;
565 		break;
566 	}
567 	case HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING: {
568 		struct hfi_enable *in = pdata, *en = prop_data;
569 
570 		en->enable = in->enable;
571 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
572 		break;
573 	}
574 	case HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER: {
575 		struct hfi_enable *in = pdata, *en = prop_data;
576 
577 		en->enable = in->enable;
578 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
579 		break;
580 	}
581 	case HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE: {
582 		struct hfi_enable *in = pdata, *en = prop_data;
583 
584 		en->enable = in->enable;
585 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
586 		break;
587 	}
588 	case HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER: {
589 		struct hfi_enable *in = pdata, *en = prop_data;
590 
591 		en->enable = in->enable;
592 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
593 		break;
594 	}
595 	case HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME:
596 		pkt->shdr.hdr.size += sizeof(u32);
597 		break;
598 	case HFI_PROPERTY_PARAM_VENC_MPEG4_SHORT_HEADER:
599 		break;
600 	case HFI_PROPERTY_PARAM_VENC_MPEG4_AC_PREDICTION:
601 		break;
602 	case HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE: {
603 		struct hfi_bitrate *in = pdata, *brate = prop_data;
604 
605 		brate->bitrate = in->bitrate;
606 		brate->layer_id = in->layer_id;
607 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*brate);
608 		break;
609 	}
610 	case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE: {
611 		struct hfi_bitrate *in = pdata, *hfi = prop_data;
612 
613 		hfi->bitrate = in->bitrate;
614 		hfi->layer_id = in->layer_id;
615 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hfi);
616 		break;
617 	}
618 	case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: {
619 		struct hfi_profile_level *in = pdata, *pl = prop_data;
620 
621 		pl->level = in->level;
622 		pl->profile = in->profile;
623 		if (pl->profile <= 0)
624 			/* Profile not supported, falling back to high */
625 			pl->profile = HFI_H264_PROFILE_HIGH;
626 
627 		if (!pl->level)
628 			/* Level not supported, falling back to 1 */
629 			pl->level = 1;
630 
631 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*pl);
632 		break;
633 	}
634 	case HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL: {
635 		struct hfi_h264_entropy_control *in = pdata, *hfi = prop_data;
636 
637 		hfi->entropy_mode = in->entropy_mode;
638 		if (hfi->entropy_mode == HFI_H264_ENTROPY_CABAC)
639 			hfi->cabac_model = in->cabac_model;
640 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hfi);
641 		break;
642 	}
643 	case HFI_PROPERTY_PARAM_VENC_RATE_CONTROL: {
644 		u32 *in = pdata;
645 
646 		switch (*in) {
647 		case HFI_RATE_CONTROL_OFF:
648 		case HFI_RATE_CONTROL_CBR_CFR:
649 		case HFI_RATE_CONTROL_CBR_VFR:
650 		case HFI_RATE_CONTROL_VBR_CFR:
651 		case HFI_RATE_CONTROL_VBR_VFR:
652 			break;
653 		default:
654 			ret = -EINVAL;
655 			break;
656 		}
657 
658 		pkt->data[1] = *in;
659 		pkt->shdr.hdr.size += sizeof(u32) * 2;
660 		break;
661 	}
662 	case HFI_PROPERTY_PARAM_VENC_MPEG4_TIME_RESOLUTION: {
663 		struct hfi_mpeg4_time_resolution *in = pdata, *res = prop_data;
664 
665 		res->time_increment_resolution = in->time_increment_resolution;
666 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*res);
667 		break;
668 	}
669 	case HFI_PROPERTY_PARAM_VENC_MPEG4_HEADER_EXTENSION: {
670 		struct hfi_mpeg4_header_extension *in = pdata, *ext = prop_data;
671 
672 		ext->header_extension = in->header_extension;
673 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*ext);
674 		break;
675 	}
676 	case HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL: {
677 		struct hfi_h264_db_control *in = pdata, *db = prop_data;
678 
679 		switch (in->mode) {
680 		case HFI_H264_DB_MODE_DISABLE:
681 		case HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY:
682 		case HFI_H264_DB_MODE_ALL_BOUNDARY:
683 			break;
684 		default:
685 			ret = -EINVAL;
686 			break;
687 		}
688 
689 		db->mode = in->mode;
690 		db->slice_alpha_offset = in->slice_alpha_offset;
691 		db->slice_beta_offset = in->slice_beta_offset;
692 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*db);
693 		break;
694 	}
695 	case HFI_PROPERTY_PARAM_VENC_SESSION_QP: {
696 		struct hfi_quantization *in = pdata, *quant = prop_data;
697 
698 		quant->qp_i = in->qp_i;
699 		quant->qp_p = in->qp_p;
700 		quant->qp_b = in->qp_b;
701 		quant->layer_id = in->layer_id;
702 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*quant);
703 		break;
704 	}
705 	case HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE: {
706 		struct hfi_quantization_range *in = pdata, *range = prop_data;
707 		u32 min_qp, max_qp;
708 
709 		min_qp = in->min_qp;
710 		max_qp = in->max_qp;
711 
712 		/* We'll be packing in the qp, so make sure we
713 		 * won't be losing data when masking
714 		 */
715 		if (min_qp > 0xff || max_qp > 0xff) {
716 			ret = -ERANGE;
717 			break;
718 		}
719 
720 		/* When creating the packet, pack the qp value as
721 		 * 0xiippbb, where ii = qp range for I-frames,
722 		 * pp = qp range for P-frames, etc.
723 		 */
724 		range->min_qp = min_qp | min_qp << 8 | min_qp << 16;
725 		range->max_qp = max_qp | max_qp << 8 | max_qp << 16;
726 		range->layer_id = in->layer_id;
727 
728 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*range);
729 		break;
730 	}
731 	case HFI_PROPERTY_PARAM_VENC_VC1_PERF_CFG: {
732 		struct hfi_vc1e_perf_cfg_type *in = pdata, *perf = prop_data;
733 
734 		memcpy(perf->search_range_x_subsampled,
735 		       in->search_range_x_subsampled,
736 		       sizeof(perf->search_range_x_subsampled));
737 		memcpy(perf->search_range_y_subsampled,
738 		       in->search_range_y_subsampled,
739 		       sizeof(perf->search_range_y_subsampled));
740 
741 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*perf);
742 		break;
743 	}
744 	case HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES: {
745 		struct hfi_max_num_b_frames *bframes = prop_data;
746 		u32 *in = pdata;
747 
748 		bframes->max_num_b_frames = *in;
749 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*bframes);
750 		break;
751 	}
752 	case HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD: {
753 		struct hfi_intra_period *in = pdata, *intra = prop_data;
754 
755 		intra->pframes = in->pframes;
756 		intra->bframes = in->bframes;
757 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*intra);
758 		break;
759 	}
760 	case HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD: {
761 		struct hfi_idr_period *in = pdata, *idr = prop_data;
762 
763 		idr->idr_period = in->idr_period;
764 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*idr);
765 		break;
766 	}
767 	case HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR: {
768 		struct hfi_conceal_color *color = prop_data;
769 		u32 *in = pdata;
770 
771 		color->conceal_color = *in;
772 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*color);
773 		break;
774 	}
775 	case HFI_PROPERTY_CONFIG_VPE_OPERATIONS: {
776 		struct hfi_operations_type *in = pdata, *ops = prop_data;
777 
778 		switch (in->rotation) {
779 		case HFI_ROTATE_NONE:
780 		case HFI_ROTATE_90:
781 		case HFI_ROTATE_180:
782 		case HFI_ROTATE_270:
783 			break;
784 		default:
785 			ret = -EINVAL;
786 			break;
787 		}
788 
789 		switch (in->flip) {
790 		case HFI_FLIP_NONE:
791 		case HFI_FLIP_HORIZONTAL:
792 		case HFI_FLIP_VERTICAL:
793 			break;
794 		default:
795 			ret = -EINVAL;
796 			break;
797 		}
798 
799 		ops->rotation = in->rotation;
800 		ops->flip = in->flip;
801 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*ops);
802 		break;
803 	}
804 	case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH: {
805 		struct hfi_intra_refresh *in = pdata, *intra = prop_data;
806 
807 		switch (in->mode) {
808 		case HFI_INTRA_REFRESH_NONE:
809 		case HFI_INTRA_REFRESH_ADAPTIVE:
810 		case HFI_INTRA_REFRESH_CYCLIC:
811 		case HFI_INTRA_REFRESH_CYCLIC_ADAPTIVE:
812 		case HFI_INTRA_REFRESH_RANDOM:
813 			break;
814 		default:
815 			ret = -EINVAL;
816 			break;
817 		}
818 
819 		intra->mode = in->mode;
820 		intra->air_mbs = in->air_mbs;
821 		intra->air_ref = in->air_ref;
822 		intra->cir_mbs = in->cir_mbs;
823 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*intra);
824 		break;
825 	}
826 	case HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_CONTROL: {
827 		struct hfi_multi_slice_control *in = pdata, *multi = prop_data;
828 
829 		switch (in->multi_slice) {
830 		case HFI_MULTI_SLICE_OFF:
831 		case HFI_MULTI_SLICE_GOB:
832 		case HFI_MULTI_SLICE_BY_MB_COUNT:
833 		case HFI_MULTI_SLICE_BY_BYTE_COUNT:
834 			break;
835 		default:
836 			ret = -EINVAL;
837 			break;
838 		}
839 
840 		multi->multi_slice = in->multi_slice;
841 		multi->slice_size = in->slice_size;
842 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*multi);
843 		break;
844 	}
845 	case HFI_PROPERTY_PARAM_VENC_SLICE_DELIVERY_MODE: {
846 		struct hfi_enable *in = pdata, *en = prop_data;
847 
848 		en->enable = in->enable;
849 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
850 		break;
851 	}
852 	case HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO: {
853 		struct hfi_h264_vui_timing_info *in = pdata, *vui = prop_data;
854 
855 		vui->enable = in->enable;
856 		vui->fixed_framerate = in->fixed_framerate;
857 		vui->time_scale = in->time_scale;
858 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*vui);
859 		break;
860 	}
861 	case HFI_PROPERTY_CONFIG_VPE_DEINTERLACE: {
862 		struct hfi_enable *in = pdata, *en = prop_data;
863 
864 		en->enable = in->enable;
865 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
866 		break;
867 	}
868 	case HFI_PROPERTY_PARAM_VENC_H264_GENERATE_AUDNAL: {
869 		struct hfi_enable *in = pdata, *en = prop_data;
870 
871 		en->enable = in->enable;
872 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
873 		break;
874 	}
875 	case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE: {
876 		struct hfi_buffer_alloc_mode *in = pdata, *mode = prop_data;
877 
878 		mode->type = in->type;
879 		mode->mode = in->mode;
880 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*mode);
881 		break;
882 	}
883 	case HFI_PROPERTY_PARAM_VDEC_FRAME_ASSEMBLY: {
884 		struct hfi_enable *in = pdata, *en = prop_data;
885 
886 		en->enable = in->enable;
887 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
888 		break;
889 	}
890 	case HFI_PROPERTY_PARAM_VENC_H264_VUI_BITSTREAM_RESTRC: {
891 		struct hfi_enable *in = pdata, *en = prop_data;
892 
893 		en->enable = in->enable;
894 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
895 		break;
896 	}
897 	case HFI_PROPERTY_PARAM_VENC_PRESERVE_TEXT_QUALITY: {
898 		struct hfi_enable *in = pdata, *en = prop_data;
899 
900 		en->enable = in->enable;
901 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
902 		break;
903 	}
904 	case HFI_PROPERTY_PARAM_VDEC_SCS_THRESHOLD: {
905 		struct hfi_scs_threshold *thres = prop_data;
906 		u32 *in = pdata;
907 
908 		thres->threshold_value = *in;
909 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*thres);
910 		break;
911 	}
912 	case HFI_PROPERTY_PARAM_MVC_BUFFER_LAYOUT: {
913 		struct hfi_mvc_buffer_layout_descp_type *in = pdata;
914 		struct hfi_mvc_buffer_layout_descp_type *mvc = prop_data;
915 
916 		switch (in->layout_type) {
917 		case HFI_MVC_BUFFER_LAYOUT_TOP_BOTTOM:
918 		case HFI_MVC_BUFFER_LAYOUT_SEQ:
919 			break;
920 		default:
921 			ret = -EINVAL;
922 			break;
923 		}
924 
925 		mvc->layout_type = in->layout_type;
926 		mvc->bright_view_first = in->bright_view_first;
927 		mvc->ngap = in->ngap;
928 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*mvc);
929 		break;
930 	}
931 	case HFI_PROPERTY_PARAM_VENC_LTRMODE: {
932 		struct hfi_ltr_mode *in = pdata, *ltr = prop_data;
933 
934 		switch (in->ltr_mode) {
935 		case HFI_LTR_MODE_DISABLE:
936 		case HFI_LTR_MODE_MANUAL:
937 		case HFI_LTR_MODE_PERIODIC:
938 			break;
939 		default:
940 			ret = -EINVAL;
941 			break;
942 		}
943 
944 		ltr->ltr_mode = in->ltr_mode;
945 		ltr->ltr_count = in->ltr_count;
946 		ltr->trust_mode = in->trust_mode;
947 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*ltr);
948 		break;
949 	}
950 	case HFI_PROPERTY_CONFIG_VENC_USELTRFRAME: {
951 		struct hfi_ltr_use *in = pdata, *ltr_use = prop_data;
952 
953 		ltr_use->frames = in->frames;
954 		ltr_use->ref_ltr = in->ref_ltr;
955 		ltr_use->use_constrnt = in->use_constrnt;
956 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_use);
957 		break;
958 	}
959 	case HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME: {
960 		struct hfi_ltr_mark *in = pdata, *ltr_mark = prop_data;
961 
962 		ltr_mark->mark_frame = in->mark_frame;
963 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_mark);
964 		break;
965 	}
966 	case HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER: {
967 		u32 *in = pdata;
968 
969 		pkt->data[1] = *in;
970 		pkt->shdr.hdr.size += sizeof(u32) * 2;
971 		break;
972 	}
973 	case HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER: {
974 		u32 *in = pdata;
975 
976 		pkt->data[1] = *in;
977 		pkt->shdr.hdr.size += sizeof(u32) * 2;
978 		break;
979 	}
980 	case HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP: {
981 		struct hfi_enable *in = pdata, *en = prop_data;
982 
983 		en->enable = in->enable;
984 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
985 		break;
986 	}
987 	case HFI_PROPERTY_PARAM_VENC_INITIAL_QP: {
988 		struct hfi_initial_quantization *in = pdata, *quant = prop_data;
989 
990 		quant->init_qp_enable = in->init_qp_enable;
991 		quant->qp_i = in->qp_i;
992 		quant->qp_p = in->qp_p;
993 		quant->qp_b = in->qp_b;
994 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*quant);
995 		break;
996 	}
997 	case HFI_PROPERTY_PARAM_VPE_COLOR_SPACE_CONVERSION: {
998 		struct hfi_vpe_color_space_conversion *in = pdata;
999 		struct hfi_vpe_color_space_conversion *csc = prop_data;
1000 
1001 		memcpy(csc->csc_matrix, in->csc_matrix,
1002 		       sizeof(csc->csc_matrix));
1003 		memcpy(csc->csc_bias, in->csc_bias, sizeof(csc->csc_bias));
1004 		memcpy(csc->csc_limit, in->csc_limit, sizeof(csc->csc_limit));
1005 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*csc);
1006 		break;
1007 	}
1008 	case HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE: {
1009 		struct hfi_enable *in = pdata, *en = prop_data;
1010 
1011 		en->enable = in->enable;
1012 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
1013 		break;
1014 	}
1015 	case HFI_PROPERTY_PARAM_VENC_H264_NAL_SVC_EXT: {
1016 		struct hfi_enable *in = pdata, *en = prop_data;
1017 
1018 		en->enable = in->enable;
1019 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
1020 		break;
1021 	}
1022 	case HFI_PROPERTY_CONFIG_VENC_PERF_MODE: {
1023 		u32 *in = pdata;
1024 
1025 		pkt->data[1] = *in;
1026 		pkt->shdr.hdr.size += sizeof(u32) * 2;
1027 		break;
1028 	}
1029 	case HFI_PROPERTY_PARAM_VENC_HIER_B_MAX_NUM_ENH_LAYER: {
1030 		u32 *in = pdata;
1031 
1032 		pkt->data[1] = *in;
1033 		pkt->shdr.hdr.size += sizeof(u32) * 2;
1034 		break;
1035 	}
1036 	case HFI_PROPERTY_PARAM_VDEC_NONCP_OUTPUT2: {
1037 		struct hfi_enable *in = pdata, *en = prop_data;
1038 
1039 		en->enable = in->enable;
1040 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
1041 		break;
1042 	}
1043 	case HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE: {
1044 		struct hfi_hybrid_hierp *in = pdata, *hierp = prop_data;
1045 
1046 		hierp->layers = in->layers;
1047 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hierp);
1048 		break;
1049 	}
1050 
1051 	/* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */
1052 	case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
1053 	case HFI_PROPERTY_CONFIG_PRIORITY:
1054 	case HFI_PROPERTY_CONFIG_BATCH_INFO:
1055 	case HFI_PROPERTY_SYS_IDLE_INDICATOR:
1056 	case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
1057 	case HFI_PROPERTY_PARAM_INTERLACE_FORMAT_SUPPORTED:
1058 	case HFI_PROPERTY_PARAM_CHROMA_SITE:
1059 	case HFI_PROPERTY_PARAM_PROPERTIES_SUPPORTED:
1060 	case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED:
1061 	case HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED:
1062 	case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
1063 	case HFI_PROPERTY_PARAM_MULTI_VIEW_FORMAT:
1064 	case HFI_PROPERTY_PARAM_MAX_SEQUENCE_HEADER_SIZE:
1065 	case HFI_PROPERTY_PARAM_CODEC_SUPPORTED:
1066 	case HFI_PROPERTY_PARAM_VDEC_MULTI_VIEW_SELECT:
1067 	case HFI_PROPERTY_PARAM_VDEC_MB_QUANTIZATION:
1068 	case HFI_PROPERTY_PARAM_VDEC_NUM_CONCEALED_MB:
1069 	case HFI_PROPERTY_PARAM_VDEC_H264_ENTROPY_SWITCHING:
1070 	case HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_INFO:
1071 	default:
1072 		return -EINVAL;
1073 	}
1074 
1075 	return ret;
1076 }
1077 
1078 static int
1079 pkt_session_get_property_3xx(struct hfi_session_get_property_pkt *pkt,
1080 			     void *cookie, u32 ptype)
1081 {
1082 	int ret = 0;
1083 
1084 	if (!pkt || !cookie)
1085 		return -EINVAL;
1086 
1087 	pkt->shdr.hdr.size = sizeof(struct hfi_session_get_property_pkt);
1088 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_GET_PROPERTY;
1089 	pkt->shdr.session_id = hash32_ptr(cookie);
1090 	pkt->num_properties = 1;
1091 
1092 	switch (ptype) {
1093 	case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
1094 		pkt->data[0] = HFI_PROPERTY_CONFIG_VDEC_ENTROPY;
1095 		break;
1096 	default:
1097 		ret = pkt_session_get_property_1x(pkt, cookie, ptype);
1098 		break;
1099 	}
1100 
1101 	return ret;
1102 }
1103 
1104 static int
1105 pkt_session_set_property_3xx(struct hfi_session_set_property_pkt *pkt,
1106 			     void *cookie, u32 ptype, void *pdata)
1107 {
1108 	void *prop_data;
1109 	int ret = 0;
1110 
1111 	if (!pkt || !cookie || !pdata)
1112 		return -EINVAL;
1113 
1114 	prop_data = &pkt->data[1];
1115 
1116 	pkt->shdr.hdr.size = sizeof(*pkt);
1117 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
1118 	pkt->shdr.session_id = hash32_ptr(cookie);
1119 	pkt->num_properties = 1;
1120 	pkt->data[0] = ptype;
1121 
1122 	/*
1123 	 * Any session set property which is different in 3XX packetization
1124 	 * should be added as a new case below. All unchanged session set
1125 	 * properties will be handled in the default case.
1126 	 */
1127 	switch (ptype) {
1128 	case HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM: {
1129 		struct hfi_multi_stream *in = pdata;
1130 		struct hfi_multi_stream_3x *multi = prop_data;
1131 
1132 		multi->buffer_type = in->buffer_type;
1133 		multi->enable = in->enable;
1134 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*multi);
1135 		break;
1136 	}
1137 	case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH: {
1138 		struct hfi_intra_refresh *in = pdata;
1139 		struct hfi_intra_refresh_3x *intra = prop_data;
1140 
1141 		switch (in->mode) {
1142 		case HFI_INTRA_REFRESH_NONE:
1143 		case HFI_INTRA_REFRESH_ADAPTIVE:
1144 		case HFI_INTRA_REFRESH_CYCLIC:
1145 		case HFI_INTRA_REFRESH_CYCLIC_ADAPTIVE:
1146 		case HFI_INTRA_REFRESH_RANDOM:
1147 			break;
1148 		default:
1149 			ret = -EINVAL;
1150 			break;
1151 		}
1152 
1153 		intra->mode = in->mode;
1154 		intra->mbs = in->cir_mbs;
1155 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*intra);
1156 		break;
1157 	}
1158 	case HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER:
1159 		/* for 3xx fw version session_continue is used */
1160 		break;
1161 	default:
1162 		ret = pkt_session_set_property_1x(pkt, cookie, ptype, pdata);
1163 		break;
1164 	}
1165 
1166 	return ret;
1167 }
1168 
1169 static int
1170 pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt,
1171 			     void *cookie, u32 ptype, void *pdata)
1172 {
1173 	void *prop_data;
1174 
1175 	if (!pkt || !cookie || !pdata)
1176 		return -EINVAL;
1177 
1178 	prop_data = &pkt->data[1];
1179 
1180 	pkt->shdr.hdr.size = sizeof(*pkt);
1181 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
1182 	pkt->shdr.session_id = hash32_ptr(cookie);
1183 	pkt->num_properties = 1;
1184 	pkt->data[0] = ptype;
1185 
1186 	/*
1187 	 * Any session set property which is different in 3XX packetization
1188 	 * should be added as a new case below. All unchanged session set
1189 	 * properties will be handled in the default case.
1190 	 */
1191 	switch (ptype) {
1192 	case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: {
1193 		struct hfi_buffer_count_actual *in = pdata;
1194 		struct hfi_buffer_count_actual_4xx *count = prop_data;
1195 
1196 		count->count_actual = in->count_actual;
1197 		count->type = in->type;
1198 		count->count_min_host = in->count_actual;
1199 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
1200 		break;
1201 	}
1202 	case HFI_PROPERTY_PARAM_WORK_MODE: {
1203 		struct hfi_video_work_mode *in = pdata, *wm = prop_data;
1204 
1205 		wm->video_work_mode = in->video_work_mode;
1206 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*wm);
1207 		break;
1208 	}
1209 	case HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE: {
1210 		struct hfi_videocores_usage_type *in = pdata, *cu = prop_data;
1211 
1212 		cu->video_core_enable_mask = in->video_core_enable_mask;
1213 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*cu);
1214 		break;
1215 	}
1216 	case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE:
1217 		/* not implemented on Venus 4xx */
1218 		return -ENOTSUPP;
1219 	default:
1220 		return pkt_session_set_property_3xx(pkt, cookie, ptype, pdata);
1221 	}
1222 
1223 	return 0;
1224 }
1225 
1226 int pkt_session_get_property(struct hfi_session_get_property_pkt *pkt,
1227 			     void *cookie, u32 ptype)
1228 {
1229 	if (hfi_ver == HFI_VERSION_1XX)
1230 		return pkt_session_get_property_1x(pkt, cookie, ptype);
1231 
1232 	return pkt_session_get_property_3xx(pkt, cookie, ptype);
1233 }
1234 
1235 int pkt_session_set_property(struct hfi_session_set_property_pkt *pkt,
1236 			     void *cookie, u32 ptype, void *pdata)
1237 {
1238 	if (hfi_ver == HFI_VERSION_1XX)
1239 		return pkt_session_set_property_1x(pkt, cookie, ptype, pdata);
1240 
1241 	if (hfi_ver == HFI_VERSION_3XX)
1242 		return pkt_session_set_property_3xx(pkt, cookie, ptype, pdata);
1243 
1244 	return pkt_session_set_property_4xx(pkt, cookie, ptype, pdata);
1245 }
1246 
1247 void pkt_set_version(enum hfi_version version)
1248 {
1249 	hfi_ver = version;
1250 }
1251