1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2019 Pengutronix, Michael Tretter <kernel@pengutronix.de>
4  *
5  * Helper functions for handling messages that are send via mailbox to the
6  * Allegro VCU firmware.
7  */
8 
9 #include <linux/bitfield.h>
10 #include <linux/export.h>
11 #include <linux/errno.h>
12 #include <linux/string.h>
13 #include <linux/videodev2.h>
14 
15 #include "allegro-mail.h"
16 
17 const char *msg_type_name(enum mcu_msg_type type)
18 {
19 	static char buf[9];
20 
21 	switch (type) {
22 	case MCU_MSG_TYPE_INIT:
23 		return "INIT";
24 	case MCU_MSG_TYPE_CREATE_CHANNEL:
25 		return "CREATE_CHANNEL";
26 	case MCU_MSG_TYPE_DESTROY_CHANNEL:
27 		return "DESTROY_CHANNEL";
28 	case MCU_MSG_TYPE_ENCODE_FRAME:
29 		return "ENCODE_FRAME";
30 	case MCU_MSG_TYPE_PUT_STREAM_BUFFER:
31 		return "PUT_STREAM_BUFFER";
32 	case MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE:
33 		return "PUSH_BUFFER_INTERMEDIATE";
34 	case MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE:
35 		return "PUSH_BUFFER_REFERENCE";
36 	default:
37 		snprintf(buf, sizeof(buf), "(0x%04x)", type);
38 		return buf;
39 	}
40 }
41 EXPORT_SYMBOL(msg_type_name);
42 
43 static ssize_t
44 allegro_enc_init(u32 *dst, struct mcu_msg_init_request *msg)
45 {
46 	unsigned int i = 0;
47 	enum mcu_msg_version version = msg->header.version;
48 
49 	dst[i++] = msg->reserved0;
50 	dst[i++] = msg->suballoc_dma;
51 	dst[i++] = msg->suballoc_size;
52 	dst[i++] = msg->l2_cache[0];
53 	dst[i++] = msg->l2_cache[1];
54 	dst[i++] = msg->l2_cache[2];
55 	if (version >= MCU_MSG_VERSION_2019_2) {
56 		dst[i++] = -1;
57 		dst[i++] = 0;
58 	}
59 
60 	return i * sizeof(*dst);
61 }
62 
63 static inline u32 settings_get_mcu_codec(struct create_channel_param *param)
64 {
65 	enum mcu_msg_version version = param->version;
66 	u32 pixelformat = param->codec;
67 
68 	if (version < MCU_MSG_VERSION_2019_2) {
69 		switch (pixelformat) {
70 		case V4L2_PIX_FMT_H264:
71 		default:
72 			return 1;
73 		}
74 	} else {
75 		switch (pixelformat) {
76 		case V4L2_PIX_FMT_H264:
77 		default:
78 			return 0;
79 		}
80 	}
81 }
82 
83 ssize_t
84 allegro_encode_config_blob(u32 *dst, struct create_channel_param *param)
85 {
86 	enum mcu_msg_version version = param->version;
87 	unsigned int i = 0;
88 	unsigned int j = 0;
89 	u32 val;
90 	unsigned int codec = settings_get_mcu_codec(param);
91 
92 	if (version >= MCU_MSG_VERSION_2019_2)
93 		dst[i++] = param->layer_id;
94 	dst[i++] = FIELD_PREP(GENMASK(31, 16), param->height) |
95 		   FIELD_PREP(GENMASK(15, 0), param->width);
96 	if (version >= MCU_MSG_VERSION_2019_2)
97 		dst[i++] = param->videomode;
98 	dst[i++] = param->format;
99 	if (version < MCU_MSG_VERSION_2019_2)
100 		dst[i++] = param->colorspace;
101 	dst[i++] = param->src_mode;
102 	if (version >= MCU_MSG_VERSION_2019_2)
103 		dst[i++] = param->src_bit_depth;
104 	dst[i++] = FIELD_PREP(GENMASK(31, 24), codec) |
105 		   FIELD_PREP(GENMASK(23, 8), param->constraint_set_flags) |
106 		   FIELD_PREP(GENMASK(7, 0), param->profile);
107 	dst[i++] = FIELD_PREP(GENMASK(31, 16), param->tier) |
108 		   FIELD_PREP(GENMASK(15, 0), param->level);
109 
110 	val = 0;
111 	val |= param->temporal_mvp_enable ? BIT(20) : 0;
112 	val |= FIELD_PREP(GENMASK(7, 4), param->log2_max_frame_num) |
113 	       FIELD_PREP(GENMASK(3, 0), param->log2_max_poc);
114 	dst[i++] = val;
115 
116 	val = 0;
117 	val |= param->dbf_ovr_en ? BIT(2) : 0;
118 	dst[i++] = val;
119 
120 	if (version >= MCU_MSG_VERSION_2019_2) {
121 		val = 0;
122 		val |= param->custom_lda ? BIT(2) : 0;
123 		val |= param->rdo_cost_mode ? BIT(20) : 0;
124 		dst[i++] = val;
125 
126 		val = 0;
127 		val |= param->lf ? BIT(2) : 0;
128 		val |= param->lf_x_tile ? BIT(3) : 0;
129 		val |= param->lf_x_slice ? BIT(4) : 0;
130 		dst[i++] = val;
131 	} else {
132 		val = 0;
133 		dst[i++] = val;
134 	}
135 
136 	dst[i++] = FIELD_PREP(GENMASK(15, 8), param->beta_offset) |
137 		   FIELD_PREP(GENMASK(7, 0), param->tc_offset);
138 	dst[i++] = param->unknown11;
139 	dst[i++] = param->unknown12;
140 	if (version >= MCU_MSG_VERSION_2019_2)
141 		dst[i++] = param->num_slices;
142 	else
143 		dst[i++] = FIELD_PREP(GENMASK(31, 16), param->prefetch_auto) |
144 			   FIELD_PREP(GENMASK(15, 0), param->num_slices);
145 	dst[i++] = param->prefetch_mem_offset;
146 	dst[i++] = param->prefetch_mem_size;
147 	dst[i++] = FIELD_PREP(GENMASK(31, 16), param->clip_vrt_range) |
148 		   FIELD_PREP(GENMASK(15, 0), param->clip_hrz_range);
149 	dst[i++] = FIELD_PREP(GENMASK(31, 16), param->me_range[1]) |
150 		   FIELD_PREP(GENMASK(15, 0), param->me_range[0]);
151 	dst[i++] = FIELD_PREP(GENMASK(31, 16), param->me_range[3]) |
152 		   FIELD_PREP(GENMASK(15, 0), param->me_range[2]);
153 	dst[i++] = FIELD_PREP(GENMASK(31, 24), param->min_tu_size) |
154 		   FIELD_PREP(GENMASK(23, 16), param->max_tu_size) |
155 		   FIELD_PREP(GENMASK(15, 8), param->min_cu_size) |
156 		   FIELD_PREP(GENMASK(8, 0), param->max_cu_size);
157 	dst[i++] = FIELD_PREP(GENMASK(15, 8), param->max_transfo_depth_intra) |
158 		   FIELD_PREP(GENMASK(7, 0), param->max_transfo_depth_inter);
159 	dst[i++] = param->entropy_mode;
160 	dst[i++] = param->wp_mode;
161 
162 	dst[i++] = param->rate_control_mode;
163 	dst[i++] = param->initial_rem_delay;
164 	dst[i++] = param->cpb_size;
165 	dst[i++] = FIELD_PREP(GENMASK(31, 16), param->clk_ratio) |
166 		   FIELD_PREP(GENMASK(15, 0), param->framerate);
167 	dst[i++] = param->target_bitrate;
168 	dst[i++] = param->max_bitrate;
169 	dst[i++] = FIELD_PREP(GENMASK(31, 16), param->min_qp) |
170 		   FIELD_PREP(GENMASK(15, 0), param->initial_qp);
171 	dst[i++] = FIELD_PREP(GENMASK(31, 16), param->ip_delta) |
172 		   FIELD_PREP(GENMASK(15, 0), param->max_qp);
173 	dst[i++] = FIELD_PREP(GENMASK(31, 16), param->golden_ref) |
174 		   FIELD_PREP(GENMASK(15, 0), param->pb_delta);
175 	dst[i++] = FIELD_PREP(GENMASK(31, 16), param->golden_ref_frequency) |
176 		   FIELD_PREP(GENMASK(15, 0), param->golden_delta);
177 	if (version >= MCU_MSG_VERSION_2019_2)
178 		dst[i++] = param->rate_control_option;
179 	else
180 		dst[i++] = 0;
181 
182 	if (version >= MCU_MSG_VERSION_2019_2) {
183 		dst[i++] = param->num_pixel;
184 		dst[i++] = FIELD_PREP(GENMASK(31, 16), param->max_pixel_value) |
185 			FIELD_PREP(GENMASK(15, 0), param->max_psnr);
186 		for (j = 0; j < 3; j++)
187 			dst[i++] = param->maxpicturesize[j];
188 	}
189 
190 	if (version >= MCU_MSG_VERSION_2019_2)
191 		dst[i++] = param->gop_ctrl_mode;
192 	else
193 		dst[i++] = 0;
194 
195 	if (version >= MCU_MSG_VERSION_2019_2)
196 		dst[i++] = FIELD_PREP(GENMASK(31, 24), param->freq_golden_ref) |
197 			   FIELD_PREP(GENMASK(23, 16), param->num_b) |
198 			   FIELD_PREP(GENMASK(15, 0), param->gop_length);
199 	dst[i++] = param->freq_idr;
200 	if (version >= MCU_MSG_VERSION_2019_2)
201 		dst[i++] = param->enable_lt;
202 	dst[i++] = param->freq_lt;
203 	dst[i++] = param->gdr_mode;
204 	if (version < MCU_MSG_VERSION_2019_2)
205 		dst[i++] = FIELD_PREP(GENMASK(31, 24), param->freq_golden_ref) |
206 			   FIELD_PREP(GENMASK(23, 16), param->num_b) |
207 			   FIELD_PREP(GENMASK(15, 0), param->gop_length);
208 
209 	if (version >= MCU_MSG_VERSION_2019_2)
210 		dst[i++] = param->tmpdqp;
211 
212 	dst[i++] = param->subframe_latency;
213 	dst[i++] = param->lda_control_mode;
214 	if (version < MCU_MSG_VERSION_2019_2)
215 		dst[i++] = param->unknown41;
216 
217 	if (version >= MCU_MSG_VERSION_2019_2) {
218 		for (j = 0; j < 6; j++)
219 			dst[i++] = param->lda_factors[j];
220 		dst[i++] = param->max_num_merge_cand;
221 	}
222 
223 	return i * sizeof(*dst);
224 }
225 
226 static ssize_t
227 allegro_enc_create_channel(u32 *dst, struct mcu_msg_create_channel *msg)
228 {
229 	enum mcu_msg_version version = msg->header.version;
230 	unsigned int i = 0;
231 
232 	dst[i++] = msg->user_id;
233 
234 	if (version >= MCU_MSG_VERSION_2019_2) {
235 		dst[i++] = msg->blob_mcu_addr;
236 	} else {
237 		memcpy(&dst[i], msg->blob, msg->blob_size);
238 		i += msg->blob_size / sizeof(*dst);
239 	}
240 
241 	if (version >= MCU_MSG_VERSION_2019_2)
242 		dst[i++] = msg->ep1_addr;
243 
244 	return i * sizeof(*dst);
245 }
246 
247 ssize_t allegro_decode_config_blob(struct create_channel_param *param,
248 				   struct mcu_msg_create_channel_response *msg,
249 				   u32 *src)
250 {
251 	enum mcu_msg_version version = msg->header.version;
252 
253 	if (version >= MCU_MSG_VERSION_2019_2) {
254 		param->num_ref_idx_l0 = FIELD_GET(GENMASK(7, 4), src[9]);
255 		param->num_ref_idx_l1 = FIELD_GET(GENMASK(11, 8), src[9]);
256 	} else {
257 		param->num_ref_idx_l0 = msg->num_ref_idx_l0;
258 		param->num_ref_idx_l1 = msg->num_ref_idx_l1;
259 	}
260 
261 	return 0;
262 }
263 
264 static ssize_t
265 allegro_enc_destroy_channel(u32 *dst, struct mcu_msg_destroy_channel *msg)
266 {
267 	unsigned int i = 0;
268 
269 	dst[i++] = msg->channel_id;
270 
271 	return i * sizeof(*dst);
272 }
273 
274 static ssize_t
275 allegro_enc_push_buffers(u32 *dst, struct mcu_msg_push_buffers_internal *msg)
276 {
277 	unsigned int i = 0;
278 	struct mcu_msg_push_buffers_internal_buffer *buffer;
279 	unsigned int num_buffers = msg->num_buffers;
280 	unsigned int j;
281 
282 	dst[i++] = msg->channel_id;
283 
284 	for (j = 0; j < num_buffers; j++) {
285 		buffer = &msg->buffer[j];
286 		dst[i++] = buffer->dma_addr;
287 		dst[i++] = buffer->mcu_addr;
288 		dst[i++] = buffer->size;
289 	}
290 
291 	return i * sizeof(*dst);
292 }
293 
294 static ssize_t
295 allegro_enc_put_stream_buffer(u32 *dst,
296 			      struct mcu_msg_put_stream_buffer *msg)
297 {
298 	unsigned int i = 0;
299 
300 	dst[i++] = msg->channel_id;
301 	dst[i++] = msg->dma_addr;
302 	dst[i++] = msg->mcu_addr;
303 	dst[i++] = msg->size;
304 	dst[i++] = msg->offset;
305 	dst[i++] = lower_32_bits(msg->dst_handle);
306 	dst[i++] = upper_32_bits(msg->dst_handle);
307 
308 	return i * sizeof(*dst);
309 }
310 
311 static ssize_t
312 allegro_enc_encode_frame(u32 *dst, struct mcu_msg_encode_frame *msg)
313 {
314 	enum mcu_msg_version version = msg->header.version;
315 	unsigned int i = 0;
316 
317 	dst[i++] = msg->channel_id;
318 
319 	dst[i++] = msg->reserved;
320 	dst[i++] = msg->encoding_options;
321 	dst[i++] = FIELD_PREP(GENMASK(31, 16), msg->padding) |
322 		   FIELD_PREP(GENMASK(15, 0), msg->pps_qp);
323 
324 	if (version >= MCU_MSG_VERSION_2019_2) {
325 		dst[i++] = 0;
326 		dst[i++] = 0;
327 		dst[i++] = 0;
328 		dst[i++] = 0;
329 	}
330 
331 	dst[i++] = lower_32_bits(msg->user_param);
332 	dst[i++] = upper_32_bits(msg->user_param);
333 	dst[i++] = lower_32_bits(msg->src_handle);
334 	dst[i++] = upper_32_bits(msg->src_handle);
335 	dst[i++] = msg->request_options;
336 	dst[i++] = msg->src_y;
337 	dst[i++] = msg->src_uv;
338 	if (version >= MCU_MSG_VERSION_2019_2)
339 		dst[i++] = msg->is_10_bit;
340 	dst[i++] = msg->stride;
341 	if (version >= MCU_MSG_VERSION_2019_2)
342 		dst[i++] = msg->format;
343 	dst[i++] = msg->ep2;
344 	dst[i++] = lower_32_bits(msg->ep2_v);
345 	dst[i++] = upper_32_bits(msg->ep2_v);
346 
347 	return i * sizeof(*dst);
348 }
349 
350 static ssize_t
351 allegro_dec_init(struct mcu_msg_init_response *msg, u32 *src)
352 {
353 	unsigned int i = 0;
354 
355 	msg->reserved0 = src[i++];
356 
357 	return i * sizeof(*src);
358 }
359 
360 static ssize_t
361 allegro_dec_create_channel(struct mcu_msg_create_channel_response *msg,
362 			   u32 *src)
363 {
364 	enum mcu_msg_version version = msg->header.version;
365 	unsigned int i = 0;
366 
367 	msg->channel_id = src[i++];
368 	msg->user_id = src[i++];
369 	/*
370 	 * Version >= MCU_MSG_VERSION_2019_2 is handled in
371 	 * allegro_decode_config_blob().
372 	 */
373 	if (version < MCU_MSG_VERSION_2019_2) {
374 		msg->options = src[i++];
375 		msg->num_core = src[i++];
376 		msg->num_ref_idx_l0 = FIELD_GET(GENMASK(7, 4), src[i]);
377 		msg->num_ref_idx_l1 = FIELD_GET(GENMASK(11, 8), src[i++]);
378 	}
379 	msg->int_buffers_count = src[i++];
380 	msg->int_buffers_size = src[i++];
381 	msg->rec_buffers_count = src[i++];
382 	msg->rec_buffers_size = src[i++];
383 	msg->reserved = src[i++];
384 	msg->error_code = src[i++];
385 
386 	return i * sizeof(*src);
387 }
388 
389 static ssize_t
390 allegro_dec_destroy_channel(struct mcu_msg_destroy_channel_response *msg,
391 			    u32 *src)
392 {
393 	unsigned int i = 0;
394 
395 	msg->channel_id = src[i++];
396 
397 	return i * sizeof(*src);
398 }
399 
400 static ssize_t
401 allegro_dec_encode_frame(struct mcu_msg_encode_frame_response *msg, u32 *src)
402 {
403 	enum mcu_msg_version version = msg->header.version;
404 	unsigned int i = 0;
405 	unsigned int j;
406 
407 	msg->channel_id = src[i++];
408 
409 	msg->dst_handle = src[i++];
410 	msg->dst_handle |= (((u64)src[i++]) << 32);
411 	msg->user_param = src[i++];
412 	msg->user_param |= (((u64)src[i++]) << 32);
413 	msg->src_handle = src[i++];
414 	msg->src_handle |= (((u64)src[i++]) << 32);
415 	msg->skip = FIELD_GET(GENMASK(31, 16), src[i]);
416 	msg->is_ref = FIELD_GET(GENMASK(15, 0), src[i++]);
417 	msg->initial_removal_delay = src[i++];
418 	msg->dpb_output_delay = src[i++];
419 	msg->size = src[i++];
420 	msg->frame_tag_size = src[i++];
421 	msg->stuffing = src[i++];
422 	msg->filler = src[i++];
423 	msg->num_column = FIELD_GET(GENMASK(31, 16), src[i]);
424 	msg->num_row = FIELD_GET(GENMASK(15, 0), src[i++]);
425 	msg->num_ref_idx_l1 = FIELD_GET(GENMASK(31, 24), src[i]);
426 	msg->num_ref_idx_l0 = FIELD_GET(GENMASK(23, 16), src[i]);
427 	msg->qp = FIELD_GET(GENMASK(15, 0), src[i++]);
428 	msg->partition_table_offset = src[i++];
429 	msg->partition_table_size = src[i++];
430 	msg->sum_complex = src[i++];
431 	for (j = 0; j < 4; j++)
432 		msg->tile_width[j] = src[i++];
433 	for (j = 0; j < 22; j++)
434 		msg->tile_height[j] = src[i++];
435 	msg->error_code = src[i++];
436 	msg->slice_type = src[i++];
437 	msg->pic_struct = src[i++];
438 	msg->reserved = FIELD_GET(GENMASK(31, 24), src[i]);
439 	msg->is_last_slice = FIELD_GET(GENMASK(23, 16), src[i]);
440 	msg->is_first_slice = FIELD_GET(GENMASK(15, 8), src[i]);
441 	msg->is_idr = FIELD_GET(GENMASK(7, 0), src[i++]);
442 
443 	msg->reserved1 = FIELD_GET(GENMASK(31, 16), src[i]);
444 	msg->pps_qp = FIELD_GET(GENMASK(15, 0), src[i++]);
445 
446 	msg->reserved2 = src[i++];
447 	if (version >= MCU_MSG_VERSION_2019_2) {
448 		msg->reserved3 = src[i++];
449 		msg->reserved4 = src[i++];
450 		msg->reserved5 = src[i++];
451 		msg->reserved6 = src[i++];
452 	}
453 
454 	return i * sizeof(*src);
455 }
456 
457 /**
458  * allegro_encode_mail() - Encode allegro messages to firmware format
459  * @dst: Pointer to the memory that will be filled with data
460  * @msg: The allegro message that will be encoded
461  */
462 ssize_t allegro_encode_mail(u32 *dst, void *msg)
463 {
464 	const struct mcu_msg_header *header = msg;
465 	ssize_t size;
466 
467 	if (!msg || !dst)
468 		return -EINVAL;
469 
470 	switch (header->type) {
471 	case MCU_MSG_TYPE_INIT:
472 		size = allegro_enc_init(&dst[1], msg);
473 		break;
474 	case MCU_MSG_TYPE_CREATE_CHANNEL:
475 		size = allegro_enc_create_channel(&dst[1], msg);
476 		break;
477 	case MCU_MSG_TYPE_DESTROY_CHANNEL:
478 		size = allegro_enc_destroy_channel(&dst[1], msg);
479 		break;
480 	case MCU_MSG_TYPE_ENCODE_FRAME:
481 		size = allegro_enc_encode_frame(&dst[1], msg);
482 		break;
483 	case MCU_MSG_TYPE_PUT_STREAM_BUFFER:
484 		size = allegro_enc_put_stream_buffer(&dst[1], msg);
485 		break;
486 	case MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE:
487 	case MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE:
488 		size = allegro_enc_push_buffers(&dst[1], msg);
489 		break;
490 	default:
491 		return -EINVAL;
492 	}
493 
494 	/*
495 	 * The encoded messages might have different length depending on
496 	 * the firmware version or certain fields. Therefore, we have to
497 	 * set the body length after encoding the message.
498 	 */
499 	dst[0] = FIELD_PREP(GENMASK(31, 16), header->type) |
500 		 FIELD_PREP(GENMASK(15, 0), size);
501 
502 	return size + sizeof(*dst);
503 }
504 
505 /**
506  * allegro_decode_mail() - Parse allegro messages from the firmware.
507  * @msg: The mcu_msg_response that will be filled with parsed values.
508  * @src: Pointer to the memory that will be parsed
509  *
510  * The message format in the mailbox depends on the firmware. Parse the
511  * different formats into a uniform message format that can be used without
512  * taking care of the firmware version.
513  */
514 int allegro_decode_mail(void *msg, u32 *src)
515 {
516 	struct mcu_msg_header *header;
517 
518 	if (!src || !msg)
519 		return -EINVAL;
520 
521 	header = msg;
522 	header->type = FIELD_GET(GENMASK(31, 16), src[0]);
523 
524 	src++;
525 	switch (header->type) {
526 	case MCU_MSG_TYPE_INIT:
527 		allegro_dec_init(msg, src);
528 		break;
529 	case MCU_MSG_TYPE_CREATE_CHANNEL:
530 		allegro_dec_create_channel(msg, src);
531 		break;
532 	case MCU_MSG_TYPE_DESTROY_CHANNEL:
533 		allegro_dec_destroy_channel(msg, src);
534 		break;
535 	case MCU_MSG_TYPE_ENCODE_FRAME:
536 		allegro_dec_encode_frame(msg, src);
537 		break;
538 	default:
539 		return -EINVAL;
540 	}
541 
542 	return 0;
543 }
544