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