msm_vidc.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. */
  5. /* Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. */
  6. #include <linux/types.h>
  7. #include <linux/hash.h>
  8. #include "msm_vidc_core.h"
  9. #include "msm_vidc_inst.h"
  10. #include "msm_vdec.h"
  11. #include "msm_venc.h"
  12. #include "msm_vidc_internal.h"
  13. #include "msm_vidc_driver.h"
  14. #include "msm_vidc_vb2.h"
  15. #include "msm_vidc_v4l2.h"
  16. #include "msm_vidc_debug.h"
  17. #include "msm_vidc_control.h"
  18. #include "msm_vidc_power.h"
  19. #include "msm_vidc_fence.h"
  20. #include "msm_vidc_memory.h"
  21. #include "venus_hfi_response.h"
  22. #include "msm_vidc.h"
  23. #include "msm_vidc_platform.h"
  24. extern const char video_banner[];
  25. #define MSM_VIDC_DRV_NAME "msm_vidc_driver"
  26. #define MSM_VIDC_BUS_NAME "platform:msm_vidc_bus"
  27. /* kernel/msm-4.19 */
  28. #define MSM_VIDC_VERSION ((5 << 16) + (10 << 8) + 0)
  29. static inline bool valid_v4l2_buffer(struct v4l2_buffer *b,
  30. struct msm_vidc_inst *inst)
  31. {
  32. if (b->type == INPUT_MPLANE || b->type == OUTPUT_MPLANE)
  33. return b->length > 0;
  34. else if (b->type == INPUT_META_PLANE || b->type == OUTPUT_META_PLANE)
  35. return true;
  36. return false;
  37. }
  38. static int get_poll_flags(struct msm_vidc_inst *inst, u32 port)
  39. {
  40. int poll = 0;
  41. struct vb2_queue *q = NULL;
  42. struct vb2_buffer *vb = NULL;
  43. unsigned long flags = 0;
  44. if (!inst || port >= MAX_PORT) {
  45. d_vpr_e("%s: invalid params, inst %pK, port %d\n",
  46. __func__, inst, port);
  47. return poll;
  48. }
  49. q = inst->bufq[port].vb2q;
  50. spin_lock_irqsave(&q->done_lock, flags);
  51. if (!list_empty(&q->done_list))
  52. vb = list_first_entry(&q->done_list, struct vb2_buffer,
  53. done_entry);
  54. if (vb && (vb->state == VB2_BUF_STATE_DONE ||
  55. vb->state == VB2_BUF_STATE_ERROR)) {
  56. if (port == OUTPUT_PORT || port == OUTPUT_META_PORT)
  57. poll |= POLLIN | POLLRDNORM;
  58. else if (port == INPUT_PORT || port == INPUT_META_PORT)
  59. poll |= POLLOUT | POLLWRNORM;
  60. }
  61. spin_unlock_irqrestore(&q->done_lock, flags);
  62. return poll;
  63. }
  64. int msm_vidc_poll(void *instance, struct file *filp,
  65. struct poll_table_struct *wait)
  66. {
  67. int poll = 0;
  68. struct msm_vidc_inst *inst = instance;
  69. if (!inst) {
  70. d_vpr_e("%s: invalid params\n", __func__);
  71. return POLLERR;
  72. }
  73. if (is_session_error(inst)) {
  74. i_vpr_e(inst, "%s: inst in error state\n", __func__);
  75. return POLLERR;
  76. }
  77. poll_wait(filp, &inst->event_handler.wait, wait);
  78. poll_wait(filp, &inst->bufq[INPUT_META_PORT].vb2q->done_wq, wait);
  79. poll_wait(filp, &inst->bufq[OUTPUT_META_PORT].vb2q->done_wq, wait);
  80. poll_wait(filp, &inst->bufq[INPUT_PORT].vb2q->done_wq, wait);
  81. poll_wait(filp, &inst->bufq[OUTPUT_PORT].vb2q->done_wq, wait);
  82. if (v4l2_event_pending(&inst->event_handler))
  83. poll |= POLLPRI;
  84. poll |= get_poll_flags(inst, INPUT_META_PORT);
  85. poll |= get_poll_flags(inst, OUTPUT_META_PORT);
  86. poll |= get_poll_flags(inst, INPUT_PORT);
  87. poll |= get_poll_flags(inst, OUTPUT_PORT);
  88. return poll;
  89. }
  90. EXPORT_SYMBOL(msm_vidc_poll);
  91. int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
  92. {
  93. struct msm_vidc_inst *inst = instance;
  94. if (!inst || !cap) {
  95. d_vpr_e("%s: invalid params\n", __func__);
  96. return -EINVAL;
  97. }
  98. strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver));
  99. strlcpy(cap->bus_info, MSM_VIDC_BUS_NAME, sizeof(cap->bus_info));
  100. cap->version = MSM_VIDC_VERSION;
  101. memset(cap->reserved, 0, sizeof(cap->reserved));
  102. if (inst->domain == MSM_VIDC_DECODER)
  103. strlcpy(cap->card, "msm_vidc_decoder", sizeof(cap->card));
  104. else if (inst->domain == MSM_VIDC_ENCODER)
  105. strlcpy(cap->card, "msm_vidc_encoder", sizeof(cap->card));
  106. else
  107. return -EINVAL;
  108. return 0;
  109. }
  110. EXPORT_SYMBOL(msm_vidc_querycap);
  111. int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
  112. {
  113. struct msm_vidc_inst *inst = instance;
  114. if (!inst || !f) {
  115. d_vpr_e("%s: invalid params\n", __func__);
  116. return -EINVAL;
  117. }
  118. if (inst->domain == MSM_VIDC_DECODER)
  119. return msm_vdec_enum_fmt(inst, f);
  120. if (inst->domain == MSM_VIDC_ENCODER)
  121. return msm_venc_enum_fmt(inst, f);
  122. return -EINVAL;
  123. }
  124. EXPORT_SYMBOL(msm_vidc_enum_fmt);
  125. int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *q_ctrl)
  126. {
  127. int rc = 0;
  128. struct msm_vidc_inst *inst = instance;
  129. struct v4l2_ctrl *ctrl;
  130. if (!inst || !q_ctrl) {
  131. d_vpr_e("%s: invalid params %pK %pK\n",
  132. __func__, inst, q_ctrl);
  133. return -EINVAL;
  134. }
  135. ctrl = v4l2_ctrl_find(&inst->ctrl_handler, q_ctrl->id);
  136. if (!ctrl) {
  137. i_vpr_e(inst, "%s: get_ctrl failed for id %d\n",
  138. __func__, q_ctrl->id);
  139. return -EINVAL;
  140. }
  141. q_ctrl->minimum = ctrl->minimum;
  142. q_ctrl->maximum = ctrl->maximum;
  143. q_ctrl->default_value = ctrl->default_value;
  144. q_ctrl->flags = 0;
  145. q_ctrl->step = ctrl->step;
  146. i_vpr_h(inst,
  147. "query ctrl: %s: min %d, max %d, default %d step %d flags %#x\n",
  148. ctrl->name, q_ctrl->minimum, q_ctrl->maximum,
  149. q_ctrl->default_value, q_ctrl->step, q_ctrl->flags);
  150. return rc;
  151. }
  152. EXPORT_SYMBOL(msm_vidc_query_ctrl);
  153. int msm_vidc_query_menu(void *instance, struct v4l2_querymenu *qmenu)
  154. {
  155. int rc = 0;
  156. struct msm_vidc_inst *inst = instance;
  157. struct v4l2_ctrl *ctrl;
  158. if (!inst || !qmenu) {
  159. d_vpr_e("%s: invalid params %pK %pK\n",
  160. __func__, inst, qmenu);
  161. return -EINVAL;
  162. }
  163. ctrl = v4l2_ctrl_find(&inst->ctrl_handler, qmenu->id);
  164. if (!ctrl) {
  165. i_vpr_e(inst, "%s: get_ctrl failed for id %d\n",
  166. __func__, qmenu->id);
  167. return -EINVAL;
  168. }
  169. if (ctrl->type != V4L2_CTRL_TYPE_MENU) {
  170. i_vpr_e(inst, "%s: ctrl: %s: type (%d) is not MENU type\n",
  171. __func__, ctrl->name, ctrl->type);
  172. return -EINVAL;
  173. }
  174. if (qmenu->index < ctrl->minimum || qmenu->index > ctrl->maximum)
  175. return -EINVAL;
  176. if (ctrl->menu_skip_mask & (1 << qmenu->index))
  177. rc = -EINVAL;
  178. i_vpr_h(inst,
  179. "%s: ctrl: %s: min %lld, max %lld, menu_skip_mask %lld, qmenu: id %u, index %d, %s\n",
  180. __func__, ctrl->name, ctrl->minimum, ctrl->maximum,
  181. ctrl->menu_skip_mask, qmenu->id, qmenu->index,
  182. rc ? "not supported" : "supported");
  183. return rc;
  184. }
  185. EXPORT_SYMBOL(msm_vidc_query_menu);
  186. int msm_vidc_try_fmt(void *instance, struct v4l2_format *f)
  187. {
  188. int rc = 0;
  189. struct msm_vidc_inst *inst = instance;
  190. if (!inst || !f) {
  191. d_vpr_e("%s: invalid params\n", __func__);
  192. return -EINVAL;
  193. }
  194. if (!msm_vidc_allow_s_fmt(inst, f->type))
  195. return -EBUSY;
  196. if (inst->domain == MSM_VIDC_DECODER)
  197. rc = msm_vdec_try_fmt(inst, f);
  198. if (inst->domain == MSM_VIDC_ENCODER)
  199. rc = msm_venc_try_fmt(inst, f);
  200. if (rc)
  201. i_vpr_e(inst, "%s: try_fmt(%d) failed %d\n",
  202. __func__, f->type, rc);
  203. return rc;
  204. }
  205. EXPORT_SYMBOL(msm_vidc_try_fmt);
  206. int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
  207. {
  208. int rc = 0;
  209. struct msm_vidc_inst *inst = instance;
  210. if (!inst || !f) {
  211. d_vpr_e("%s: invalid params\n", __func__);
  212. return -EINVAL;
  213. }
  214. if (!msm_vidc_allow_s_fmt(inst, f->type))
  215. return -EBUSY;
  216. if (inst->domain == MSM_VIDC_DECODER)
  217. rc = msm_vdec_s_fmt(inst, f);
  218. if (inst->domain == MSM_VIDC_ENCODER)
  219. rc = msm_venc_s_fmt(inst, f);
  220. if (rc)
  221. i_vpr_e(inst, "%s: s_fmt(%d) failed %d\n",
  222. __func__, f->type, rc);
  223. return rc;
  224. }
  225. EXPORT_SYMBOL(msm_vidc_s_fmt);
  226. int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
  227. {
  228. int rc = 0;
  229. struct msm_vidc_inst *inst = instance;
  230. if (!inst || !f) {
  231. d_vpr_e("%s: invalid params\n", __func__);
  232. return -EINVAL;
  233. }
  234. if (is_decode_session(inst))
  235. rc = msm_vdec_g_fmt(inst, f);
  236. if (is_encode_session(inst))
  237. rc = msm_venc_g_fmt(inst, f);
  238. if (rc)
  239. return rc;
  240. if (f->type == INPUT_MPLANE || f->type == OUTPUT_MPLANE)
  241. i_vpr_h(inst, "%s: type %s format %s width %d height %d size %d\n",
  242. __func__, v4l2_type_name(f->type),
  243. v4l2_pixelfmt_name(inst, f->fmt.pix_mp.pixelformat),
  244. f->fmt.pix_mp.width, f->fmt.pix_mp.height,
  245. f->fmt.pix_mp.plane_fmt[0].sizeimage);
  246. else if (f->type == INPUT_META_PLANE || f->type == OUTPUT_META_PLANE)
  247. i_vpr_h(inst, "%s: type %s size %d\n",
  248. __func__, v4l2_type_name(f->type), f->fmt.meta.buffersize);
  249. return 0;
  250. }
  251. EXPORT_SYMBOL(msm_vidc_g_fmt);
  252. int msm_vidc_s_selection(void *instance, struct v4l2_selection *s)
  253. {
  254. int rc = 0;
  255. struct msm_vidc_inst *inst = instance;
  256. if (!inst || !s) {
  257. d_vpr_e("%s: invalid params\n", __func__);
  258. return -EINVAL;
  259. }
  260. if (is_decode_session(inst))
  261. rc = msm_vdec_s_selection(inst, s);
  262. if (is_encode_session(inst))
  263. rc = msm_venc_s_selection(inst, s);
  264. return rc;
  265. }
  266. EXPORT_SYMBOL(msm_vidc_s_selection);
  267. int msm_vidc_g_selection(void *instance, struct v4l2_selection *s)
  268. {
  269. int rc = 0;
  270. struct msm_vidc_inst *inst = instance;
  271. if (!inst || !s) {
  272. d_vpr_e("%s: invalid params\n", __func__);
  273. return -EINVAL;
  274. }
  275. if (is_decode_session(inst))
  276. rc = msm_vdec_g_selection(inst, s);
  277. if (is_encode_session(inst))
  278. rc = msm_venc_g_selection(inst, s);
  279. return rc;
  280. }
  281. EXPORT_SYMBOL(msm_vidc_g_selection);
  282. int msm_vidc_s_param(void *instance, struct v4l2_streamparm *param)
  283. {
  284. int rc = 0;
  285. struct msm_vidc_inst *inst = instance;
  286. if (!inst || !param) {
  287. d_vpr_e("%s: invalid params\n", __func__);
  288. return -EINVAL;
  289. }
  290. if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
  291. param->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
  292. return -EINVAL;
  293. if (is_encode_session(inst)) {
  294. rc = msm_venc_s_param(instance, param);
  295. } else {
  296. i_vpr_e(inst, "%s: invalid domain %#x\n",
  297. __func__, inst->domain);
  298. return -EINVAL;
  299. }
  300. return rc;
  301. }
  302. EXPORT_SYMBOL(msm_vidc_s_param);
  303. int msm_vidc_g_param(void *instance, struct v4l2_streamparm *param)
  304. {
  305. int rc = 0;
  306. struct msm_vidc_inst *inst = instance;
  307. if (!inst || !param) {
  308. d_vpr_e("%s: invalid params\n", __func__);
  309. return -EINVAL;
  310. }
  311. if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
  312. param->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
  313. return -EINVAL;
  314. if (is_encode_session(inst)) {
  315. rc = msm_venc_g_param(instance, param);
  316. } else {
  317. i_vpr_e(inst, "%s: invalid domain %#x\n",
  318. __func__, inst->domain);
  319. return -EINVAL;
  320. }
  321. return rc;
  322. }
  323. EXPORT_SYMBOL(msm_vidc_g_param);
  324. int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
  325. {
  326. int rc = 0;
  327. struct msm_vidc_inst *inst = instance;
  328. int port;
  329. if (!inst || !b) {
  330. d_vpr_e("%s: invalid params\n", __func__);
  331. return -EINVAL;
  332. }
  333. if (!msm_vidc_allow_reqbufs(inst, b->type)) {
  334. rc = -EBUSY;
  335. goto exit;
  336. }
  337. port = v4l2_type_to_driver_port(inst, b->type, __func__);
  338. if (port < 0) {
  339. rc = -EINVAL;
  340. goto exit;
  341. }
  342. rc = vb2_reqbufs(inst->bufq[port].vb2q, b);
  343. if (rc) {
  344. i_vpr_e(inst, "%s: vb2_reqbufs(%d) failed, %d\n",
  345. __func__, b->type, rc);
  346. goto exit;
  347. }
  348. exit:
  349. return rc;
  350. }
  351. EXPORT_SYMBOL(msm_vidc_reqbufs);
  352. int msm_vidc_querybuf(void *instance, struct v4l2_buffer *b)
  353. {
  354. int rc = 0;
  355. struct msm_vidc_inst *inst = instance;
  356. int port;
  357. if (!inst || !b) {
  358. d_vpr_e("%s: invalid params\n", __func__);
  359. return -EINVAL;
  360. }
  361. port = v4l2_type_to_driver_port(inst, b->type, __func__);
  362. if (port < 0) {
  363. rc = -EINVAL;
  364. goto exit;
  365. }
  366. rc = vb2_querybuf(inst->bufq[port].vb2q, b);
  367. if (rc) {
  368. i_vpr_e(inst, "%s: vb2_querybuf(%d) failed, %d\n",
  369. __func__, b->type, rc);
  370. goto exit;
  371. }
  372. exit:
  373. return rc;
  374. }
  375. EXPORT_SYMBOL(msm_vidc_querybuf);
  376. int msm_vidc_create_bufs(void *instance, struct v4l2_create_buffers *b)
  377. {
  378. int rc = 0;
  379. struct msm_vidc_inst *inst = instance;
  380. int port;
  381. struct v4l2_format *f;
  382. if (!inst || !b) {
  383. d_vpr_e("%s: invalid params\n", __func__);
  384. return -EINVAL;
  385. }
  386. f = &b->format;
  387. port = v4l2_type_to_driver_port(inst, f->type, __func__);
  388. if (port < 0) {
  389. rc = -EINVAL;
  390. goto exit;
  391. }
  392. rc = vb2_create_bufs(inst->bufq[port].vb2q, b);
  393. if (rc) {
  394. i_vpr_e(inst, "%s: vb2_create_bufs(%d) failed, %d\n",
  395. __func__, f->type, rc);
  396. goto exit;
  397. }
  398. exit:
  399. return rc;
  400. }
  401. EXPORT_SYMBOL(msm_vidc_create_bufs);
  402. int msm_vidc_prepare_buf(void *instance, struct media_device *mdev,
  403. struct v4l2_buffer *b)
  404. {
  405. int rc = 0;
  406. struct msm_vidc_inst *inst = instance;
  407. struct vb2_queue *q;
  408. if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) {
  409. d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, b);
  410. return -EINVAL;
  411. }
  412. q = msm_vidc_get_vb2q(inst, b->type, __func__);
  413. if (!q) {
  414. rc = -EINVAL;
  415. goto exit;
  416. }
  417. rc = vb2_prepare_buf(q, mdev, b);
  418. if (rc) {
  419. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  420. goto exit;
  421. }
  422. exit:
  423. return rc;
  424. }
  425. EXPORT_SYMBOL(msm_vidc_prepare_buf);
  426. int msm_vidc_qbuf(void *instance, struct media_device *mdev,
  427. struct v4l2_buffer *b)
  428. {
  429. int rc = 0;
  430. struct msm_vidc_inst *inst = instance;
  431. struct vb2_queue *q;
  432. if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) {
  433. d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, b);
  434. return -EINVAL;
  435. }
  436. q = msm_vidc_get_vb2q(inst, b->type, __func__);
  437. if (!q) {
  438. rc = -EINVAL;
  439. goto exit;
  440. }
  441. rc = vb2_qbuf(q, mdev, b);
  442. if (rc)
  443. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  444. exit:
  445. return rc;
  446. }
  447. EXPORT_SYMBOL(msm_vidc_qbuf);
  448. int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
  449. {
  450. int rc = 0;
  451. struct msm_vidc_inst *inst = instance;
  452. struct vb2_queue *q;
  453. if (!inst || !b || !valid_v4l2_buffer(b, inst)) {
  454. d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, b);
  455. return -EINVAL;
  456. }
  457. q = msm_vidc_get_vb2q(inst, b->type, __func__);
  458. if (!q) {
  459. rc = -EINVAL;
  460. goto exit;
  461. }
  462. rc = vb2_dqbuf(q, b, true);
  463. if (rc == -EAGAIN) {
  464. goto exit;
  465. } else if (rc) {
  466. i_vpr_l(inst, "%s: failed with %d\n", __func__, rc);
  467. goto exit;
  468. }
  469. exit:
  470. return rc;
  471. }
  472. EXPORT_SYMBOL(msm_vidc_dqbuf);
  473. int msm_vidc_streamon(void *instance, enum v4l2_buf_type type)
  474. {
  475. int rc = 0;
  476. struct msm_vidc_inst *inst = instance;
  477. int port;
  478. if (!inst) {
  479. d_vpr_e("%s: invalid params\n", __func__);
  480. return -EINVAL;
  481. }
  482. port = v4l2_type_to_driver_port(inst, type, __func__);
  483. if (port < 0) {
  484. rc = -EINVAL;
  485. goto exit;
  486. }
  487. rc = vb2_streamon(inst->bufq[port].vb2q, type);
  488. if (rc) {
  489. i_vpr_e(inst, "%s: vb2_streamon(%d) failed, %d\n",
  490. __func__, type, rc);
  491. goto exit;
  492. }
  493. exit:
  494. return rc;
  495. }
  496. EXPORT_SYMBOL(msm_vidc_streamon);
  497. int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type)
  498. {
  499. int rc = 0;
  500. struct msm_vidc_inst *inst = instance;
  501. int port;
  502. if (!inst) {
  503. d_vpr_e("%s: invalid params\n", __func__);
  504. return -EINVAL;
  505. }
  506. port = v4l2_type_to_driver_port(inst, type, __func__);
  507. if (port < 0) {
  508. rc = -EINVAL;
  509. goto exit;
  510. }
  511. rc = vb2_streamoff(inst->bufq[port].vb2q, type);
  512. if (rc) {
  513. i_vpr_e(inst, "%s: vb2_streamoff(%d) failed, %d\n",
  514. __func__, type, rc);
  515. goto exit;
  516. }
  517. exit:
  518. return rc;
  519. }
  520. EXPORT_SYMBOL(msm_vidc_streamoff);
  521. int msm_vidc_try_cmd(void *instance, union msm_v4l2_cmd *cmd)
  522. {
  523. int rc = 0;
  524. struct msm_vidc_inst *inst = instance;
  525. struct v4l2_decoder_cmd *dec = NULL;
  526. struct v4l2_encoder_cmd *enc = NULL;
  527. if (is_decode_session(inst)) {
  528. dec = (struct v4l2_decoder_cmd *)cmd;
  529. i_vpr_h(inst, "%s: cmd %d\n", __func__, dec->cmd);
  530. if (dec->cmd != V4L2_DEC_CMD_STOP && dec->cmd != V4L2_DEC_CMD_START)
  531. return -EINVAL;
  532. dec->flags = 0;
  533. if (dec->cmd == V4L2_DEC_CMD_STOP) {
  534. dec->stop.pts = 0;
  535. } else if (dec->cmd == V4L2_DEC_CMD_START) {
  536. dec->start.speed = 0;
  537. dec->start.format = V4L2_DEC_START_FMT_NONE;
  538. }
  539. } else if (is_encode_session(inst)) {
  540. enc = (struct v4l2_encoder_cmd *)cmd;
  541. i_vpr_h(inst, "%s: cmd %d\n", __func__, enc->cmd);
  542. if (enc->cmd != V4L2_ENC_CMD_STOP && enc->cmd != V4L2_ENC_CMD_START)
  543. return -EINVAL;
  544. enc->flags = 0;
  545. }
  546. return rc;
  547. }
  548. EXPORT_SYMBOL(msm_vidc_try_cmd);
  549. int msm_vidc_cmd(void *instance, union msm_v4l2_cmd *cmd)
  550. {
  551. int rc = 0;
  552. struct msm_vidc_inst *inst = instance;
  553. struct v4l2_decoder_cmd *dec = NULL;
  554. struct v4l2_encoder_cmd *enc = NULL;
  555. if (is_decode_session(inst)) {
  556. dec = (struct v4l2_decoder_cmd *)cmd;
  557. rc = msm_vdec_process_cmd(inst, dec->cmd);
  558. } else if (is_encode_session(inst)) {
  559. enc = (struct v4l2_encoder_cmd *)cmd;
  560. rc = msm_venc_process_cmd(inst, enc->cmd);
  561. }
  562. if (rc)
  563. return rc;
  564. return 0;
  565. }
  566. EXPORT_SYMBOL(msm_vidc_cmd);
  567. int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize)
  568. {
  569. struct msm_vidc_inst *inst = instance;
  570. struct msm_vidc_inst_capability *capability;
  571. enum msm_vidc_colorformat_type colorfmt;
  572. enum msm_vidc_codec_type codec;
  573. u32 meta_fmt;
  574. if (!inst || !fsize) {
  575. d_vpr_e("%s: invalid params: %pK %pK\n",
  576. __func__, inst, fsize);
  577. return -EINVAL;
  578. }
  579. if (!inst->capabilities) {
  580. i_vpr_e(inst, "%s: capabilities not available\n", __func__);
  581. return -EINVAL;
  582. }
  583. capability = inst->capabilities;
  584. /* only index 0 allowed as per v4l2 spec */
  585. if (fsize->index)
  586. return -EINVAL;
  587. meta_fmt = v4l2_colorformat_from_driver(inst, MSM_VIDC_FMT_META, __func__);
  588. if (fsize->pixel_format != meta_fmt) {
  589. /* validate pixel format */
  590. codec = v4l2_codec_to_driver(inst, fsize->pixel_format, __func__);
  591. if (!codec) {
  592. colorfmt = v4l2_colorformat_to_driver(inst, fsize->pixel_format,
  593. __func__);
  594. if (colorfmt == MSM_VIDC_FMT_NONE) {
  595. i_vpr_e(inst, "%s: unsupported pix fmt %#x\n",
  596. __func__, fsize->pixel_format);
  597. return -EINVAL;
  598. }
  599. }
  600. }
  601. fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
  602. fsize->stepwise.min_width = capability->cap[FRAME_WIDTH].min;
  603. fsize->stepwise.max_width = capability->cap[FRAME_WIDTH].max;
  604. fsize->stepwise.step_width =
  605. capability->cap[FRAME_WIDTH].step_or_mask;
  606. fsize->stepwise.min_height = capability->cap[FRAME_HEIGHT].min;
  607. fsize->stepwise.max_height = capability->cap[FRAME_HEIGHT].max;
  608. fsize->stepwise.step_height =
  609. capability->cap[FRAME_HEIGHT].step_or_mask;
  610. return 0;
  611. }
  612. EXPORT_SYMBOL(msm_vidc_enum_framesizes);
  613. int msm_vidc_enum_frameintervals(void *instance, struct v4l2_frmivalenum *fival)
  614. {
  615. struct msm_vidc_inst *inst = instance;
  616. struct msm_vidc_core *core;
  617. struct msm_vidc_inst_capability *capability;
  618. enum msm_vidc_colorformat_type colorfmt;
  619. u32 fps, mbpf;
  620. u32 meta_fmt;
  621. if (!inst || !fival) {
  622. d_vpr_e("%s: invalid params: %pK %pK\n",
  623. __func__, inst, fival);
  624. return -EINVAL;
  625. }
  626. if (is_decode_session(inst)) {
  627. i_vpr_e(inst, "%s: not supported by decoder\n", __func__);
  628. return -ENOTTY;
  629. }
  630. core = inst->core;
  631. if (!inst->capabilities || !core->capabilities) {
  632. i_vpr_e(inst, "%s: capabilities not available\n", __func__);
  633. return -EINVAL;
  634. }
  635. capability = inst->capabilities;
  636. /* only index 0 allowed as per v4l2 spec */
  637. if (fival->index)
  638. return -EINVAL;
  639. meta_fmt = v4l2_colorformat_from_driver(inst, MSM_VIDC_FMT_META, __func__);
  640. if (fival->pixel_format != meta_fmt) {
  641. /* validate pixel format */
  642. colorfmt = v4l2_colorformat_to_driver(inst, fival->pixel_format, __func__);
  643. if (colorfmt == MSM_VIDC_FMT_NONE) {
  644. i_vpr_e(inst, "%s: unsupported pix fmt %#x\n",
  645. __func__, fival->pixel_format);
  646. return -EINVAL;
  647. }
  648. }
  649. /* validate resolution */
  650. if (fival->width > capability->cap[FRAME_WIDTH].max ||
  651. fival->width < capability->cap[FRAME_WIDTH].min ||
  652. fival->height > capability->cap[FRAME_HEIGHT].max ||
  653. fival->height < capability->cap[FRAME_HEIGHT].min) {
  654. i_vpr_e(inst, "%s: unsupported resolution %u x %u\n", __func__,
  655. fival->width, fival->height);
  656. return -EINVAL;
  657. }
  658. /* calculate max supported fps for a given resolution */
  659. mbpf = NUM_MBS_PER_FRAME(fival->height, fival->width);
  660. fps = core->capabilities[MAX_MBPS].value / mbpf;
  661. fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
  662. fival->stepwise.min.numerator = 1;
  663. fival->stepwise.min.denominator =
  664. min_t(u32, fps, capability->cap[FRAME_RATE].max);
  665. fival->stepwise.max.numerator = 1;
  666. fival->stepwise.max.denominator = 1;
  667. fival->stepwise.step.numerator = 1;
  668. fival->stepwise.step.denominator = capability->cap[FRAME_RATE].max;
  669. return 0;
  670. }
  671. EXPORT_SYMBOL(msm_vidc_enum_frameintervals);
  672. int msm_vidc_subscribe_event(void *instance,
  673. const struct v4l2_event_subscription *sub)
  674. {
  675. int rc = 0;
  676. struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
  677. if (!inst || !sub) {
  678. d_vpr_e("%s: invalid params\n", __func__);
  679. return -EINVAL;
  680. }
  681. i_vpr_h(inst, "%s: type %d id %d\n", __func__, sub->type, sub->id);
  682. if (inst->domain == MSM_VIDC_DECODER)
  683. rc = msm_vdec_subscribe_event(inst, sub);
  684. if (inst->domain == MSM_VIDC_ENCODER)
  685. rc = msm_venc_subscribe_event(inst, sub);
  686. return rc;
  687. }
  688. EXPORT_SYMBOL(msm_vidc_subscribe_event);
  689. int msm_vidc_unsubscribe_event(void *instance,
  690. const struct v4l2_event_subscription *sub)
  691. {
  692. int rc = 0;
  693. struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
  694. if (!inst || !sub) {
  695. d_vpr_e("%s: invalid params\n", __func__);
  696. return -EINVAL;
  697. }
  698. i_vpr_h(inst, "%s: type %d id %d\n", __func__, sub->type, sub->id);
  699. rc = v4l2_event_unsubscribe(&inst->event_handler, sub);
  700. if (rc)
  701. i_vpr_e(inst, "%s: failed, type %d id %d\n",
  702. __func__, sub->type, sub->id);
  703. return rc;
  704. }
  705. EXPORT_SYMBOL(msm_vidc_unsubscribe_event);
  706. int msm_vidc_dqevent(void *instance, struct v4l2_event *event)
  707. {
  708. int rc = 0;
  709. struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
  710. if (!inst || !event) {
  711. d_vpr_e("%s: invalid params\n", __func__);
  712. return -EINVAL;
  713. }
  714. rc = v4l2_event_dequeue(&inst->event_handler, event, false);
  715. if (rc)
  716. i_vpr_e(inst, "%s: fialed\n", __func__);
  717. return rc;
  718. }
  719. EXPORT_SYMBOL(msm_vidc_dqevent);
  720. void *msm_vidc_open(void *vidc_core, u32 session_type)
  721. {
  722. int rc = 0;
  723. struct msm_vidc_inst *inst = NULL;
  724. struct msm_vidc_core *core;
  725. int i = 0;
  726. d_vpr_h("%s: %s\n", __func__, video_banner);
  727. core = vidc_core;
  728. if (!core) {
  729. d_vpr_e("%s: invalid params\n", __func__);
  730. return NULL;
  731. }
  732. if (session_type != MSM_VIDC_DECODER &&
  733. session_type != MSM_VIDC_ENCODER) {
  734. d_vpr_e("%s: invalid session_type %d\n",
  735. __func__, session_type);
  736. return NULL;
  737. }
  738. rc = msm_vidc_core_init(core);
  739. if (rc)
  740. return NULL;
  741. rc = msm_vidc_core_init_wait(core);
  742. if (rc)
  743. return NULL;
  744. rc = msm_vidc_vmem_alloc(sizeof(*inst), (void **)&inst, "inst memory");
  745. if (rc)
  746. return NULL;
  747. inst->core = core;
  748. inst->domain = session_type;
  749. inst->session_id = hash32_ptr(inst);
  750. msm_vidc_change_state(inst, MSM_VIDC_OPEN, __func__);
  751. inst->sub_state = MSM_VIDC_SUB_STATE_NONE;
  752. strlcpy(inst->sub_state_name, "SUB_STATE_NONE", sizeof(inst->sub_state_name));
  753. inst->active = true;
  754. inst->request = false;
  755. inst->ipsc_properties_set = false;
  756. inst->opsc_properties_set = false;
  757. inst->has_bframe = false;
  758. inst->auto_framerate = DEFAULT_FPS << 16;
  759. inst->initial_time_us = ktime_get_ns() / 1000;
  760. kref_init(&inst->kref);
  761. mutex_init(&inst->lock);
  762. mutex_init(&inst->request_lock);
  763. mutex_init(&inst->client_lock);
  764. msm_vidc_update_debug_str(inst);
  765. i_vpr_h(inst, "Opening video instance: %d\n", session_type);
  766. rc = call_mem_op(core, pools_init, inst);
  767. if (rc) {
  768. i_vpr_e(inst, "%s: failed to init pool buffers\n", __func__);
  769. msm_vidc_vmem_free((void **)&inst);
  770. return NULL;
  771. }
  772. INIT_LIST_HEAD(&inst->caps_list);
  773. INIT_LIST_HEAD(&inst->timestamps.list);
  774. INIT_LIST_HEAD(&inst->ts_reorder.list);
  775. INIT_LIST_HEAD(&inst->buffers.input.list);
  776. INIT_LIST_HEAD(&inst->buffers.input_meta.list);
  777. INIT_LIST_HEAD(&inst->buffers.output.list);
  778. INIT_LIST_HEAD(&inst->buffers.output_meta.list);
  779. INIT_LIST_HEAD(&inst->buffers.read_only.list);
  780. INIT_LIST_HEAD(&inst->buffers.bin.list);
  781. INIT_LIST_HEAD(&inst->buffers.arp.list);
  782. INIT_LIST_HEAD(&inst->buffers.comv.list);
  783. INIT_LIST_HEAD(&inst->buffers.non_comv.list);
  784. INIT_LIST_HEAD(&inst->buffers.line.list);
  785. INIT_LIST_HEAD(&inst->buffers.dpb.list);
  786. INIT_LIST_HEAD(&inst->buffers.persist.list);
  787. INIT_LIST_HEAD(&inst->buffers.vpss.list);
  788. INIT_LIST_HEAD(&inst->buffers.partial_data.list);
  789. INIT_LIST_HEAD(&inst->allocations.bin.list);
  790. INIT_LIST_HEAD(&inst->allocations.arp.list);
  791. INIT_LIST_HEAD(&inst->allocations.comv.list);
  792. INIT_LIST_HEAD(&inst->allocations.non_comv.list);
  793. INIT_LIST_HEAD(&inst->allocations.line.list);
  794. INIT_LIST_HEAD(&inst->allocations.dpb.list);
  795. INIT_LIST_HEAD(&inst->allocations.persist.list);
  796. INIT_LIST_HEAD(&inst->allocations.vpss.list);
  797. INIT_LIST_HEAD(&inst->allocations.partial_data.list);
  798. INIT_LIST_HEAD(&inst->mappings.bin.list);
  799. INIT_LIST_HEAD(&inst->mappings.arp.list);
  800. INIT_LIST_HEAD(&inst->mappings.comv.list);
  801. INIT_LIST_HEAD(&inst->mappings.non_comv.list);
  802. INIT_LIST_HEAD(&inst->mappings.line.list);
  803. INIT_LIST_HEAD(&inst->mappings.dpb.list);
  804. INIT_LIST_HEAD(&inst->mappings.persist.list);
  805. INIT_LIST_HEAD(&inst->mappings.vpss.list);
  806. INIT_LIST_HEAD(&inst->mappings.partial_data.list);
  807. INIT_LIST_HEAD(&inst->children_list);
  808. INIT_LIST_HEAD(&inst->firmware_list);
  809. INIT_LIST_HEAD(&inst->enc_input_crs);
  810. INIT_LIST_HEAD(&inst->dmabuf_tracker);
  811. INIT_LIST_HEAD(&inst->input_timer_list);
  812. INIT_LIST_HEAD(&inst->pending_pkts);
  813. INIT_LIST_HEAD(&inst->fence_list);
  814. INIT_LIST_HEAD(&inst->buffer_stats_list);
  815. for (i = 0; i < MAX_SIGNAL; i++)
  816. init_completion(&inst->completions[i]);
  817. inst->workq = create_singlethread_workqueue("workq");
  818. if (!inst->workq) {
  819. i_vpr_e(inst, "%s: create workq failed\n", __func__);
  820. goto error;
  821. }
  822. INIT_DELAYED_WORK(&inst->stats_work, msm_vidc_stats_handler);
  823. INIT_WORK(&inst->stability_work, msm_vidc_stability_handler);
  824. rc = msm_vidc_vmem_alloc(sizeof(struct msm_vidc_inst_capability),
  825. (void **)&inst->capabilities, "inst capability");
  826. if (rc)
  827. goto error;
  828. rc = msm_vidc_event_queue_init(inst);
  829. if (rc)
  830. goto error;
  831. rc = msm_vidc_vb2_queue_init(inst);
  832. if (rc)
  833. goto error;
  834. if (is_decode_session(inst))
  835. rc = msm_vdec_inst_init(inst);
  836. else if (is_encode_session(inst))
  837. rc = msm_venc_inst_init(inst);
  838. if (rc)
  839. goto error;
  840. rc = msm_vidc_fence_init(inst);
  841. if (rc)
  842. goto error;
  843. rc = msm_vidc_add_session(inst);
  844. if (rc) {
  845. i_vpr_e(inst, "%s: failed to get session id\n", __func__);
  846. goto error;
  847. }
  848. msm_vidc_scale_power(inst, true);
  849. rc = msm_vidc_session_open(inst);
  850. if (rc) {
  851. msm_vidc_core_deinit(core, true);
  852. goto error;
  853. }
  854. inst->debugfs_root =
  855. msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
  856. if (!inst->debugfs_root)
  857. i_vpr_h(inst, "%s: debugfs not available\n", __func__);
  858. return inst;
  859. error:
  860. msm_vidc_close(inst);
  861. return NULL;
  862. }
  863. EXPORT_SYMBOL(msm_vidc_open);
  864. int msm_vidc_close(void *instance)
  865. {
  866. int rc = 0;
  867. struct msm_vidc_inst *inst = instance;
  868. struct msm_vidc_core *core;
  869. if (!inst) {
  870. d_vpr_e("%s: invalid params\n", __func__);
  871. return -EINVAL;
  872. }
  873. core = inst->core;
  874. i_vpr_h(inst, "%s()\n", __func__);
  875. client_lock(inst, __func__);
  876. inst_lock(inst, __func__);
  877. /* print final stats */
  878. msm_vidc_print_stats(inst);
  879. msm_vidc_session_close(inst);
  880. msm_vidc_event_queue_deinit(inst);
  881. msm_vidc_vb2_queue_deinit(inst);
  882. msm_vidc_remove_session(inst);
  883. inst_unlock(inst, __func__);
  884. client_unlock(inst, __func__);
  885. cancel_stability_work_sync(inst);
  886. cancel_stats_work_sync(inst);
  887. msm_vidc_show_stats(inst);
  888. put_inst(inst);
  889. msm_vidc_schedule_core_deinit(core);
  890. return rc;
  891. }
  892. EXPORT_SYMBOL(msm_vidc_close);