allegro-mail.c 15 KB

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