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