msm_venc.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  4. */
  5. #include <media/v4l2_vidc_extensions.h>
  6. #include <media/msm_media_info.h>
  7. #include "msm_venc.h"
  8. #include "msm_vidc_core.h"
  9. #include "msm_vidc_inst.h"
  10. #include "msm_vidc_driver.h"
  11. #include "msm_vidc_internal.h"
  12. #include "msm_vidc_platform.h"
  13. #include "msm_vidc_control.h"
  14. #include "msm_vidc_debug.h"
  15. #include "venus_hfi.h"
  16. #include "hfi_packet.h"
  17. u32 msm_venc_input_set_prop[] = {
  18. HFI_PROP_COLOR_FORMAT,
  19. HFI_PROP_RAW_RESOLUTION,
  20. HFI_PROP_LINEAR_ALIGNMENT_FACTOR,
  21. HFI_PROP_BUFFER_HOST_MAX_COUNT,
  22. };
  23. u32 msm_venc_output_set_prop[] = {
  24. HFI_PROP_BITSTREAM_RESOLUTION,
  25. HFI_PROP_CROP_OFFSETS,
  26. HFI_PROP_BUFFER_HOST_MAX_COUNT,
  27. };
  28. u32 msm_venc_input_subscribe_for_properties[] = {
  29. HFI_PROP_NO_OUTPUT,
  30. };
  31. u32 msm_venc_output_subscribe_for_properties[] = {
  32. HFI_PROP_PICTURE_TYPE,
  33. HFI_PROP_BUFFER_MARK,
  34. };
  35. static int msm_venc_codec_change(struct msm_vidc_inst *inst, u32 v4l2_codec)
  36. {
  37. int rc = 0;
  38. if (inst->codec && inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat == v4l2_codec)
  39. return 0;
  40. s_vpr_h(inst->sid, "%s: codec changed from %#x to %#x\n",
  41. __func__, inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat, v4l2_codec);
  42. inst->codec = v4l2_codec_to_driver(v4l2_codec, __func__);
  43. rc = msm_vidc_get_inst_capability(inst);
  44. if (rc)
  45. goto exit;
  46. rc = msm_vidc_ctrl_deinit(inst);
  47. if (rc)
  48. goto exit;
  49. rc = msm_vidc_ctrl_init(inst);
  50. if (rc)
  51. goto exit;
  52. exit:
  53. return rc;
  54. }
  55. /* todo: add logs for each property once finalised */
  56. static int msm_venc_set_colorformat(struct msm_vidc_inst *inst,
  57. enum msm_vidc_port_type port)
  58. {
  59. int rc = 0;
  60. u32 pixelformat;
  61. enum msm_vidc_colorformat_type colorformat;
  62. u32 hfi_colorformat;
  63. if (port != INPUT_PORT && port != OUTPUT_PORT) {
  64. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  65. return -EINVAL;
  66. }
  67. pixelformat = inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat;
  68. if (pixelformat != V4L2_PIX_FMT_VIDC_NV12C &&
  69. pixelformat != V4L2_PIX_FMT_VIDC_TP10C) {
  70. s_vpr_e(inst->sid, "%s: invalid pixelformat %#x\n",
  71. __func__, pixelformat);
  72. return -EINVAL;
  73. }
  74. colorformat = v4l2_colorformat_to_driver(pixelformat, __func__);
  75. hfi_colorformat = get_hfi_colorformat(inst, colorformat);
  76. rc = venus_hfi_session_property(inst,
  77. HFI_PROP_COLOR_FORMAT,
  78. HFI_HOST_FLAGS_NONE,
  79. get_hfi_port(inst, port),
  80. HFI_PAYLOAD_U32_ENUM,
  81. &hfi_colorformat,
  82. sizeof(u32));
  83. if (rc)
  84. return rc;
  85. return 0;
  86. }
  87. /* TODO: Enable when NV12 support is required */
  88. static int msm_venc_set_linear_alignment_factor(struct msm_vidc_inst *inst,
  89. enum msm_vidc_port_type port)
  90. {
  91. /* int rc = 0;
  92. u32 pixelformat;
  93. u32 alignment_factor[2];
  94. if (port != INPUT_PORT) {
  95. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  96. return -EINVAL;
  97. }
  98. pixelformat = inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat;
  99. if (pixelformat == V4L2_PIX_FMT_VIDC_NV12C ||
  100. pixelformat == V4L2_PIX_FMT_VIDC_TP10C ||
  101. pixelformat == V4L2_PIX_FMT_VIDC_ARGB32C) {
  102. s_vpr_e(inst->sid,
  103. "%s: not a linear color fmt, property is not set\n",
  104. __func__);
  105. return 0;
  106. }
  107. if (pixelformat == V4L2_PIX_FMT_ARGB32) {
  108. alignment_factor[0] =
  109. (rgb_stride_alignment(pixelformat, __func__) << 16) |
  110. rgb_scanline_alignment(pixelformat, __func__);
  111. alignment_factor[1] = 0;
  112. } else {
  113. alignment_factor[0] =
  114. (y_stride_alignment(pixelformat, __func__) << 16) |
  115. y_scanline_alignment(pixelformat, __func__);
  116. alignment_factor[1] =
  117. (uv_stride_alignment(pixelformat, __func__) << 16) |
  118. uv_scanline_alignment(pixelformat, __func__);
  119. }
  120. s_vpr_h(inst->sid, "%s: payload[0]: %u payload[1]: %u\n", __func__,
  121. alignment_factor[0], alignment_factor[1]);
  122. rc = venus_hfi_session_property(inst,
  123. HFI_PROP_LINEAR_ALIGNMENT_FACTOR,
  124. HFI_HOST_FLAGS_NONE,
  125. get_hfi_port(inst, port),
  126. HFI_PAYLOAD_64_PACKED,
  127. &alignment_factor,
  128. sizeof(u64));
  129. if (rc)
  130. return rc;
  131. */
  132. return 0;
  133. }
  134. static int msm_venc_set_raw_resolution(struct msm_vidc_inst *inst,
  135. enum msm_vidc_port_type port)
  136. {
  137. int rc = 0;
  138. u32 resolution;
  139. if (port != INPUT_PORT) {
  140. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  141. return -EINVAL;
  142. }
  143. resolution = inst->crop.width << 16 | inst->crop.height;
  144. s_vpr_h(inst->sid, "%s: width: %d height: %d\n", __func__,
  145. inst->crop.width, inst->crop.height);
  146. rc = venus_hfi_session_property(inst,
  147. HFI_PROP_RAW_RESOLUTION,
  148. HFI_HOST_FLAGS_NONE,
  149. get_hfi_port(inst, port),
  150. HFI_PAYLOAD_32_PACKED,
  151. &resolution,
  152. sizeof(u32));
  153. if (rc)
  154. return rc;
  155. return 0;
  156. }
  157. static int msm_venc_set_bitstream_resolution(struct msm_vidc_inst *inst,
  158. enum msm_vidc_port_type port)
  159. {
  160. int rc = 0;
  161. u32 resolution;
  162. if (port != OUTPUT_PORT) {
  163. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  164. return -EINVAL;
  165. }
  166. resolution = (inst->fmts[port].fmt.pix_mp.width << 16) |
  167. inst->fmts[port].fmt.pix_mp.height;
  168. s_vpr_h(inst->sid, "%s: width: %d height: %d\n", __func__,
  169. inst->fmts[port].fmt.pix_mp.width,
  170. inst->fmts[port].fmt.pix_mp.height);
  171. rc = venus_hfi_session_property(inst,
  172. HFI_PROP_BITSTREAM_RESOLUTION,
  173. HFI_HOST_FLAGS_NONE,
  174. get_hfi_port(inst, port),
  175. HFI_PAYLOAD_32_PACKED,
  176. &resolution,
  177. sizeof(u32));
  178. if (rc)
  179. return rc;
  180. return 0;
  181. }
  182. static int msm_venc_set_crop_offsets(struct msm_vidc_inst *inst,
  183. enum msm_vidc_port_type port)
  184. {
  185. int rc = 0;
  186. u32 left_offset, top_offset, right_offset, bottom_offset;
  187. u64 crop;
  188. if (port != OUTPUT_PORT) {
  189. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  190. return -EINVAL;
  191. }
  192. left_offset = inst->crop.left;
  193. top_offset = inst->crop.top;
  194. right_offset = (inst->fmts[port].fmt.pix_mp.width -
  195. inst->crop.width);
  196. bottom_offset = (inst->fmts[port].fmt.pix_mp.height -
  197. inst->crop.height);
  198. crop = (u64)right_offset << 48 | (u64)bottom_offset << 32 |
  199. (u64)left_offset << 16 | top_offset;
  200. s_vpr_h(inst->sid, "%s: left_offset: %d top_offset: %d "
  201. "right_offset: %d bottom_offset: %d", __func__,
  202. left_offset, top_offset, right_offset, bottom_offset);
  203. rc = venus_hfi_session_property(inst,
  204. HFI_PROP_CROP_OFFSETS,
  205. HFI_HOST_FLAGS_NONE,
  206. get_hfi_port(inst, port),
  207. HFI_PAYLOAD_64_PACKED,
  208. &crop,
  209. sizeof(u64));
  210. if (rc)
  211. return rc;
  212. return 0;
  213. }
  214. static int msm_venc_set_host_max_buf_count(struct msm_vidc_inst *inst,
  215. enum msm_vidc_port_type port)
  216. {
  217. int rc = 0;
  218. u32 count = DEFAULT_MAX_HOST_BUF_COUNT;
  219. if (port != INPUT_PORT && port != OUTPUT_PORT) {
  220. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  221. return -EINVAL;
  222. }
  223. s_vpr_h(inst->sid, "%s: count: %u port: %u\n", __func__, count, port);
  224. rc = venus_hfi_session_property(inst,
  225. HFI_PROP_BUFFER_HOST_MAX_COUNT,
  226. HFI_HOST_FLAGS_NONE,
  227. get_hfi_port(inst, port),
  228. HFI_PAYLOAD_U32,
  229. &count,
  230. sizeof(u32));
  231. if (rc)
  232. return rc;
  233. return 0;
  234. }
  235. static int msm_venc_set_stage(struct msm_vidc_inst *inst)
  236. {
  237. int rc = 0;
  238. struct msm_vidc_core *core = inst->core;
  239. struct msm_vidc_inst_capability *capability = inst->capabilities;
  240. u32 stage;
  241. rc = call_session_op(core, decide_work_mode, inst);
  242. if (rc) {
  243. s_vpr_e(inst->sid, "%s: decide_work_mode failed\n",
  244. __func__);
  245. return -EINVAL;
  246. }
  247. stage = capability->cap[STAGE].value;
  248. s_vpr_h(inst->sid, "%s: stage: %u\n", __func__, stage);
  249. rc = venus_hfi_session_property(inst,
  250. HFI_PROP_STAGE,
  251. HFI_HOST_FLAGS_NONE,
  252. HFI_PORT_NONE,
  253. HFI_PAYLOAD_U32,
  254. &stage,
  255. sizeof(u32));
  256. if (rc)
  257. return rc;
  258. return 0;
  259. }
  260. static int msm_venc_set_pipe(struct msm_vidc_inst *inst)
  261. {
  262. int rc = 0;
  263. struct msm_vidc_core *core = inst->core;
  264. struct msm_vidc_inst_capability *capability = inst->capabilities;
  265. u32 pipe;
  266. rc = call_session_op(core, decide_work_route, inst);
  267. if (rc) {
  268. s_vpr_e(inst->sid, "%s: decide_work_route failed\n",
  269. __func__);
  270. return -EINVAL;
  271. }
  272. pipe = capability->cap[PIPE].value;
  273. s_vpr_h(inst->sid, "%s: pipe: %u\n", __func__, pipe);
  274. rc = venus_hfi_session_property(inst,
  275. HFI_PROP_PIPE,
  276. HFI_HOST_FLAGS_NONE,
  277. HFI_PORT_NONE,
  278. HFI_PAYLOAD_U32,
  279. &pipe,
  280. sizeof(u32));
  281. if (rc)
  282. return rc;
  283. return 0;
  284. }
  285. static int msm_venc_set_quality_mode(struct msm_vidc_inst *inst)
  286. {
  287. int rc = 0;
  288. struct msm_vidc_inst_capability *capability = inst->capabilities;
  289. u32 mode;
  290. mode = capability->cap[QUALITY_MODE].value;
  291. s_vpr_h(inst->sid, "%s: quality_mode: %u\n", __func__, mode);
  292. rc = venus_hfi_session_property(inst,
  293. HFI_PROP_QUALITY_MODE,
  294. HFI_HOST_FLAGS_NONE,
  295. HFI_PORT_BITSTREAM,
  296. HFI_PAYLOAD_U32_ENUM,
  297. &mode,
  298. sizeof(u32));
  299. if (rc)
  300. return rc;
  301. return 0;
  302. }
  303. static int msm_venc_set_input_properties(struct msm_vidc_inst *inst)
  304. {
  305. int rc = 0;
  306. int i = 0;
  307. d_vpr_h("%s()\n", __func__);
  308. if (!inst) {
  309. d_vpr_e("%s: invalid params\n", __func__);
  310. return -EINVAL;
  311. }
  312. for (i = 0; i < ARRAY_SIZE(msm_venc_input_set_prop);
  313. i++) {
  314. switch (msm_venc_input_set_prop[i]) {
  315. case HFI_PROP_COLOR_FORMAT:
  316. rc = msm_venc_set_colorformat(inst, INPUT_PORT);
  317. break;
  318. case HFI_PROP_RAW_RESOLUTION:
  319. rc = msm_venc_set_raw_resolution(inst, INPUT_PORT);
  320. break;
  321. case HFI_PROP_LINEAR_ALIGNMENT_FACTOR:
  322. rc = msm_venc_set_linear_alignment_factor(inst, INPUT_PORT);
  323. break;
  324. case HFI_PROP_BUFFER_HOST_MAX_COUNT:
  325. rc = msm_venc_set_host_max_buf_count(inst, INPUT_PORT);
  326. break;
  327. default:
  328. d_vpr_e("%s: unknown property %#x\n", __func__,
  329. msm_venc_input_set_prop[i]);
  330. rc = -EINVAL;
  331. break;
  332. }
  333. }
  334. return rc;
  335. }
  336. static int msm_venc_set_output_properties(struct msm_vidc_inst *inst)
  337. {
  338. int rc = 0;
  339. int i = 0;
  340. d_vpr_h("%s()\n", __func__);
  341. if (!inst) {
  342. d_vpr_e("%s: invalid params\n", __func__);
  343. return -EINVAL;
  344. }
  345. for (i = 0; i < ARRAY_SIZE(msm_venc_output_set_prop);
  346. i++) {
  347. switch (msm_venc_output_set_prop[i]) {
  348. case HFI_PROP_BITSTREAM_RESOLUTION:
  349. rc = msm_venc_set_bitstream_resolution(inst, OUTPUT_PORT);
  350. break;
  351. case HFI_PROP_CROP_OFFSETS:
  352. rc = msm_venc_set_crop_offsets(inst, OUTPUT_PORT);
  353. break;
  354. case HFI_PROP_BUFFER_HOST_MAX_COUNT:
  355. rc = msm_venc_set_host_max_buf_count(inst, OUTPUT_PORT);
  356. break;
  357. default:
  358. d_vpr_e("%s: unknown property %#x\n", __func__,
  359. msm_venc_output_set_prop[i]);
  360. rc = -EINVAL;
  361. break;
  362. }
  363. }
  364. return rc;
  365. }
  366. static int msm_venc_set_internal_properties(struct msm_vidc_inst *inst)
  367. {
  368. int rc = 0;
  369. d_vpr_h("%s()\n", __func__);
  370. if (!inst) {
  371. d_vpr_e("%s: invalid params\n", __func__);
  372. return -EINVAL;
  373. }
  374. //TODO: set HFI_PORT_NONE properties at master port streamon.
  375. rc = msm_venc_set_stage(inst);
  376. if (rc)
  377. return rc;
  378. rc = msm_venc_set_pipe(inst);
  379. if (rc)
  380. return rc;
  381. rc = msm_venc_set_quality_mode(inst);
  382. if (rc)
  383. return rc;
  384. return rc;
  385. }
  386. static int msm_venc_get_input_internal_buffers(struct msm_vidc_inst *inst)
  387. {
  388. int rc = 0;
  389. struct msm_vidc_core *core;
  390. if (!inst || !inst->core) {
  391. d_vpr_e("%s: invalid params\n", __func__);
  392. return -EINVAL;
  393. }
  394. core = inst->core;
  395. inst->buffers.arp.size = call_session_op(core, buffer_size,
  396. inst, MSM_VIDC_BUF_ARP) + 100000000;
  397. inst->buffers.bin.size = call_session_op(core, buffer_size,
  398. inst, MSM_VIDC_BUF_BIN) + 100000000;
  399. inst->buffers.comv.size = call_session_op(core, buffer_size,
  400. inst, MSM_VIDC_BUF_COMV) + 100000000;
  401. inst->buffers.non_comv.size = call_session_op(core, buffer_size,
  402. inst, MSM_VIDC_BUF_NON_COMV) + 100000000;
  403. inst->buffers.line.size = call_session_op(core, buffer_size,
  404. inst, MSM_VIDC_BUF_LINE) + 100000000;
  405. inst->buffers.dpb.size = call_session_op(core, buffer_size,
  406. inst, MSM_VIDC_BUF_DPB) + 100000000;
  407. //inst->buffers.vpss.size = call_session_op(core, buffer_size,
  408. //inst, MSM_VIDC_BUF_VPSS) + 100000000;
  409. //vpss is req - 100 mb
  410. /* inst->buffers.persist.size = call_session_op(core, buffer_size,
  411. inst, MSM_VIDC_BUF_PERSIST); */
  412. inst->buffers.arp.min_count = call_session_op(core, min_count,
  413. inst, MSM_VIDC_BUF_ARP);
  414. inst->buffers.bin.min_count = call_session_op(core, min_count,
  415. inst, MSM_VIDC_BUF_BIN);
  416. inst->buffers.comv.min_count = call_session_op(core, min_count,
  417. inst, MSM_VIDC_BUF_COMV);
  418. inst->buffers.non_comv.min_count = call_session_op(core, min_count,
  419. inst, MSM_VIDC_BUF_NON_COMV);
  420. inst->buffers.line.min_count = call_session_op(core, min_count,
  421. inst, MSM_VIDC_BUF_LINE);
  422. inst->buffers.dpb.min_count = call_session_op(core, min_count,
  423. inst, MSM_VIDC_BUF_DPB);
  424. /* inst->buffers.persist.min_count = call_session_op(core, min_count,
  425. inst, MSM_VIDC_BUF_PERSIST); */
  426. s_vpr_h(inst->sid, "internal buffer: min size\n");
  427. s_vpr_h(inst->sid, "arp buffer: %d %d\n",
  428. inst->buffers.arp.min_count,
  429. inst->buffers.arp.size);
  430. s_vpr_h(inst->sid, "bin buffer: %d %d\n",
  431. inst->buffers.bin.min_count,
  432. inst->buffers.bin.size);
  433. s_vpr_h(inst->sid, "comv buffer: %d %d\n",
  434. inst->buffers.comv.min_count,
  435. inst->buffers.comv.size);
  436. s_vpr_h(inst->sid, "non_comv buffer: %d %d\n",
  437. inst->buffers.non_comv.min_count,
  438. inst->buffers.non_comv.size);
  439. s_vpr_h(inst->sid, "line buffer: %d %d\n",
  440. inst->buffers.line.min_count,
  441. inst->buffers.line.size);
  442. s_vpr_h(inst->sid, "dpb buffer: %d %d\n",
  443. inst->buffers.dpb.min_count,
  444. inst->buffers.dpb.size);
  445. /* s_vpr_h(inst->sid, "persist buffer: %d %d\n",
  446. inst->buffers.persist.min_count,
  447. inst->buffers.persist.size); */
  448. return rc;
  449. }
  450. static int msm_venc_create_input_internal_buffers(struct msm_vidc_inst *inst)
  451. {
  452. int rc = 0;
  453. d_vpr_h("%s()\n", __func__);
  454. if (!inst || !inst->core) {
  455. d_vpr_e("%s: invalid params\n", __func__);
  456. return -EINVAL;
  457. }
  458. rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_ARP);
  459. if (rc)
  460. return rc;
  461. rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_BIN);
  462. if (rc)
  463. return rc;
  464. rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_COMV);
  465. if (rc)
  466. return rc;
  467. rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_NON_COMV);
  468. if (rc)
  469. return rc;
  470. rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_LINE);
  471. if (rc)
  472. return rc;
  473. rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_DPB);
  474. if (rc)
  475. return rc;
  476. /* rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_PERSIST);
  477. if (rc)
  478. return rc; */
  479. return 0;
  480. }
  481. static int msm_venc_queue_input_internal_buffers(struct msm_vidc_inst *inst)
  482. {
  483. int rc = 0;
  484. d_vpr_h("%s()\n", __func__);
  485. if (!inst || !inst->core) {
  486. d_vpr_e("%s: invalid params\n", __func__);
  487. return -EINVAL;
  488. }
  489. rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_ARP);
  490. if (rc)
  491. return rc;
  492. rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_BIN);
  493. if (rc)
  494. return rc;
  495. rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_COMV);
  496. if (rc)
  497. return rc;
  498. rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_NON_COMV);
  499. if (rc)
  500. return rc;
  501. rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_LINE);
  502. if (rc)
  503. return rc;
  504. rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_DPB);
  505. if (rc)
  506. return rc;
  507. // TODO: fw is not accepting persist buffer and returning session error.
  508. //rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_PERSIST);
  509. if (rc)
  510. return rc;
  511. return 0;
  512. }
  513. static int msm_venc_property_subscription(struct msm_vidc_inst *inst,
  514. enum msm_vidc_port_type port)
  515. {
  516. int rc = 0;
  517. struct msm_vidc_core *core;
  518. u32 payload[32] = {0};
  519. u32 i;
  520. u32 payload_size = 0;
  521. if (!inst || !inst->core) {
  522. d_vpr_e("%s: invalid params\n", __func__);
  523. return -EINVAL;
  524. }
  525. core = inst->core;
  526. d_vpr_h("%s()\n", __func__);
  527. payload[0] = HFI_MODE_PROPERTY;
  528. if (port == INPUT_PORT) {
  529. for (i = 0; i < ARRAY_SIZE(msm_venc_input_subscribe_for_properties); i++)
  530. payload[i + 1] = msm_venc_input_subscribe_for_properties[i];
  531. payload_size = (ARRAY_SIZE(msm_venc_input_subscribe_for_properties) + 1) *
  532. sizeof(u32);
  533. } else if (port == OUTPUT_PORT) {
  534. for (i = 0; i < ARRAY_SIZE(msm_venc_output_subscribe_for_properties); i++)
  535. payload[i + 1] = msm_venc_output_subscribe_for_properties[i];
  536. payload_size = (ARRAY_SIZE(msm_venc_output_subscribe_for_properties) + 1) *
  537. sizeof(u32);
  538. } else {
  539. s_vpr_e(inst->sid, "%s: invalid port: %d\n", __func__, port);
  540. return -EINVAL;
  541. }
  542. rc = venus_hfi_session_command(inst,
  543. HFI_CMD_SUBSCRIBE_MODE,
  544. port,
  545. HFI_PAYLOAD_U32_ARRAY,
  546. &payload[0],
  547. payload_size);
  548. return rc;
  549. }
  550. static int msm_venc_metadata_delivery(struct msm_vidc_inst *inst,
  551. enum msm_vidc_port_type port)
  552. {
  553. int rc = 0;
  554. struct msm_vidc_core *core;
  555. u32 payload[32] = {0};
  556. u32 i, count = 0;
  557. struct msm_vidc_inst_capability *capability;
  558. u32 metadata_list[] = {
  559. META_SEI_MASTERING_DISP,
  560. META_SEI_CLL,
  561. META_HDR10PLUS,
  562. META_EVA_STATS,
  563. META_BUF_TAG,
  564. META_ROI_INFO,
  565. };
  566. if (!inst || !inst->core) {
  567. d_vpr_e("%s: invalid params\n", __func__);
  568. return -EINVAL;
  569. }
  570. core = inst->core;
  571. d_vpr_h("%s()\n", __func__);
  572. capability = inst->capabilities;
  573. payload[0] = HFI_MODE_METADATA;
  574. for (i = 0; i < ARRAY_SIZE(metadata_list); i++) {
  575. if (capability->cap[metadata_list[i]].value) {
  576. payload[count + 1] =
  577. capability->cap[metadata_list[i]].hfi_id;
  578. count++;
  579. }
  580. };
  581. rc = venus_hfi_session_command(inst,
  582. HFI_CMD_DELIVERY_MODE,
  583. port,
  584. HFI_PAYLOAD_U32_ARRAY,
  585. &payload[0],
  586. (count + 1) * sizeof(u32));
  587. return rc;
  588. }
  589. static int msm_venc_metadata_subscription(struct msm_vidc_inst *inst,
  590. enum msm_vidc_port_type port)
  591. {
  592. int rc = 0;
  593. struct msm_vidc_core *core;
  594. u32 payload[32] = {0};
  595. u32 i, count = 0;
  596. struct msm_vidc_inst_capability *capability;
  597. u32 metadata_list[] = {
  598. META_LTR_MARK_USE,
  599. META_SEQ_HDR_NAL,
  600. META_TIMESTAMP,
  601. META_BUF_TAG,
  602. META_SUBFRAME_OUTPUT,
  603. META_ENC_QP_METADATA,
  604. };
  605. if (!inst || !inst->core) {
  606. d_vpr_e("%s: invalid params\n", __func__);
  607. return -EINVAL;
  608. }
  609. core = inst->core;
  610. d_vpr_h("%s()\n", __func__);
  611. capability = inst->capabilities;
  612. payload[0] = HFI_MODE_METADATA;
  613. for (i = 0; i < ARRAY_SIZE(metadata_list); i++) {
  614. if (capability->cap[metadata_list[i]].value) {
  615. payload[count + 1] =
  616. capability->cap[metadata_list[i]].hfi_id;
  617. count++;
  618. }
  619. };
  620. rc = venus_hfi_session_command(inst,
  621. HFI_CMD_SUBSCRIBE_MODE,
  622. port,
  623. HFI_PAYLOAD_U32_ARRAY,
  624. &payload[0],
  625. (count + 1) * sizeof(u32));
  626. return rc;
  627. }
  628. int msm_venc_streamoff_input(struct msm_vidc_inst *inst)
  629. {
  630. int rc = 0;
  631. if (!inst || !inst->core) {
  632. d_vpr_e("%s: invalid params\n", __func__);
  633. return -EINVAL;
  634. }
  635. rc = msm_vidc_session_streamoff(inst, INPUT_PORT);
  636. if (rc)
  637. return rc;
  638. return 0;
  639. }
  640. int msm_venc_streamon_input(struct msm_vidc_inst *inst)
  641. {
  642. int rc = 0;
  643. if (!inst || !inst->core) {
  644. d_vpr_e("%s: invalid params\n", __func__);
  645. return -EINVAL;
  646. }
  647. if (is_input_meta_enabled(inst) &&
  648. !inst->vb2q[INPUT_META_PORT].streaming) {
  649. s_vpr_e(inst->sid,
  650. "%s: Meta port must be streamed on before data port\n",
  651. __func__);
  652. return -EINVAL;
  653. }
  654. //rc = msm_vidc_check_session_supported(inst);
  655. if (rc)
  656. goto error;
  657. //rc = msm_vidc_check_scaling_supported(inst);
  658. if (rc)
  659. goto error;
  660. rc = msm_venc_set_input_properties(inst);
  661. if (rc)
  662. goto error;
  663. /* Decide bse vpp delay after work mode */
  664. //msm_vidc_set_bse_vpp_delay(inst);
  665. rc = msm_venc_get_input_internal_buffers(inst);
  666. if (rc)
  667. goto error;
  668. /* check for memory after all buffers calculation */
  669. //rc = msm_vidc_check_memory_supported(inst);
  670. if (rc)
  671. goto error;
  672. //msm_vidc_update_dcvs(inst);
  673. //msm_vidc_update_batching(inst);
  674. //msm_vidc_scale_power(inst);
  675. rc = msm_venc_create_input_internal_buffers(inst);
  676. rc = 0; // TODO
  677. if (rc)
  678. goto error;
  679. rc = msm_venc_queue_input_internal_buffers(inst);
  680. rc = 0; // TODO
  681. if (rc)
  682. goto error;
  683. rc = msm_venc_property_subscription(inst, INPUT_PORT);
  684. if (rc)
  685. return rc;
  686. rc = msm_venc_metadata_delivery(inst, INPUT_PORT);
  687. if (rc)
  688. return rc;
  689. rc = msm_vidc_session_streamon(inst, INPUT_PORT);
  690. if (rc)
  691. goto error;
  692. return 0;
  693. error:
  694. s_vpr_e(inst->sid, "%s: failed\n", __func__);
  695. msm_venc_streamoff_input(inst);
  696. return rc;
  697. }
  698. int msm_venc_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
  699. {
  700. int rc = 0;
  701. if (!inst || !inst->core) {
  702. d_vpr_e("%s: invalid params\n", __func__);
  703. return -EINVAL;
  704. }
  705. if (cmd == V4L2_ENC_CMD_STOP) {
  706. if (!msm_vidc_allow_stop(inst))
  707. return -EBUSY;
  708. rc = venus_hfi_session_command(inst,
  709. HFI_CMD_DRAIN,
  710. INPUT_PORT,
  711. HFI_PAYLOAD_NONE,
  712. NULL,
  713. 0);
  714. if (rc)
  715. return rc;
  716. rc = msm_vidc_state_change_stop(inst);
  717. if (rc)
  718. return rc;
  719. } else if (cmd == V4L2_ENC_CMD_START) {
  720. if (!msm_vidc_allow_start(inst))
  721. return -EBUSY;
  722. rc = msm_vidc_state_change_start(inst);
  723. if (rc)
  724. return rc;
  725. rc = venus_hfi_session_command(inst,
  726. HFI_CMD_RESUME,
  727. INPUT_PORT,
  728. HFI_PAYLOAD_NONE,
  729. NULL,
  730. 0);
  731. if (rc)
  732. return rc;
  733. } else {
  734. d_vpr_e("%s: unknown cmd %d\n", __func__, cmd);
  735. return -EINVAL;
  736. }
  737. return 0;
  738. }
  739. int msm_venc_streamoff_output(struct msm_vidc_inst *inst)
  740. {
  741. int rc = 0;
  742. if (!inst || !inst->core) {
  743. d_vpr_e("%s: invalid params\n", __func__);
  744. return -EINVAL;
  745. }
  746. rc = msm_vidc_session_streamoff(inst, OUTPUT_PORT);
  747. if (rc)
  748. return rc;
  749. return 0;
  750. }
  751. int msm_venc_streamon_output(struct msm_vidc_inst *inst)
  752. {
  753. int rc = 0;
  754. if (!inst || !inst->core) {
  755. d_vpr_e("%s: invalid params\n", __func__);
  756. return -EINVAL;
  757. }
  758. if (is_output_meta_enabled(inst) &&
  759. !inst->vb2q[OUTPUT_META_PORT].streaming) {
  760. s_vpr_e(inst->sid,
  761. "%s: Meta port must be streamed on before data port\n",
  762. __func__);
  763. return -EINVAL;
  764. }
  765. rc = msm_venc_set_output_properties(inst);
  766. if (rc)
  767. goto error;
  768. rc = msm_vidc_adjust_v4l2_properties(inst);
  769. if (rc)
  770. goto error;
  771. rc = msm_vidc_set_v4l2_properties(inst);
  772. if (rc)
  773. goto error;
  774. rc = msm_venc_set_internal_properties(inst);
  775. if (rc)
  776. goto error;
  777. rc = msm_venc_property_subscription(inst, OUTPUT_PORT);
  778. if (rc)
  779. goto error;
  780. rc = msm_venc_metadata_subscription(inst, OUTPUT_PORT);
  781. if (rc)
  782. goto error;
  783. rc = msm_vidc_session_streamon(inst, OUTPUT_PORT);
  784. if (rc)
  785. goto error;
  786. return 0;
  787. error:
  788. s_vpr_e(inst->sid, "%s: failed\n", __func__);
  789. msm_venc_streamoff_output(inst);
  790. return rc;
  791. }
  792. // TODO: use PIX_FMTS caps to check supported color format
  793. int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
  794. {
  795. int rc = 0;
  796. struct msm_vidc_core *core;
  797. struct v4l2_format *fmt;
  798. u32 codec_align;
  799. if (!inst || !inst->core) {
  800. d_vpr_e("%s: invalid params\n", __func__);
  801. return -EINVAL;
  802. }
  803. core = inst->core;
  804. if (f->type == INPUT_MPLANE) {
  805. fmt = &inst->fmts[INPUT_PORT];
  806. fmt->type = INPUT_MPLANE;
  807. fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
  808. fmt->fmt.pix_mp.width = VENUS_Y_STRIDE(
  809. v4l2_colorformat_to_media(fmt->fmt.pix_mp.pixelformat, __func__),
  810. f->fmt.pix_mp.width);
  811. fmt->fmt.pix_mp.height = VENUS_Y_SCANLINES(
  812. v4l2_colorformat_to_media(fmt->fmt.pix_mp.pixelformat, __func__),
  813. f->fmt.pix_mp.height);
  814. fmt->fmt.pix_mp.num_planes = 1;
  815. fmt->fmt.pix_mp.plane_fmt[0].bytesperline =
  816. fmt->fmt.pix_mp.width;
  817. fmt->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core,
  818. buffer_size, inst, MSM_VIDC_BUF_INPUT);
  819. inst->buffers.input.min_count = call_session_op(core,
  820. min_count, inst, MSM_VIDC_BUF_INPUT);
  821. inst->buffers.input.extra_count = call_session_op(core,
  822. extra_count, inst, MSM_VIDC_BUF_INPUT);
  823. if (inst->buffers.input.actual_count <
  824. inst->buffers.input.min_count +
  825. inst->buffers.input.extra_count) {
  826. inst->buffers.input.actual_count =
  827. inst->buffers.input.min_count +
  828. inst->buffers.input.extra_count;
  829. }
  830. inst->buffers.input.size =
  831. fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
  832. codec_align = inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat ==
  833. V4L2_PIX_FMT_HEVC ? 32 : 16;
  834. /* check if resolution changed */
  835. if (inst->fmts[OUTPUT_PORT].fmt.pix_mp.width !=
  836. ALIGN(f->fmt.pix_mp.width, codec_align) ||
  837. inst->fmts[OUTPUT_PORT].fmt.pix_mp.height !=
  838. ALIGN(f->fmt.pix_mp.height, codec_align)) {
  839. /* reset bitstream port with updated resolution */
  840. inst->fmts[OUTPUT_PORT].fmt.pix_mp.width =
  841. ALIGN(f->fmt.pix_mp.width, codec_align);
  842. inst->fmts[OUTPUT_PORT].fmt.pix_mp.height =
  843. ALIGN(f->fmt.pix_mp.height, codec_align);
  844. inst->fmts[OUTPUT_PORT].fmt.pix_mp.plane_fmt[0].sizeimage =
  845. call_session_op(core, buffer_size,
  846. inst, MSM_VIDC_BUF_OUTPUT);
  847. /* reset crop dimensions with updated resolution */
  848. inst->crop.top = inst->crop.left = 0;
  849. inst->crop.width = f->fmt.pix_mp.width;
  850. inst->crop.height = f->fmt.pix_mp.height;
  851. /* reset compose dimensions with updated resolution */
  852. inst->compose.top = inst->crop.left = 0;
  853. inst->compose.width = f->fmt.pix_mp.width;
  854. inst->compose.height = f->fmt.pix_mp.height;
  855. }
  856. //rc = msm_vidc_check_session_supported(inst);
  857. if (rc)
  858. goto err_invalid_fmt;
  859. //update_log_ctxt(inst->sid, inst->session_type,
  860. // mplane->pixelformat);
  861. s_vpr_h(inst->sid,
  862. "%s: input: codec %#x width %d height %d size %d min_count %d extra_count %d\n",
  863. __func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width,
  864. f->fmt.pix_mp.height,
  865. fmt->fmt.pix_mp.plane_fmt[0].sizeimage,
  866. inst->buffers.input.min_count,
  867. inst->buffers.input.extra_count);
  868. //msm_vidc_update_dcvs(inst);
  869. //msm_vidc_update_batching(inst);
  870. } else if (f->type == INPUT_META_PLANE) {
  871. fmt = &inst->fmts[INPUT_META_PORT];
  872. fmt->type = INPUT_META_PLANE;
  873. fmt->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  874. if (is_input_meta_enabled(inst)) {
  875. fmt->fmt.meta.buffersize = call_session_op(core,
  876. buffer_size, inst, MSM_VIDC_BUF_OUTPUT_META);
  877. inst->buffers.input_meta.min_count =
  878. inst->buffers.input.min_count;
  879. inst->buffers.input_meta.extra_count =
  880. inst->buffers.input.extra_count;
  881. inst->buffers.input_meta.actual_count =
  882. inst->buffers.input.actual_count;
  883. inst->buffers.input_meta.size = fmt->fmt.meta.buffersize;
  884. } else {
  885. fmt->fmt.meta.buffersize = 0;
  886. inst->buffers.input_meta.min_count = 0;
  887. inst->buffers.input_meta.extra_count = 0;
  888. inst->buffers.input_meta.actual_count = 0;
  889. inst->buffers.input_meta.size = 0;
  890. }
  891. s_vpr_h(inst->sid,
  892. "%s: input meta: size %d min_count %d extra_count %d\n",
  893. __func__, fmt->fmt.meta.buffersize,
  894. inst->buffers.input_meta.min_count,
  895. inst->buffers.input_meta.extra_count);
  896. } else if (f->type == OUTPUT_MPLANE) {
  897. fmt = &inst->fmts[OUTPUT_PORT];
  898. if (fmt->fmt.pix_mp.pixelformat != f->fmt.pix_mp.pixelformat) {
  899. s_vpr_e(inst->sid,
  900. "%s: codec changed from %#x to %#x\n", __func__,
  901. fmt->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat);
  902. rc = msm_venc_codec_change(inst, f->fmt.pix_mp.pixelformat);
  903. if (rc)
  904. goto err_invalid_fmt;
  905. }
  906. fmt->type = OUTPUT_MPLANE;
  907. codec_align = f->fmt.pix_mp.pixelformat ==
  908. V4L2_PIX_FMT_HEVC ? 32 : 16;
  909. /* width, height is readonly for client */
  910. fmt->fmt.pix_mp.width = ALIGN(inst->crop.width, codec_align);
  911. fmt->fmt.pix_mp.height = ALIGN(inst->crop.height, codec_align);
  912. fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
  913. fmt->fmt.pix_mp.num_planes = 1;
  914. fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
  915. fmt->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core,
  916. buffer_size, inst, MSM_VIDC_BUF_OUTPUT);
  917. inst->buffers.output.min_count = call_session_op(core,
  918. min_count, inst, MSM_VIDC_BUF_OUTPUT);
  919. inst->buffers.output.extra_count = call_session_op(core,
  920. extra_count, inst, MSM_VIDC_BUF_OUTPUT);
  921. if (inst->buffers.output.actual_count <
  922. inst->buffers.output.min_count +
  923. inst->buffers.output.extra_count) {
  924. inst->buffers.output.actual_count =
  925. inst->buffers.output.min_count +
  926. inst->buffers.output.extra_count;
  927. }
  928. inst->buffers.output.size =
  929. fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
  930. //rc = msm_vidc_check_session_supported(inst);
  931. if (rc)
  932. goto err_invalid_fmt;
  933. //update_log_ctxt(inst->sid, inst->session_type,
  934. // mplane->pixelformat);
  935. s_vpr_h(inst->sid,
  936. "%s: output: format %#x width %d height %d size %d min_count %d extra_count %d\n",
  937. __func__, fmt->fmt.pix_mp.pixelformat, fmt->fmt.pix_mp.width,
  938. fmt->fmt.pix_mp.height,
  939. fmt->fmt.pix_mp.plane_fmt[0].sizeimage,
  940. inst->buffers.output.min_count,
  941. inst->buffers.output.extra_count);
  942. } else if (f->type == OUTPUT_META_PLANE) {
  943. fmt = &inst->fmts[OUTPUT_META_PORT];
  944. fmt->type = OUTPUT_META_PLANE;
  945. fmt->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  946. if (is_output_meta_enabled(inst)) {
  947. fmt->fmt.meta.buffersize = call_session_op(core,
  948. buffer_size, inst, MSM_VIDC_BUF_OUTPUT_META);
  949. inst->buffers.output_meta.min_count =
  950. inst->buffers.output.min_count;
  951. inst->buffers.output_meta.extra_count =
  952. inst->buffers.output.extra_count;
  953. inst->buffers.output_meta.actual_count =
  954. inst->buffers.output.actual_count;
  955. inst->buffers.output_meta.size = fmt->fmt.meta.buffersize;
  956. } else {
  957. fmt->fmt.meta.buffersize = 0;
  958. inst->buffers.output_meta.min_count = 0;
  959. inst->buffers.output_meta.extra_count = 0;
  960. inst->buffers.output_meta.actual_count = 0;
  961. inst->buffers.output_meta.size = 0;
  962. }
  963. s_vpr_h(inst->sid,
  964. "%s: output meta: size %d min_count %d extra_count %d\n",
  965. __func__, fmt->fmt.meta.buffersize,
  966. inst->buffers.output_meta.min_count,
  967. inst->buffers.output_meta.extra_count);
  968. } else {
  969. s_vpr_e(inst->sid, "%s: invalid type %d\n", __func__, f->type);
  970. goto err_invalid_fmt;
  971. }
  972. memcpy(f, fmt, sizeof(struct v4l2_format));
  973. err_invalid_fmt:
  974. return rc;
  975. }
  976. int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
  977. {
  978. int rc = 0;
  979. int port;
  980. if (!inst) {
  981. d_vpr_e("%s: invalid params\n", __func__);
  982. return -EINVAL;
  983. }
  984. port = v4l2_type_to_driver_port(inst, f->type, __func__);
  985. if (port < 0)
  986. return -EINVAL;
  987. memcpy(f, &inst->fmts[port], sizeof(struct v4l2_format));
  988. return rc;
  989. }
  990. int msm_venc_s_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s)
  991. {
  992. int rc = 0;
  993. u32 codec_align;
  994. if (!inst || !s) {
  995. d_vpr_e("%s: invalid params\n", __func__);
  996. return -EINVAL;
  997. }
  998. if (s->type != INPUT_MPLANE && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
  999. s_vpr_e(inst->sid, "%s: invalid type %d\n", __func__, s->type);
  1000. return -EINVAL;
  1001. }
  1002. switch (s->target) {
  1003. case V4L2_SEL_TGT_CROP_BOUNDS:
  1004. case V4L2_SEL_TGT_CROP_DEFAULT:
  1005. case V4L2_SEL_TGT_CROP:
  1006. codec_align = inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat ==
  1007. V4L2_PIX_FMT_HEVC ? 32 : 16;
  1008. if (s->r.left || s->r.top) {
  1009. s_vpr_h(inst->sid, "%s: unsupported top %d or left %d\n",
  1010. __func__, s->r.left, s->r.top);
  1011. s->r.left = s->r.top = 0;
  1012. }
  1013. if (s->r.width > inst->fmts[OUTPUT_PORT].fmt.pix_mp.width ||
  1014. ALIGN(s->r.width, codec_align) != inst->fmts[OUTPUT_PORT].fmt.pix_mp.width) {
  1015. s_vpr_h(inst->sid, "%s: unsupported width %d, fmt width %d\n",
  1016. __func__, s->r.width,
  1017. inst->fmts[OUTPUT_PORT].fmt.pix_mp.width);
  1018. s->r.width = inst->fmts[OUTPUT_PORT].fmt.pix_mp.width;
  1019. }
  1020. if (s->r.height > inst->fmts[OUTPUT_PORT].fmt.pix_mp.height ||
  1021. ALIGN(s->r.height, codec_align) != inst->fmts[OUTPUT_PORT].fmt.pix_mp.height) {
  1022. s_vpr_h(inst->sid, "%s: unsupported height %d, fmt height %d\n",
  1023. __func__, s->r.height,
  1024. inst->fmts[OUTPUT_PORT].fmt.pix_mp.height);
  1025. s->r.height = inst->fmts[OUTPUT_PORT].fmt.pix_mp.height;
  1026. }
  1027. inst->crop.left = s->r.left;
  1028. inst->crop.top = s->r.top;
  1029. inst->crop.width = s->r.width;
  1030. inst->crop.height = s->r.height;
  1031. /* adjust compose such that it is within crop */
  1032. if (inst->compose.left < inst->crop.left)
  1033. inst->compose.left = inst->crop.left;
  1034. if (inst->compose.top < inst->crop.top)
  1035. inst->compose.top = inst->crop.top;
  1036. if (inst->compose.width > inst->crop.width)
  1037. inst->compose.width = inst->crop.width;
  1038. if (inst->compose.height > inst->crop.height)
  1039. inst->compose.height = inst->crop.height;
  1040. break;
  1041. case V4L2_SEL_TGT_COMPOSE_BOUNDS:
  1042. case V4L2_SEL_TGT_COMPOSE_PADDED:
  1043. case V4L2_SEL_TGT_COMPOSE_DEFAULT:
  1044. case V4L2_SEL_TGT_COMPOSE:
  1045. if (s->r.left < inst->crop.left) {
  1046. s_vpr_e(inst->sid,
  1047. "%s: compose left (%d) less than crop left (%d)\n",
  1048. __func__, s->r.left, inst->crop.left);
  1049. s->r.left = inst->crop.left;
  1050. }
  1051. if (s->r.top < inst->crop.top) {
  1052. s_vpr_e(inst->sid,
  1053. "%s: compose top (%d) less than crop top (%d)\n",
  1054. __func__, s->r.top, inst->crop.top);
  1055. s->r.top = inst->crop.top;
  1056. }
  1057. if (s->r.width > inst->crop.width) {
  1058. s_vpr_e(inst->sid,
  1059. "%s: compose width (%d) greate than crop width (%d)\n",
  1060. __func__, s->r.width, inst->crop.width);
  1061. s->r.width = inst->crop.width;
  1062. }
  1063. if (s->r.height > inst->crop.height) {
  1064. s_vpr_e(inst->sid,
  1065. "%s: compose height (%d) greate than crop height (%d)\n",
  1066. __func__, s->r.height, inst->crop.height);
  1067. s->r.height = inst->crop.height;
  1068. }
  1069. inst->compose.left = s->r.left;
  1070. inst->compose.top = s->r.top;
  1071. inst->compose.width = s->r.width;
  1072. inst->compose.height= s->r.height;
  1073. break;
  1074. default:
  1075. s_vpr_e(inst->sid, "%s: invalid target %d\n",
  1076. __func__, s->target);
  1077. rc = -EINVAL;
  1078. break;
  1079. }
  1080. if (!rc)
  1081. s_vpr_h(inst->sid, "%s: target %d, r [%d, %d, %d, %d]\n",
  1082. __func__, s->target, s->r.top, s->r.left,
  1083. s->r.width, s->r.height);
  1084. return rc;
  1085. }
  1086. int msm_venc_g_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s)
  1087. {
  1088. int rc = 0;
  1089. if (!inst || !s) {
  1090. d_vpr_e("%s: invalid params\n", __func__);
  1091. return -EINVAL;
  1092. }
  1093. if (s->type != INPUT_MPLANE && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
  1094. s_vpr_e(inst->sid, "%s: invalid type %d\n", __func__, s->type);
  1095. return -EINVAL;
  1096. }
  1097. switch (s->target) {
  1098. case V4L2_SEL_TGT_CROP_BOUNDS:
  1099. case V4L2_SEL_TGT_CROP_DEFAULT:
  1100. case V4L2_SEL_TGT_CROP:
  1101. s->r.left = inst->crop.left;
  1102. s->r.top = inst->crop.top;
  1103. s->r.width = inst->crop.width;
  1104. s->r.height = inst->crop.height;
  1105. break;
  1106. case V4L2_SEL_TGT_COMPOSE_BOUNDS:
  1107. case V4L2_SEL_TGT_COMPOSE_PADDED:
  1108. case V4L2_SEL_TGT_COMPOSE_DEFAULT:
  1109. case V4L2_SEL_TGT_COMPOSE:
  1110. s->r.left = inst->compose.left;
  1111. s->r.top = inst->compose.top;
  1112. s->r.width = inst->compose.width;
  1113. s->r.height = inst->compose.height;
  1114. break;
  1115. default:
  1116. s_vpr_e(inst->sid, "%s: invalid target %d\n",
  1117. __func__, s->target);
  1118. rc = -EINVAL;
  1119. break;
  1120. }
  1121. if (!rc)
  1122. s_vpr_h(inst->sid, "%s: target %d, r [%d, %d, %d, %d]\n",
  1123. __func__, s->target, s->r.top, s->r.left,
  1124. s->r.width, s->r.height);
  1125. return rc;
  1126. }
  1127. int msm_venc_s_param(struct msm_vidc_inst *inst,
  1128. struct v4l2_streamparm *s_parm)
  1129. {
  1130. int rc = 0;
  1131. struct msm_vidc_inst_capability *capability = NULL;
  1132. struct v4l2_fract *timeperframe = NULL;
  1133. u32 q16_rate, max_rate, default_rate;
  1134. u64 us_per_frame = 0, input_rate = 0;
  1135. bool is_frame_rate = false;
  1136. if (!inst || !s_parm) {
  1137. d_vpr_e("%s: invalid params\n", __func__);
  1138. return -EINVAL;
  1139. }
  1140. capability = inst->capabilities;
  1141. if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
  1142. timeperframe = &s_parm->parm.output.timeperframe;
  1143. max_rate = capability->cap[OPERATING_RATE].max;
  1144. default_rate = capability->cap[OPERATING_RATE].value;
  1145. } else {
  1146. timeperframe = &s_parm->parm.capture.timeperframe;
  1147. is_frame_rate = true;
  1148. max_rate = capability->cap[FRAME_RATE].value;
  1149. default_rate = capability->cap[FRAME_RATE].value;
  1150. }
  1151. if (!timeperframe->denominator || !timeperframe->numerator) {
  1152. s_vpr_e(inst->sid,
  1153. "%s: invalid rate for type %u\n",
  1154. __func__, s_parm->type);
  1155. input_rate = default_rate >> 16;
  1156. goto set_default;
  1157. }
  1158. us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;
  1159. do_div(us_per_frame, timeperframe->denominator);
  1160. if (!us_per_frame) {
  1161. s_vpr_e(inst->sid, "%s: us_per_frame is zero\n",
  1162. __func__);
  1163. rc = -EINVAL;
  1164. goto exit;
  1165. }
  1166. input_rate = (u64)USEC_PER_SEC;
  1167. do_div(input_rate, us_per_frame);
  1168. /* Check max allowed rate */
  1169. if (input_rate > max_rate) {
  1170. s_vpr_e(inst->sid,
  1171. "%s: Unsupported rate %u, max_fps %u, type: %u\n",
  1172. __func__, input_rate, max_rate, s_parm->type);
  1173. rc = -ENOTSUPP;
  1174. goto exit;
  1175. }
  1176. set_default:
  1177. q16_rate = (u32)input_rate << 16;
  1178. s_vpr_h(inst->sid, "%s: type %u value %#x\n",
  1179. __func__, s_parm->type, q16_rate);
  1180. if (!is_frame_rate) {
  1181. capability->cap[OPERATING_RATE].value = q16_rate;
  1182. goto exit;
  1183. } else {
  1184. capability->cap[FRAME_RATE].value = q16_rate;
  1185. }
  1186. /*
  1187. * In static case, frame rate is set during via
  1188. * inst database set function mentioned in
  1189. * FRAME_RATE cap id.
  1190. * In dynamic case, frame rate is set like below.
  1191. */
  1192. if (inst->vb2q[OUTPUT_PORT].streaming) {
  1193. rc = venus_hfi_session_property(inst,
  1194. HFI_PROP_FRAME_RATE,
  1195. HFI_HOST_FLAGS_NONE,
  1196. HFI_PORT_BITSTREAM,
  1197. HFI_PAYLOAD_Q16,
  1198. &q16_rate,
  1199. sizeof(u32));
  1200. if (rc) {
  1201. s_vpr_e(inst->sid,
  1202. "%s: failed to set frame rate to fw\n",
  1203. __func__);
  1204. goto exit;
  1205. }
  1206. }
  1207. exit:
  1208. return rc;
  1209. }
  1210. int msm_venc_g_param(struct msm_vidc_inst *inst,
  1211. struct v4l2_streamparm *s_parm)
  1212. {
  1213. struct msm_vidc_inst_capability *capability = NULL;
  1214. struct v4l2_fract *timeperframe = NULL;
  1215. if (!inst || !s_parm) {
  1216. d_vpr_e("%s: invalid params\n", __func__);
  1217. return -EINVAL;
  1218. }
  1219. capability = inst->capabilities;
  1220. if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
  1221. timeperframe = &s_parm->parm.output.timeperframe;
  1222. timeperframe->numerator = 1;
  1223. timeperframe->denominator =
  1224. capability->cap[OPERATING_RATE].value >> 16;
  1225. } else {
  1226. timeperframe = &s_parm->parm.capture.timeperframe;
  1227. timeperframe->numerator = 1;
  1228. timeperframe->denominator =
  1229. capability->cap[FRAME_RATE].value >> 16;
  1230. }
  1231. s_vpr_h(inst->sid, "%s: type %u, num %u denom %u\n",
  1232. __func__, s_parm->type, timeperframe->numerator,
  1233. timeperframe->denominator);
  1234. return 0;
  1235. }
  1236. int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
  1237. {
  1238. int rc = 0;
  1239. struct msm_vidc_core *core;
  1240. u32 array[32] = {0};
  1241. u32 i = 0, idx = 0;
  1242. if (!inst || !inst->core || !inst->capabilities || !f) {
  1243. d_vpr_e("%s: invalid params\n", __func__);
  1244. return -EINVAL;
  1245. }
  1246. core = inst->core;
  1247. if (f->type == OUTPUT_MPLANE) {
  1248. u32 codecs = core->capabilities[DEC_CODECS].value;
  1249. while (codecs) {
  1250. if (idx > 31)
  1251. break;
  1252. if (codecs & BIT(i)) {
  1253. array[idx] = codecs & BIT(i);
  1254. idx++;
  1255. }
  1256. i++;
  1257. codecs >>= 1;
  1258. }
  1259. f->pixelformat = v4l2_codec_from_driver(array[f->index],
  1260. __func__);
  1261. if (!f->pixelformat)
  1262. return -EINVAL;
  1263. f->flags = V4L2_FMT_FLAG_COMPRESSED;
  1264. strlcpy(f->description, "codec", sizeof(f->description));
  1265. } else if (f->type == INPUT_MPLANE) {
  1266. u32 formats = inst->capabilities->cap[PIX_FMTS].step_or_mask;
  1267. while (formats) {
  1268. if (idx > 31)
  1269. break;
  1270. if (formats & BIT(i)) {
  1271. array[idx] = formats & BIT(i);
  1272. idx++;
  1273. }
  1274. i++;
  1275. formats >>= 1;
  1276. }
  1277. f->pixelformat = v4l2_colorformat_from_driver(array[f->index],
  1278. __func__);
  1279. if (!f->pixelformat)
  1280. return -EINVAL;
  1281. strlcpy(f->description, "colorformat", sizeof(f->description));
  1282. } else if (f->type == INPUT_META_PLANE || f->type == OUTPUT_META_PLANE) {
  1283. if (!f->index) {
  1284. f->pixelformat = V4L2_META_FMT_VIDC;
  1285. strlcpy(f->description, "metadata", sizeof(f->description));
  1286. } else {
  1287. return -EINVAL;
  1288. }
  1289. }
  1290. memset(f->reserved, 0, sizeof(f->reserved));
  1291. s_vpr_h(inst->sid, "%s: index %d, %s : %#x, flags %#x\n",
  1292. __func__, f->index, f->description, f->pixelformat, f->flags);
  1293. return rc;
  1294. }
  1295. int msm_venc_inst_init(struct msm_vidc_inst *inst)
  1296. {
  1297. int rc = 0;
  1298. struct msm_vidc_core *core;
  1299. struct v4l2_format *f;
  1300. d_vpr_h("%s()\n", __func__);
  1301. if (!inst || !inst->core) {
  1302. d_vpr_e("%s: invalid params\n", __func__);
  1303. return -EINVAL;
  1304. }
  1305. core = inst->core;
  1306. f = &inst->fmts[OUTPUT_PORT];
  1307. f->type = OUTPUT_MPLANE;
  1308. f->fmt.pix_mp.width = DEFAULT_WIDTH;
  1309. f->fmt.pix_mp.height = DEFAULT_HEIGHT;
  1310. f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
  1311. f->fmt.pix_mp.num_planes = 1;
  1312. f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
  1313. f->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core,
  1314. buffer_size, inst, MSM_VIDC_BUF_OUTPUT);
  1315. inst->buffers.output.min_count = call_session_op(core,
  1316. min_count, inst, MSM_VIDC_BUF_OUTPUT);
  1317. inst->buffers.output.extra_count = call_session_op(core,
  1318. extra_count, inst, MSM_VIDC_BUF_OUTPUT);
  1319. inst->buffers.output.actual_count =
  1320. inst->buffers.output.min_count +
  1321. inst->buffers.output.extra_count;
  1322. inst->buffers.output.size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
  1323. inst->crop.left = inst->crop.top = 0;
  1324. inst->crop.width = f->fmt.pix_mp.width;
  1325. inst->crop.height = f->fmt.pix_mp.height;
  1326. f = &inst->fmts[OUTPUT_META_PORT];
  1327. f->type = OUTPUT_META_PLANE;
  1328. f->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  1329. f->fmt.meta.buffersize = call_session_op(core, buffer_size,
  1330. inst, MSM_VIDC_BUF_OUTPUT_META);
  1331. inst->buffers.output_meta.min_count = inst->buffers.output.min_count;
  1332. inst->buffers.output_meta.extra_count = inst->buffers.output.extra_count;
  1333. inst->buffers.output_meta.actual_count = inst->buffers.output.actual_count;
  1334. inst->buffers.output_meta.size = f->fmt.meta.buffersize;
  1335. f = &inst->fmts[INPUT_PORT];
  1336. f->type = INPUT_MPLANE;
  1337. f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VIDC_NV12C;
  1338. f->fmt.pix_mp.width = VENUS_Y_STRIDE(
  1339. v4l2_colorformat_to_media(f->fmt.pix_mp.pixelformat, __func__),
  1340. DEFAULT_WIDTH);
  1341. f->fmt.pix_mp.height = VENUS_Y_SCANLINES(
  1342. v4l2_colorformat_to_media(f->fmt.pix_mp.pixelformat, __func__),
  1343. DEFAULT_HEIGHT);
  1344. f->fmt.pix_mp.num_planes = 1;
  1345. f->fmt.pix_mp.plane_fmt[0].bytesperline = f->fmt.pix_mp.width;
  1346. f->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core,
  1347. buffer_size, inst, MSM_VIDC_BUF_INPUT);
  1348. inst->buffers.input.min_count = call_session_op(core,
  1349. min_count, inst, MSM_VIDC_BUF_INPUT);
  1350. inst->buffers.input.extra_count = call_session_op(core,
  1351. extra_count, inst, MSM_VIDC_BUF_INPUT);
  1352. inst->buffers.input.actual_count =
  1353. inst->buffers.input.min_count +
  1354. inst->buffers.input.extra_count;
  1355. inst->buffers.input.size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
  1356. f = &inst->fmts[INPUT_META_PORT];
  1357. f->type = INPUT_META_PLANE;
  1358. f->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  1359. f->fmt.meta.buffersize = call_session_op(core, buffer_size,
  1360. inst, MSM_VIDC_BUF_INPUT_META);
  1361. inst->buffers.input_meta.min_count = inst->buffers.input.min_count;
  1362. inst->buffers.input_meta.extra_count = inst->buffers.input.extra_count;
  1363. inst->buffers.input_meta.actual_count = inst->buffers.input.actual_count;
  1364. inst->buffers.input_meta.size = f->fmt.meta.buffersize;
  1365. rc = msm_venc_codec_change(inst,
  1366. inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat);
  1367. return rc;
  1368. }
  1369. int msm_venc_inst_deinit(struct msm_vidc_inst *inst)
  1370. {
  1371. int rc = 0;
  1372. if (!inst) {
  1373. d_vpr_e("%s: invalid params\n", __func__);
  1374. return -EINVAL;
  1375. }
  1376. rc = msm_vidc_ctrl_deinit(inst);
  1377. return rc;
  1378. }