msm_vidc_control.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  4. */
  5. #include "msm_vidc_control.h"
  6. #include "msm_vidc_debug.h"
  7. #include "hfi_packet.h"
  8. #include "hfi_property.h"
  9. #include "venus_hfi.h"
  10. #include "msm_vidc_internal.h"
  11. #include "msm_vidc_driver.h"
  12. static bool is_priv_ctrl(u32 id)
  13. {
  14. if (IS_PRIV_CTRL(id))
  15. return true;
  16. /*
  17. * Treat below standard controls as private because
  18. * we have added custom values to the controls
  19. */
  20. return false;
  21. }
  22. static const char *const mpeg_video_rate_control[] = {
  23. "VBR",
  24. "CBR",
  25. "CBR VFR",
  26. "MBR",
  27. "MBR VFR",
  28. "CQ",
  29. NULL,
  30. };
  31. static const char *const mpeg_video_stream_format[] = {
  32. "NAL Format Start Codes",
  33. "NAL Format One NAL Per Buffer",
  34. "NAL Format One Byte Length",
  35. "NAL Format Two Byte Length",
  36. "NAL Format Four Byte Length",
  37. NULL,
  38. };
  39. static const char *const mpeg_video_blur_types[] = {
  40. "Blur None",
  41. "Blur External",
  42. "Blur Adaptive",
  43. NULL,
  44. };
  45. static const char *const roi_map_type[] = {
  46. "None",
  47. "2-bit",
  48. "2-bit",
  49. NULL,
  50. };
  51. static u32 msm_vidc_get_port_info(struct msm_vidc_inst *inst,
  52. enum msm_vidc_inst_capability_type cap_id)
  53. {
  54. struct msm_vidc_inst_capability *capability = inst->capabilities;
  55. if (capability->cap[cap_id].flags & CAP_FLAG_INPUT_PORT &&
  56. capability->cap[cap_id].flags & CAP_FLAG_OUTPUT_PORT) {
  57. s_vpr_e(inst->sid,
  58. "%s: both ports enabled. Default port set: BITSTREAM\n",
  59. __func__);
  60. return HFI_PORT_BITSTREAM;
  61. }
  62. if (capability->cap[cap_id].flags & CAP_FLAG_INPUT_PORT)
  63. return get_hfi_port(inst, INPUT_PORT);
  64. else if (capability->cap[cap_id].flags & CAP_FLAG_OUTPUT_PORT)
  65. return get_hfi_port(inst, OUTPUT_PORT);
  66. else
  67. return HFI_PORT_NONE;
  68. }
  69. static const char * const * msm_vidc_get_qmenu_type(
  70. struct msm_vidc_inst *inst, u32 control_id)
  71. {
  72. switch (control_id) {
  73. case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
  74. return mpeg_video_rate_control;
  75. case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:
  76. return mpeg_video_stream_format;
  77. case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_TYPES:
  78. return mpeg_video_blur_types;
  79. default:
  80. s_vpr_e(inst->sid, "%s: No available qmenu for ctrl %#x\n",
  81. __func__, control_id);
  82. return NULL;
  83. }
  84. }
  85. static const char *msm_vidc_get_priv_ctrl_name(u32 sid, u32 control_id)
  86. {
  87. switch (control_id) {
  88. case V4L2_CID_MPEG_VIDC_SECURE:
  89. return "Secure Mode";
  90. case V4L2_CID_MPEG_VIDC_HEIC:
  91. return "HEIC";
  92. case V4L2_CID_MPEG_VIDC_LOWLATENCY_REQUEST:
  93. return "Low Latency Mode";
  94. case V4L2_CID_MPEG_VIDC_CODEC_CONFIG:
  95. return "Codec Config";
  96. case V4L2_CID_MPEG_VIDC_B_FRAME_MIN_QP:
  97. return "B frame Min QP";
  98. case V4L2_CID_MPEG_VIDC_B_FRAME_MAX_QP:
  99. return "B frame Max QP";
  100. case V4L2_CID_MPEG_VIDC_LTRCOUNT:
  101. return "LTR count";
  102. case V4L2_CID_MPEG_VIDC_USELTRFRAME:
  103. return "Use LTR Frame";
  104. case V4L2_CID_MPEG_VIDC_MARKLTRFRAME:
  105. return "Mark LTR Frame";
  106. case V4L2_CID_MPEG_VIDC_BASELAYER_PRIORITY:
  107. return "Baselayer Priority";
  108. case V4L2_CID_MPEG_VIDC_INTRA_REFRESH_PERIOD:
  109. return "Intra Refresh Period";
  110. case V4L2_CID_MPEG_VIDC_AU_DELIMITER:
  111. return "AU Delimiter";
  112. case V4L2_CID_MPEG_VIDC_TIME_DELTA_BASED_RC:
  113. return "Time Delta Based RC";
  114. case V4L2_CID_MPEG_VIDC_CONTENT_ADAPTIVE_CODING:
  115. return "Content Adaptive Coding";
  116. case V4L2_CID_MPEG_VIDC_QUALITY_BITRATE_BOOST:
  117. return "Quality Bitrate Boost";
  118. case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_TYPES:
  119. return "Blur Types";
  120. case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_RESOLUTION:
  121. return "Blur Resolution";
  122. case V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_CUSTOM_MATRIX:
  123. return "CSC Custom Matrix";
  124. case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY:
  125. return "H264 Display Delay";
  126. case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE:
  127. return "H264 Display Delay Enable";
  128. case V4L2_CID_MPEG_VIDC_METADATA_LTR_MARK_USE_DETAILS:
  129. return "LTR Mark Use Details Metadata";
  130. case V4L2_CID_MPEG_VIDC_METADATA_SEQ_HEADER_NAL:
  131. return "Seq Header NAL Metadata";
  132. case V4L2_CID_MPEG_VIDC_METADATA_DPB_LUMA_CHROMA_MISR:
  133. return "DPB Luma-Chroma MISR Metadata";
  134. case V4L2_CID_MPEG_VIDC_METADATA_OPB_LUMA_CHROMA_MISR:
  135. return "OPB Luma-Chroma MISR Metadata";
  136. case V4L2_CID_MPEG_VIDC_METADATA_INTERLACE:
  137. return "Interlace Metadata";
  138. case V4L2_CID_MPEG_VIDC_METADATA_CONCEALED_MB_COUNT:
  139. return "Concealed MB Count Metadata";
  140. case V4L2_CID_MPEG_VIDC_METADATA_HISTOGRAM_INFO:
  141. return "Historgram Info Metadata";
  142. case V4L2_CID_MPEG_VIDC_METADATA_SEI_MASTERING_DISPLAY_COLOUR:
  143. return "SEI Mastering Display Color Metadata";
  144. case V4L2_CID_MPEG_VIDC_METADATA_SEI_CONTENT_LIGHT_LEVEL:
  145. return "SEI Content Lighting Level Metadata";
  146. case V4L2_CID_MPEG_VIDC_METADATA_HDR10PLUS:
  147. return "HDR10PLUS Metadata";
  148. case V4L2_CID_MPEG_VIDC_METADATA_EVA_STATS:
  149. return "EVA Stats Metadata";
  150. case V4L2_CID_MPEG_VIDC_METADATA_BUFFER_TAG:
  151. return "Buffer Tag Metadata";
  152. case V4L2_CID_MPEG_VIDC_METADATA_SUBFRAME_OUTPUT:
  153. return "Subframe Output Metadata";
  154. case V4L2_CID_MPEG_VIDC_METADATA_ROI_INFO:
  155. return "ROI Info Metadata";
  156. default:
  157. s_vpr_e(sid, "%s: ctrl name not available for ctrl id %#x\n",
  158. __func__, control_id);
  159. return NULL;
  160. }
  161. }
  162. static int msm_vidc_packetize_control(struct msm_vidc_inst *inst,
  163. enum msm_vidc_inst_capability_type cap_id, u32 payload_type,
  164. void *hfi_val, u32 payload_size, const char *func)
  165. {
  166. int rc = 0;
  167. s_vpr_l(inst->sid,
  168. "%s: hfi_id: %#x, value: %#x\n", func,
  169. inst->capabilities->cap[cap_id].hfi_id,
  170. *(s64 *)hfi_val);
  171. rc = venus_hfi_session_property(inst,
  172. inst->capabilities->cap[cap_id].hfi_id,
  173. HFI_HOST_FLAGS_NONE,
  174. msm_vidc_get_port_info(inst, cap_id),
  175. payload_type,
  176. hfi_val,
  177. sizeof(payload_size));
  178. if (rc)
  179. s_vpr_e(inst->sid,
  180. "%s: failed to set cap_id: %d to fw\n",
  181. __func__, cap_id);
  182. return rc;
  183. }
  184. static enum msm_vidc_inst_capability_type msm_vidc_get_cap_id(
  185. struct msm_vidc_inst *inst, u32 id)
  186. {
  187. enum msm_vidc_inst_capability_type i = INST_CAP_NONE + 1;
  188. struct msm_vidc_inst_capability *capability;
  189. enum msm_vidc_inst_capability_type cap_id = INST_CAP_NONE;
  190. capability = inst->capabilities;
  191. do {
  192. if (capability->cap[i].v4l2_id == id) {
  193. cap_id = capability->cap[i].cap;
  194. break;
  195. }
  196. i++;
  197. } while (i < INST_CAP_MAX);
  198. return cap_id;
  199. }
  200. static int msm_vidc_add_capid_to_list(struct msm_vidc_inst *inst,
  201. enum msm_vidc_inst_capability_type cap_id,
  202. enum msm_vidc_ctrl_list_type type)
  203. {
  204. struct msm_vidc_inst_cap_entry *entry = NULL, *curr_node = NULL;
  205. /* skip adding if cap_id already present in list */
  206. if (type & FW_LIST) {
  207. list_for_each_entry(curr_node, &inst->firmware.list, list) {
  208. if (curr_node->cap_id == cap_id) {
  209. s_vpr_e(inst->sid,
  210. "%s: cap %d cannot be the child of two parents\n",
  211. __func__, cap_id);
  212. return 0;
  213. }
  214. }
  215. }
  216. entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
  217. if (!entry) {
  218. s_vpr_e(inst->sid, "%s: alloc failed\n", __func__);
  219. return -ENOMEM;
  220. }
  221. entry->cap_id = cap_id;
  222. if (type & CHILD_LIST)
  223. list_add_tail(&entry->list, &inst->children.list);
  224. if (type & FW_LIST)
  225. list_add_tail(&entry->list, &inst->firmware.list);
  226. return 0;
  227. }
  228. static int msm_vidc_add_children(struct msm_vidc_inst *inst,
  229. enum msm_vidc_inst_capability_type cap_id)
  230. {
  231. int rc = 0;
  232. int i = 0;
  233. struct msm_vidc_inst_capability *capability = inst->capabilities;
  234. while (i < MAX_CAP_CHILDREN &&
  235. capability->cap[cap_id].children[i]) {
  236. rc = msm_vidc_add_capid_to_list(inst,
  237. capability->cap[cap_id].children[i],
  238. CHILD_LIST);
  239. if (rc)
  240. return rc;
  241. i++;
  242. }
  243. return rc;
  244. }
  245. static int msm_vidc_adjust_property(struct msm_vidc_inst *inst,
  246. enum msm_vidc_inst_capability_type cap_id)
  247. {
  248. int rc = 0;
  249. struct msm_vidc_inst_capability *capability;
  250. capability = inst->capabilities;
  251. /*
  252. * skip for uninitialized cap properties.
  253. * Eg: Skip Tramform 8x8 cap that is uninitialized for HEVC codec
  254. */
  255. if (!capability->cap[cap_id].cap)
  256. return 0;
  257. if (capability->cap[cap_id].adjust) {
  258. rc = capability->cap[cap_id].adjust(inst, NULL);
  259. if (rc)
  260. goto exit;
  261. }
  262. /* add children cap_id's to chidren list */
  263. rc = msm_vidc_add_children(inst, cap_id);
  264. if (rc)
  265. goto exit;
  266. /* add cap_id to firmware list */
  267. rc = msm_vidc_add_capid_to_list(inst, cap_id, FW_LIST);
  268. if (rc)
  269. goto exit;
  270. return 0;
  271. exit:
  272. return rc;
  273. }
  274. static int msm_vidc_adjust_dynamic_property(struct msm_vidc_inst *inst,
  275. enum msm_vidc_inst_capability_type cap_id, struct v4l2_ctrl *ctrl)
  276. {
  277. int rc = 0;
  278. struct msm_vidc_inst_capability *capability;
  279. s32 prev_value;
  280. capability = inst->capabilities;
  281. /*
  282. * ctrl is NULL for children adjustment calls
  283. * When a dynamic control having children is adjusted, check if dynamic
  284. * adjustment is allowed for its children.
  285. */
  286. if (!(capability->cap[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED)) {
  287. s_vpr_e(inst->sid,
  288. "%s: dynamic setting of cap_id %d is not allowed\n",
  289. __func__, cap_id);
  290. msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
  291. return -EINVAL;
  292. }
  293. /*
  294. * if ctrl is NULL, it is children of some parent, and hence,
  295. * must have an adjust function defined
  296. */
  297. if (!ctrl && !capability->cap[cap_id].adjust) {
  298. s_vpr_e(inst->sid,
  299. "%s: child cap %d must have ajdust function\n",
  300. __func__, capability->cap[cap_id].cap);
  301. return -EINVAL;
  302. }
  303. prev_value = capability->cap[cap_id].value;
  304. if (capability->cap[cap_id].adjust) {
  305. rc = capability->cap[cap_id].adjust(inst, ctrl);
  306. if (rc)
  307. goto exit;
  308. } else if (ctrl) {
  309. capability->cap[cap_id].value = ctrl->val;
  310. }
  311. /* add children if cap value modified */
  312. if (capability->cap[cap_id].value != prev_value) {
  313. rc = msm_vidc_add_children(inst, cap_id);
  314. if (rc)
  315. goto exit;
  316. }
  317. /* add cap_id to firmware list always */
  318. rc = msm_vidc_add_capid_to_list(inst, cap_id, FW_LIST);
  319. if (rc)
  320. goto exit;
  321. return 0;
  322. exit:
  323. return rc;
  324. }
  325. int msm_vidc_ctrl_deinit(struct msm_vidc_inst *inst)
  326. {
  327. if (!inst) {
  328. d_vpr_e("%s: invalid parameters\n", __func__);
  329. return -EINVAL;
  330. }
  331. s_vpr_h(inst->sid, "%s(): num ctrls %d\n", __func__, inst->num_ctrls);
  332. v4l2_ctrl_handler_free(&inst->ctrl_handler);
  333. kfree(inst->ctrls);
  334. return 0;
  335. }
  336. int msm_vidc_ctrl_init(struct msm_vidc_inst *inst)
  337. {
  338. int rc = 0;
  339. struct msm_vidc_inst_capability *capability;
  340. struct msm_vidc_core *core;
  341. int idx = 0;
  342. struct v4l2_ctrl_config ctrl_cfg = {0};
  343. int num_ctrls = 0, ctrl_idx = 0;
  344. if (!inst || !inst->core || !inst->capabilities) {
  345. d_vpr_e("%s: invalid params\n", __func__);
  346. return -EINVAL;
  347. }
  348. core = inst->core;
  349. capability = inst->capabilities;
  350. if (!core->v4l2_ctrl_ops) {
  351. s_vpr_e(inst->sid, "%s: no control ops\n", __func__);
  352. return -EINVAL;
  353. }
  354. for (idx = 0; idx < INST_CAP_MAX; idx++) {
  355. if (capability->cap[idx].v4l2_id)
  356. num_ctrls++;
  357. }
  358. if (!num_ctrls) {
  359. s_vpr_e(inst->sid, "%s: no ctrls available in cap database\n",
  360. __func__);
  361. return -EINVAL;
  362. }
  363. inst->ctrls = kcalloc(num_ctrls,
  364. sizeof(struct v4l2_ctrl *), GFP_KERNEL);
  365. if (!inst->ctrls) {
  366. s_vpr_e(inst->sid, "%s: failed to allocate ctrl\n", __func__);
  367. return -ENOMEM;
  368. }
  369. rc = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls);
  370. if (rc) {
  371. s_vpr_e(inst->sid, "control handler init failed, %d\n",
  372. inst->ctrl_handler.error);
  373. return rc;
  374. }
  375. for (idx = 0; idx < INST_CAP_MAX; idx++) {
  376. struct v4l2_ctrl *ctrl;
  377. if (!capability->cap[idx].v4l2_id)
  378. continue;
  379. if (ctrl_idx >= num_ctrls) {
  380. s_vpr_e(inst->sid,
  381. "%s: invalid ctrl %#x, max allowed %d\n",
  382. __func__, capability->cap[idx].v4l2_id,
  383. num_ctrls);
  384. return -EINVAL;
  385. }
  386. s_vpr_h(inst->sid,
  387. "%s: cap idx %d, value %d min %d max %d step_or_mask %#x flags %#x v4l2_id %#x hfi_id %#x\n",
  388. __func__, idx,
  389. capability->cap[idx].value,
  390. capability->cap[idx].min,
  391. capability->cap[idx].max,
  392. capability->cap[idx].step_or_mask,
  393. capability->cap[idx].flags,
  394. capability->cap[idx].v4l2_id,
  395. capability->cap[idx].hfi_id);
  396. memset(&ctrl_cfg, 0, sizeof(struct v4l2_ctrl_config));
  397. if (is_priv_ctrl(capability->cap[idx].v4l2_id)) {
  398. /* add private control */
  399. ctrl_cfg.def = capability->cap[idx].value;
  400. ctrl_cfg.flags = 0;
  401. ctrl_cfg.id = capability->cap[idx].v4l2_id;
  402. ctrl_cfg.max = capability->cap[idx].max;
  403. ctrl_cfg.min = capability->cap[idx].min;
  404. ctrl_cfg.ops = core->v4l2_ctrl_ops;
  405. ctrl_cfg.type = (capability->cap[idx].flags &
  406. CAP_FLAG_MENU) ?
  407. V4L2_CTRL_TYPE_MENU :
  408. V4L2_CTRL_TYPE_INTEGER;
  409. if (ctrl_cfg.type == V4L2_CTRL_TYPE_MENU) {
  410. ctrl_cfg.menu_skip_mask =
  411. ~(capability->cap[idx].step_or_mask);
  412. ctrl_cfg.qmenu = msm_vidc_get_qmenu_type(inst,
  413. capability->cap[idx].v4l2_id);
  414. } else {
  415. ctrl_cfg.step =
  416. capability->cap[idx].step_or_mask;
  417. }
  418. ctrl_cfg.name = msm_vidc_get_priv_ctrl_name(inst->sid,
  419. capability->cap[idx].v4l2_id);
  420. if (!ctrl_cfg.name) {
  421. s_vpr_e(inst->sid, "%s: %#x ctrl name is null\n",
  422. __func__, ctrl_cfg.id);
  423. return -EINVAL;
  424. }
  425. ctrl = v4l2_ctrl_new_custom(&inst->ctrl_handler,
  426. &ctrl_cfg, NULL);
  427. } else {
  428. if (capability->cap[idx].flags & CAP_FLAG_MENU) {
  429. ctrl = v4l2_ctrl_new_std_menu(
  430. &inst->ctrl_handler,
  431. core->v4l2_ctrl_ops,
  432. capability->cap[idx].v4l2_id,
  433. capability->cap[idx].max,
  434. ~(capability->cap[idx].step_or_mask),
  435. capability->cap[idx].value);
  436. } else {
  437. ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
  438. core->v4l2_ctrl_ops,
  439. capability->cap[idx].v4l2_id,
  440. capability->cap[idx].min,
  441. capability->cap[idx].max,
  442. capability->cap[idx].step_or_mask,
  443. capability->cap[idx].value);
  444. }
  445. }
  446. if (!ctrl) {
  447. s_vpr_e(inst->sid, "%s: invalid ctrl %#x\n", __func__,
  448. capability->cap[idx].v4l2_id);
  449. return -EINVAL;
  450. }
  451. rc = inst->ctrl_handler.error;
  452. if (rc) {
  453. s_vpr_e(inst->sid,
  454. "error adding ctrl (%#x) to ctrl handle, %d\n",
  455. capability->cap[idx].v4l2_id,
  456. inst->ctrl_handler.error);
  457. return rc;
  458. }
  459. /*
  460. * TODO(AS)
  461. * ctrl->flags |= capability->cap[idx].flags;
  462. */
  463. ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
  464. inst->ctrls[ctrl_idx] = ctrl;
  465. ctrl_idx++;
  466. }
  467. inst->num_ctrls = num_ctrls;
  468. s_vpr_h(inst->sid, "%s(): num ctrls %d\n", __func__, inst->num_ctrls);
  469. return rc;
  470. }
  471. int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl)
  472. {
  473. int rc = 0;
  474. struct msm_vidc_inst *inst;
  475. enum msm_vidc_inst_capability_type cap_id;
  476. struct msm_vidc_inst_cap_entry *curr_node = NULL, *tmp_node = NULL;
  477. struct msm_vidc_inst_capability *capability;
  478. if (!ctrl) {
  479. d_vpr_e("%s: invalid ctrl parameter\n", __func__);
  480. return -EINVAL;
  481. }
  482. inst = container_of(ctrl->handler,
  483. struct msm_vidc_inst, ctrl_handler);
  484. if (!inst || !inst->capabilities) {
  485. d_vpr_e("%s: invalid parameters for inst\n", __func__);
  486. return -EINVAL;
  487. }
  488. if (inst->state == MSM_VIDC_ERROR) {
  489. s_vpr_e(inst->sid, "%s: set ctrl not allowed in error state\n");
  490. /* (error name TBD); */
  491. return -EINVAL;
  492. }
  493. capability = inst->capabilities;
  494. s_vpr_h(inst->sid, "%s: state %d, name %s, id 0x%x value %d\n",
  495. __func__, inst->state, ctrl->name, ctrl->id, ctrl->val);
  496. cap_id = msm_vidc_get_cap_id(inst, ctrl->id);
  497. if (cap_id == INST_CAP_NONE) {
  498. s_vpr_e(inst->sid, "%s: could not find cap_id for ctrl %s\n",
  499. __func__, ctrl->name);
  500. return -EINVAL;
  501. }
  502. /* Static setting */
  503. if (!inst->vb2q[OUTPUT_PORT].streaming) {
  504. capability->cap[cap_id].value = ctrl->val;
  505. return 0;
  506. }
  507. /* check if dynamic adjustment is allowed */
  508. if (inst->vb2q[OUTPUT_PORT].streaming &&
  509. !(capability->cap[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED)) {
  510. s_vpr_e(inst->sid,
  511. "%s: dynamic setting of cap_id %d is not allowed\n",
  512. __func__, cap_id);
  513. return -EBUSY;
  514. }
  515. rc = msm_vidc_adjust_dynamic_property(inst, cap_id, ctrl);
  516. if (rc)
  517. goto exit;
  518. /* adjust all children if any */
  519. list_for_each_entry_safe(curr_node, tmp_node,
  520. &inst->children.list, list) {
  521. rc = msm_vidc_adjust_dynamic_property(
  522. inst, curr_node->cap_id, NULL);
  523. if (rc)
  524. goto exit;
  525. list_del(&curr_node->list);
  526. kfree(curr_node);
  527. }
  528. /* dynamic controls with request will be set along with qbuf */
  529. if (inst->request)
  530. return 0;
  531. /* Dynamic set control ASAP */
  532. rc = msm_vidc_set_v4l2_properties(inst);
  533. if (rc) {
  534. s_vpr_e(inst->sid, "%s: setting %s failed\n",
  535. __func__, ctrl->name);
  536. goto exit;
  537. }
  538. exit:
  539. return rc;
  540. }
  541. int msm_vidc_adjust_entropy_mode(void *instance, struct v4l2_ctrl *ctrl)
  542. {
  543. int rc = 0;
  544. struct msm_vidc_inst_capability *capability;
  545. s32 adjusted_value;
  546. struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
  547. s32 profile = -1;
  548. if (!inst || !inst->capabilities) {
  549. d_vpr_e("%s: invalid params\n", __func__);
  550. return -EINVAL;
  551. }
  552. capability = inst->capabilities;
  553. /* ctrl is always NULL in streamon case */
  554. if (ctrl)
  555. adjusted_value = ctrl->val;
  556. else
  557. adjusted_value = capability->cap[ENTROPY_MODE].value;
  558. if (inst->codec != MSM_VIDC_H264) {
  559. s_vpr_e(inst->sid,
  560. "%s: incorrect entry in database. fix the database\n",
  561. __func__);
  562. return 0;
  563. }
  564. profile = capability->cap[PROFILE].value;
  565. if (profile == V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE ||
  566. profile == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)
  567. adjusted_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
  568. if (capability->cap[ENTROPY_MODE].value != adjusted_value) {
  569. s_vpr_h(inst->sid, "%s: updated from %#x to adjusted %#x\n", __func__,
  570. capability->cap[ENTROPY_MODE].value, adjusted_value);
  571. capability->cap[ENTROPY_MODE].value = adjusted_value;
  572. }
  573. return rc;
  574. }
  575. int msm_vidc_adjust_profile(void *instance, struct v4l2_ctrl *ctrl)
  576. {
  577. int rc = 0;
  578. int i = 0;
  579. struct msm_vidc_inst_capability *capability;
  580. s32 adjusted_value;
  581. enum msm_vidc_inst_capability_type parent_id;
  582. struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
  583. s32 pix_fmt = -1;
  584. if (!inst || !inst->capabilities) {
  585. d_vpr_e("%s: invalid params\n", __func__);
  586. return -EINVAL;
  587. }
  588. capability = inst->capabilities;
  589. /* ctrl is always NULL in streamon case */
  590. if (ctrl)
  591. adjusted_value = ctrl->val;
  592. else
  593. adjusted_value = capability->cap[PROFILE].value;
  594. /* TODO(AS): Create a utility for this while loop and add
  595. * detailed comments within for utility functionality
  596. */
  597. while (i < MAX_CAP_PARENTS &&
  598. capability->cap[PROFILE].parents[i]) {
  599. parent_id = capability->cap[PROFILE].parents[i];
  600. if (parent_id == PIX_FMTS) {
  601. pix_fmt = capability->cap[PIX_FMTS].value;
  602. }
  603. else
  604. s_vpr_e(inst->sid,
  605. "%s: invalid parent %d\n",
  606. __func__, parent_id);
  607. i++;
  608. }
  609. /* PIX_FMTS dependency is common across all chipsets.
  610. * Hence, PIX_FMTS must be specified as Parent for HEVC profile.
  611. * Otherwise it would be a database error that should be fixed.
  612. */
  613. if (pix_fmt == -1) {
  614. s_vpr_e(inst->sid,
  615. "%s: missing parent: %d, please correct database\n",
  616. __func__, PIX_FMTS);
  617. return -EINVAL;
  618. }
  619. /* 10 bit profile for 10 bit color format */
  620. if (pix_fmt == MSM_VIDC_FMT_TP10C ||
  621. pix_fmt == MSM_VIDC_FMT_P010) {
  622. adjusted_value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10;
  623. } else {
  624. /* 8 bit profile for 8 bit color format */
  625. if (adjusted_value == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10)
  626. adjusted_value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN;
  627. }
  628. if (capability->cap[PROFILE].value != adjusted_value) {
  629. s_vpr_h(inst->sid,
  630. "%s: updated from %#x to adjusted %#x\n", __func__,
  631. capability->cap[PROFILE].value, adjusted_value);
  632. capability->cap[PROFILE].value = adjusted_value;
  633. }
  634. return rc;
  635. }
  636. int msm_vidc_adjust_ltr_count(void *instance, struct v4l2_ctrl *ctrl)
  637. {
  638. int rc = 0;
  639. int i = 0;
  640. struct msm_vidc_inst_capability *capability;
  641. s32 adjusted_value;
  642. enum msm_vidc_inst_capability_type parent_id;
  643. struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
  644. s32 rc_type = -1;
  645. if (!inst || !inst->capabilities) {
  646. d_vpr_e("%s: invalid params\n", __func__);
  647. return -EINVAL;
  648. }
  649. capability = inst->capabilities;
  650. if (ctrl)
  651. adjusted_value = ctrl->val;
  652. else
  653. adjusted_value = capability->cap[LTR_COUNT].value;
  654. /* check parents and adjust cabac session value */
  655. while (i < MAX_CAP_PARENTS &&
  656. capability->cap[LTR_COUNT].parents[i]) {
  657. parent_id = capability->cap[LTR_COUNT].parents[i];
  658. i++;
  659. }
  660. if (!(rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
  661. /* TODO(AS): remove comment after below rc modes are upstreamed
  662. || rc_type == RATE_CONTROL_OFF ||
  663. || rc_tpe == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR
  664. */))
  665. adjusted_value = 0;
  666. if (capability->cap[LTR_COUNT].value != adjusted_value) {
  667. s_vpr_h(inst->sid, "%s: adjusted from %#x to %#x\n", __func__,
  668. capability->cap[LTR_COUNT].value, adjusted_value);
  669. capability->cap[LTR_COUNT].value = adjusted_value;
  670. }
  671. return rc;
  672. }
  673. /*
  674. * Loop over instance capabilities with CAP_FLAG_ROOT
  675. * and call adjust function, where
  676. * - adjust current capability value
  677. * - update tail of instance children list with capability children
  678. * - update instance firmware list with current capability id
  679. * Now, loop over child list and call its adjust function
  680. */
  681. int msm_vidc_adjust_v4l2_properties(struct msm_vidc_inst *inst)
  682. {
  683. int rc = 0;
  684. int i;
  685. struct msm_vidc_inst_cap_entry *curr_node = NULL, *tmp_node = NULL;
  686. struct msm_vidc_inst_capability *capability;
  687. d_vpr_h("%s()\n", __func__);
  688. if (!inst || !inst->capabilities) {
  689. d_vpr_e("%s: invalid params\n", __func__);
  690. return -EINVAL;
  691. }
  692. capability = inst->capabilities;
  693. for (i = 0; i < INST_CAP_MAX; i++) {
  694. if (capability->cap[i].flags & CAP_FLAG_ROOT) {
  695. rc = msm_vidc_adjust_property(inst,
  696. capability->cap[i].cap);
  697. if (rc)
  698. goto exit;
  699. }
  700. }
  701. /*
  702. * children of all root controls are already
  703. * added to inst->children list at this point
  704. */
  705. list_for_each_entry_safe(curr_node, tmp_node,
  706. &inst->children.list, list) {
  707. /*
  708. * call adjust for each child. Each child adjust
  709. * will also update child list at the tail with
  710. * its own children list.
  711. * Also, if current control id value is updated,
  712. * its entry should be added to fw list.
  713. */
  714. rc = msm_vidc_adjust_property(inst, curr_node->cap_id);
  715. if (rc)
  716. goto exit;
  717. list_del(&curr_node->list);
  718. kfree(curr_node);
  719. }
  720. exit:
  721. return rc;
  722. }
  723. int msm_vidc_set_bitrate_mode(void *instance,
  724. enum msm_vidc_inst_capability_type cap_id)
  725. {
  726. int rc = 0;
  727. struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
  728. int lossless, frame_rc, bitrate_mode, frame_skip;
  729. u32 hfi_value;
  730. struct msm_vidc_inst_capability *capability;
  731. if (!inst || !inst->capabilities) {
  732. d_vpr_e("%s: invalid params\n", __func__);
  733. return -EINVAL;
  734. }
  735. capability = inst->capabilities;
  736. bitrate_mode = capability->cap[cap_id].value;
  737. lossless = capability->cap[LOSSLESS].value;
  738. frame_rc = capability->cap[FRAME_RC_ENABLE].value;
  739. frame_skip = capability->cap[FRAME_SKIP_MODE].value;
  740. if (lossless) {
  741. hfi_value = HFI_RC_LOSSLESS;
  742. return rc;
  743. }
  744. if (!frame_rc) {
  745. hfi_value = HFI_RC_OFF;
  746. return rc;
  747. }
  748. if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
  749. hfi_value = HFI_RC_VBR_CFR;
  750. } else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) {
  751. if (frame_skip)
  752. hfi_value = HFI_RC_CBR_VFR;
  753. else
  754. hfi_value = HFI_RC_CBR_CFR;
  755. }/* TODO: CQ mode
  756. else if (bitrate_mode == CQ) {
  757. hfi_value = HFI_RC_CQ;
  758. }
  759. */
  760. rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32_ENUM,
  761. &hfi_value, sizeof(u32), __func__);
  762. return rc;
  763. }
  764. int msm_vidc_set_header_mode(void *instance,
  765. enum msm_vidc_inst_capability_type cap_id)
  766. {
  767. int rc = 0;
  768. struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
  769. int header_mode, prepend_sps_pps, hdr_metadata;
  770. u32 hfi_value = 0;
  771. struct msm_vidc_inst_capability *capability;
  772. if (!inst || !inst->capabilities) {
  773. d_vpr_e("%s: invalid params\n", __func__);
  774. return -EINVAL;
  775. }
  776. capability = inst->capabilities;
  777. header_mode = capability->cap[cap_id].value;
  778. prepend_sps_pps = capability->cap[PREPEND_SPSPPS_TO_IDR].value;
  779. hdr_metadata = capability->cap[META_SEQ_HDR_NAL].value;
  780. if (header_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE)
  781. hfi_value |= HFI_SEQ_HEADER_SEPERATE_FRAME;
  782. else if (header_mode == V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME)
  783. hfi_value |= HFI_SEQ_HEADER_JOINED_WITH_1ST_FRAME;
  784. if (prepend_sps_pps) {
  785. hfi_value |= HFI_SEQ_HEADER_PREFIX_WITH_SYNC_FRAME;
  786. }
  787. if (hdr_metadata) {
  788. hfi_value |= HFI_SEQ_HEADER_METADATA;
  789. }
  790. rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32_ENUM,
  791. &hfi_value, sizeof(u32), __func__);
  792. return rc;
  793. }
  794. int msm_vidc_set_q16(void *instance,
  795. enum msm_vidc_inst_capability_type cap_id)
  796. {
  797. int rc = 0;
  798. struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
  799. u32 hfi_value = 0;
  800. if (!inst || !inst->capabilities) {
  801. d_vpr_e("%s: invalid params\n", __func__);
  802. return -EINVAL;
  803. }
  804. hfi_value = inst->capabilities->cap[cap_id].value;
  805. rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_Q16,
  806. &hfi_value, sizeof(u32), __func__);
  807. return rc;
  808. }
  809. int msm_vidc_set_u32(void *instance,
  810. enum msm_vidc_inst_capability_type cap_id)
  811. {
  812. int rc = 0;
  813. struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
  814. u32 hfi_value;
  815. if (!inst || !inst->capabilities) {
  816. d_vpr_e("%s: invalid params\n", __func__);
  817. return -EINVAL;
  818. }
  819. if (inst->capabilities->cap[cap_id].flags & CAP_FLAG_MENU) {
  820. rc = msm_vidc_v4l2_menu_to_hfi(inst, cap_id, &hfi_value);
  821. if (rc)
  822. return -EINVAL;
  823. } else {
  824. hfi_value = inst->capabilities->cap[cap_id].value;
  825. }
  826. rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32,
  827. &hfi_value, sizeof(u32), __func__);
  828. return rc;
  829. }
  830. int msm_vidc_set_u32_enum(void *instance,
  831. enum msm_vidc_inst_capability_type cap_id)
  832. {
  833. int rc = 0;
  834. struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
  835. u32 hfi_value;
  836. if (!inst || !inst->capabilities) {
  837. d_vpr_e("%s: invalid params\n", __func__);
  838. return -EINVAL;
  839. }
  840. rc = msm_vidc_v4l2_to_hfi_enum(inst, cap_id, &hfi_value);
  841. if (rc)
  842. return -EINVAL;
  843. rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32_ENUM,
  844. &hfi_value, sizeof(u32), __func__);
  845. return rc;
  846. }
  847. int msm_vidc_set_s32(void *instance,
  848. enum msm_vidc_inst_capability_type cap_id)
  849. {
  850. int rc = 0;
  851. struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
  852. s32 hfi_value = 0;
  853. if (!inst || !inst->capabilities) {
  854. d_vpr_e("%s: invalid params\n", __func__);
  855. return -EINVAL;
  856. }
  857. hfi_value = inst->capabilities->cap[cap_id].value;
  858. rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_S32,
  859. &hfi_value, sizeof(u32), __func__);
  860. return rc;
  861. }
  862. /* Please ignore this function for now. TO DO*/
  863. int msm_vidc_set_array(void *instance,
  864. enum msm_vidc_inst_capability_type cap_id)
  865. {
  866. int rc = 0;
  867. struct msm_vidc_inst_capability *capability;
  868. struct msm_vidc_core *core;
  869. struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
  870. if (!inst || !inst->core || !inst->capabilities) {
  871. d_vpr_e("%s: invalid params\n", __func__);
  872. return -EINVAL;
  873. }
  874. capability = inst->capabilities;
  875. core = (struct msm_vidc_core *)inst->core;
  876. switch (cap_id) {
  877. /*
  878. * Needed if any control needs to be packed into a structure
  879. * and sent for packetization.
  880. * payload types may be:
  881. * STRUCTURE, BLOB, STRING, PACKED, ARRAY,
  882. *
  883. case BITRATE_MODE:
  884. s_vpr_h(inst->sid, "%s: %d\n", __func__, hfi_value);
  885. hfi_create_packet(inst->packet, inst->packet_size,
  886. offset,
  887. capability->cap[cap_id].hfi_id,
  888. HFI_HOST_FLAGS_NONE, HFI_PAYLOAD_ENUM,
  889. HFI_PORT_NONE, core->packet_id++,
  890. &capability->cap[PROFILE].value, sizeof(u32));
  891. break;
  892. }
  893. */
  894. default:
  895. s_vpr_e(inst->sid,
  896. "%s: Unknown cap id %d, cannot set to fw\n",
  897. __func__, cap_id);
  898. rc = -EINVAL;
  899. break;
  900. }
  901. return rc;
  902. }
  903. int msm_vidc_set_v4l2_properties(struct msm_vidc_inst *inst)
  904. {
  905. int rc = 0;
  906. struct msm_vidc_inst_capability *capability;
  907. struct msm_vidc_inst_cap_entry *curr_node = NULL, *tmp_node = NULL;
  908. d_vpr_h("%s()\n", __func__);
  909. if (!inst || !inst->capabilities) {
  910. d_vpr_e("%s: invalid params\n", __func__);
  911. return -EINVAL;
  912. }
  913. capability = inst->capabilities;
  914. list_for_each_entry_safe(curr_node, tmp_node,
  915. &inst->firmware.list, list) {
  916. /* cap_id's like PIX_FMT etc may not have set functions */
  917. if (!capability->cap[curr_node->cap_id].set)
  918. continue;
  919. rc = capability->cap[curr_node->cap_id].set(inst,
  920. curr_node->cap_id);
  921. if (rc)
  922. goto exit;
  923. list_del(&curr_node->list);
  924. kfree(curr_node);
  925. }
  926. exit:
  927. return rc;
  928. }
  929. int msm_vidc_v4l2_menu_to_hfi(struct msm_vidc_inst *inst,
  930. enum msm_vidc_inst_capability_type cap_id, u32 *value)
  931. {
  932. struct msm_vidc_inst_capability *capability = inst->capabilities;
  933. switch (capability->cap[cap_id].v4l2_id) {
  934. case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
  935. switch (capability->cap[cap_id].value) {
  936. case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC:
  937. *value = 1;
  938. break;
  939. case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC:
  940. *value = 0;
  941. break;
  942. default:
  943. *value = 1;
  944. goto set_default;
  945. }
  946. return 0;
  947. default:
  948. s_vpr_e(inst->sid,
  949. "%s: mapping not specified for ctrl_id: %#x\n",
  950. __func__, capability->cap[cap_id].v4l2_id);
  951. return -EINVAL;
  952. }
  953. set_default:
  954. s_vpr_e(inst->sid,
  955. "%s: invalid value %d for ctrl id: %#x. Set default: %u\n",
  956. __func__, capability->cap[cap_id].value,
  957. capability->cap[cap_id].v4l2_id, *value);
  958. return 0;
  959. }
  960. int msm_vidc_v4l2_to_hfi_enum(struct msm_vidc_inst *inst,
  961. enum msm_vidc_inst_capability_type cap_id, u32 *value)
  962. {
  963. struct msm_vidc_inst_capability *capability = inst->capabilities;
  964. switch (capability->cap[cap_id].v4l2_id) {
  965. case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
  966. case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
  967. case V4L2_CID_MPEG_VIDEO_VP9_PROFILE:
  968. case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
  969. case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
  970. case V4L2_CID_MPEG_VIDEO_HEVC_TIER:
  971. case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_TYPES:
  972. *value = capability->cap[cap_id].value;
  973. return 0;
  974. case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE:
  975. switch (capability->cap[cap_id].value) {
  976. case V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B:
  977. *value = HFI_HIER_B;
  978. break;
  979. case V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P:
  980. //TODO (AS): check if this is right mapping
  981. *value = HFI_HIER_P_SLIDING_WINDOW;
  982. break;
  983. default:
  984. *value = HFI_HIER_P_SLIDING_WINDOW;
  985. goto set_default;
  986. }
  987. return 0;
  988. default:
  989. s_vpr_e(inst->sid,
  990. "%s: mapping not specified for ctrl_id: %#x\n",
  991. __func__, capability->cap[cap_id].v4l2_id);
  992. return -EINVAL;
  993. }
  994. set_default:
  995. s_vpr_e(inst->sid,
  996. "%s: invalid value %d for ctrl id: %#x. Set default: %u\n",
  997. __func__, capability->cap[cap_id].value,
  998. capability->cap[cap_id].v4l2_id, *value);
  999. return 0;
  1000. }