GNU Linux-libre 5.10.219-gnu1
[releases.git] / drivers / staging / media / 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[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->stream_id);
306         dst[i++] = upper_32_bits(msg->stream_id);
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->stream_id = src[i++];
410         msg->stream_id |= (((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 }