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