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