msm_vidc.c 22 KB

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