enc-mfc-subdev.c 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566
  1. /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include <media/v4l2-subdev.h>
  14. #include <mach/iommu_domains.h>
  15. #include "enc-subdev.h"
  16. #include "wfd-util.h"
  17. #include <media/msm/vcd_api.h>
  18. #include <media/msm/vidc_init.h>
  19. #include <media/msm/vcd_property.h>
  20. #include <linux/time.h>
  21. #include <linux/ktime.h>
  22. #include <linux/slab.h>
  23. #define VID_ENC_MAX_ENCODER_CLIENTS 1
  24. #define MAX_NUM_CTRLS 20
  25. #define V4L2_FRAME_FLAGS (V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_PFRAME | \
  26. V4L2_BUF_FLAG_BFRAME | V4L2_QCOM_BUF_FLAG_CODECCONFIG)
  27. static long venc_fill_outbuf(struct v4l2_subdev *sd, void *arg);
  28. struct venc_inst {
  29. struct video_client_ctx venc_client;
  30. void *cbdata;
  31. void (*op_buffer_done)(void *cookie, u32 status,
  32. struct vb2_buffer *buf);
  33. void (*ip_buffer_done)(void *cookie, u32 status,
  34. struct mem_region *mregion);
  35. u32 width;
  36. u32 height;
  37. int secure;
  38. struct mem_region unqueued_op_bufs;
  39. bool streaming;
  40. enum venc_framerate_modes framerate_mode;
  41. };
  42. struct venc {
  43. s32 device_handle;
  44. void *virt_base;
  45. struct venc_inst venc_clients[VID_ENC_MAX_ENCODER_CLIENTS];
  46. struct mutex lock;
  47. struct ion_client *iclient;
  48. };
  49. static struct venc venc_p;
  50. static void *venc_map_dev_base_addr(void *device_name)
  51. {
  52. return venc_p.virt_base;
  53. }
  54. static void venc_interrupt_deregister(void)
  55. {
  56. }
  57. static void venc_interrupt_register(void *device_name)
  58. {
  59. }
  60. static void venc_interrupt_clear(void)
  61. {
  62. }
  63. int venc_load_fw(struct v4l2_subdev *sd)
  64. {
  65. return !vidc_load_firmware();
  66. }
  67. static u32 venc_get_empty_client_index(void)
  68. {
  69. u32 i;
  70. u32 found = false;
  71. for (i = 0; i < VID_ENC_MAX_ENCODER_CLIENTS; i++) {
  72. if (!venc_p.venc_clients[i].venc_client.vcd_handle) {
  73. found = true;
  74. break;
  75. }
  76. }
  77. if (!found) {
  78. WFD_MSG_ERR("%s():ERROR No space for new client\n",
  79. __func__);
  80. return -ENOMEM;
  81. }
  82. WFD_MSG_INFO("%s(): available client index = %u\n",
  83. __func__, i);
  84. return i;
  85. }
  86. int venc_init(struct v4l2_subdev *sd, u32 val)
  87. {
  88. struct vcd_init_config vcd_init_config;
  89. mutex_init(&venc_p.lock);
  90. venc_p.virt_base = vidc_get_ioaddr();
  91. vcd_init_config.device_name = "VIDC";
  92. vcd_init_config.map_dev_base_addr = venc_map_dev_base_addr;
  93. vcd_init_config.interrupt_clr = venc_interrupt_clear;
  94. vcd_init_config.register_isr = venc_interrupt_register;
  95. vcd_init_config.deregister_isr = venc_interrupt_deregister;
  96. vcd_init(&vcd_init_config, &venc_p.device_handle);
  97. return 0;
  98. }
  99. static void venc_notify_client(struct video_client_ctx *client_ctx)
  100. {
  101. if (client_ctx)
  102. complete(&client_ctx->event);
  103. }
  104. static void venc_open_done(struct video_client_ctx *client_ctx,
  105. struct vcd_handle_container *handle_container)
  106. {
  107. if (client_ctx) {
  108. if (handle_container)
  109. client_ctx->vcd_handle = handle_container->handle;
  110. else
  111. WFD_MSG_ERR("handle_container is NULL\n");
  112. venc_notify_client(client_ctx);
  113. } else
  114. WFD_MSG_ERR("ERROR. client_ctx is NULL");
  115. }
  116. static void venc_start_done(struct video_client_ctx *client_ctx, u32 status)
  117. {
  118. if (client_ctx)
  119. venc_notify_client(client_ctx);
  120. else
  121. WFD_MSG_ERR("ERROR. client_ctx is NULL");
  122. }
  123. static void venc_stop_done(struct video_client_ctx *client_ctx, u32 status)
  124. {
  125. WFD_MSG_DBG("Inside venc_stop_done: E\n");
  126. if (client_ctx)
  127. venc_notify_client(client_ctx);
  128. else
  129. WFD_MSG_ERR("ERROR. client_ctx is NULL");
  130. WFD_MSG_DBG("Inside venc_stop_done: X\n");
  131. }
  132. static void venc_cb(u32 event, u32 status, void *info, u32 size, void *handle,
  133. void *const client_data)
  134. {
  135. struct venc_inst *inst = client_data;
  136. struct video_client_ctx *client_ctx = &inst->venc_client;
  137. struct vb2_buffer *vbuf;
  138. struct mem_region *mregion;
  139. struct vcd_frame_data *frame_data = (struct vcd_frame_data *)info;
  140. if (!client_ctx) {
  141. WFD_MSG_ERR("Client context is NULL\n");
  142. return;
  143. }
  144. client_ctx->event_status = status;
  145. switch (event) {
  146. case VCD_EVT_RESP_OPEN:
  147. WFD_MSG_DBG("EVENT: open done = %d\n", event);
  148. venc_open_done(client_ctx,
  149. (struct vcd_handle_container *)info);
  150. break;
  151. case VCD_EVT_RESP_INPUT_DONE:
  152. case VCD_EVT_RESP_INPUT_FLUSHED:
  153. WFD_MSG_DBG("EVENT: input done = %d\n", event);
  154. mregion = (struct mem_region *)
  155. frame_data->frm_clnt_data;
  156. inst->ip_buffer_done(inst->cbdata, status, mregion);
  157. break;
  158. case VCD_EVT_RESP_OUTPUT_DONE:
  159. case VCD_EVT_RESP_OUTPUT_FLUSHED:
  160. WFD_MSG_DBG("EVENT: output done = %d\n", event);
  161. vbuf = (struct vb2_buffer *)
  162. frame_data->frm_clnt_data;
  163. vbuf->v4l2_planes[0].bytesused =
  164. frame_data->data_len;
  165. vbuf->v4l2_buf.flags &= ~(V4L2_FRAME_FLAGS);
  166. switch (frame_data->frame) {
  167. case VCD_FRAME_I:
  168. case VCD_FRAME_IDR:
  169. vbuf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
  170. break;
  171. case VCD_FRAME_P:
  172. vbuf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
  173. break;
  174. case VCD_FRAME_B:
  175. vbuf->v4l2_buf.flags |= V4L2_BUF_FLAG_BFRAME;
  176. break;
  177. default:
  178. break;
  179. }
  180. if (frame_data->flags & VCD_FRAME_FLAG_CODECCONFIG)
  181. vbuf->v4l2_buf.flags |= V4L2_QCOM_BUF_FLAG_CODECCONFIG;
  182. vbuf->v4l2_buf.timestamp =
  183. ns_to_timeval(frame_data->time_stamp * NSEC_PER_USEC);
  184. WFD_MSG_DBG("bytes used %d, ts: %d.%d, frame type is %d\n",
  185. frame_data->data_len,
  186. (int)vbuf->v4l2_buf.timestamp.tv_sec,
  187. (int)vbuf->v4l2_buf.timestamp.tv_usec,
  188. frame_data->frame);
  189. /*
  190. * Output buffers are enc-subdev and vcd's problem, so
  191. * if buffer is cached, need to flush before giving to
  192. * client. So doing the dirty stuff in this little context
  193. */
  194. {
  195. unsigned long kvaddr, phys_addr;
  196. s32 buffer_index = -1, ion_flags = 0;
  197. struct ion_handle *ion_handle;
  198. int pmem_fd;
  199. struct file *filp;
  200. bool rc;
  201. rc = vidc_lookup_addr_table(client_ctx,
  202. BUFFER_TYPE_OUTPUT, true,
  203. (unsigned long *)&frame_data->
  204. frm_clnt_data, &kvaddr, &phys_addr,
  205. &pmem_fd, &filp, &buffer_index);
  206. if (rc)
  207. ion_flags = vidc_get_fd_info(client_ctx,
  208. BUFFER_TYPE_OUTPUT, pmem_fd,
  209. kvaddr, buffer_index, &ion_handle);
  210. else
  211. WFD_MSG_ERR("Got an output buffer that we " \
  212. "couldn't recognize!\n");
  213. if (msm_ion_do_cache_op(client_ctx->user_ion_client,
  214. ion_handle, &kvaddr, frame_data->data_len,
  215. ION_IOC_CLEAN_INV_CACHES))
  216. WFD_MSG_ERR("OP buffer flush failed\n");
  217. }
  218. inst->op_buffer_done(inst->cbdata, status, vbuf);
  219. break;
  220. case VCD_EVT_RESP_START:
  221. WFD_MSG_DBG("EVENT: start done = %d\n", event);
  222. venc_start_done(client_ctx, status);
  223. /*TODO: should wait for this event*/
  224. break;
  225. case VCD_EVT_RESP_STOP:
  226. WFD_MSG_DBG("EVENT: not expected = %d\n", event);
  227. venc_stop_done(client_ctx, status);
  228. break;
  229. case VCD_EVT_RESP_FLUSH_INPUT_DONE:
  230. case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
  231. venc_notify_client(client_ctx);
  232. break;
  233. case VCD_EVT_RESP_PAUSE:
  234. case VCD_EVT_IND_OUTPUT_RECONFIG:
  235. WFD_MSG_DBG("EVENT: not expected = %d\n", event);
  236. break;
  237. case VCD_EVT_IND_HWERRFATAL:
  238. case VCD_EVT_IND_RESOURCES_LOST:
  239. WFD_MSG_DBG("EVENT: error = %d\n", event);
  240. break;
  241. default:
  242. WFD_MSG_ERR("Invalid event type = %u\n", event);
  243. break;
  244. }
  245. }
  246. static long venc_open(struct v4l2_subdev *sd, void *arg)
  247. {
  248. u32 client_index;
  249. int rc = 0;
  250. struct venc_inst *inst;
  251. struct video_client_ctx *client_ctx;
  252. struct venc_msg_ops *vmops = arg;
  253. int flags = 0;
  254. mutex_lock(&venc_p.lock);
  255. client_index = venc_get_empty_client_index();
  256. if (client_index < 0) {
  257. WFD_MSG_ERR("No free clients, client_index = %d\n",
  258. client_index);
  259. rc = -ENODEV;
  260. goto no_free_client;
  261. }
  262. inst = &venc_p.venc_clients[client_index];
  263. client_ctx = &inst->venc_client;
  264. init_completion(&client_ctx->event);
  265. mutex_init(&client_ctx->msg_queue_lock);
  266. mutex_init(&client_ctx->enrty_queue_lock);
  267. INIT_LIST_HEAD(&client_ctx->msg_queue);
  268. init_waitqueue_head(&client_ctx->msg_wait);
  269. inst->op_buffer_done = vmops->op_buffer_done;
  270. inst->ip_buffer_done = vmops->ip_buffer_done;
  271. INIT_LIST_HEAD(&inst->unqueued_op_bufs.list);
  272. inst->cbdata = vmops->cbdata;
  273. inst->secure = vmops->secure;
  274. inst->streaming = false;
  275. inst->framerate_mode = VENC_MODE_VFR;
  276. if (vmops->secure) {
  277. WFD_MSG_ERR("OPENING SECURE SESSION\n");
  278. flags |= VCD_CP_SESSION;
  279. }
  280. if (vcd_get_ion_status()) {
  281. client_ctx->user_ion_client = vcd_get_ion_client();
  282. if (!client_ctx->user_ion_client) {
  283. WFD_MSG_ERR("vcd_open ion get client failed");
  284. return -EFAULT;
  285. }
  286. }
  287. rc = vcd_open(venc_p.device_handle, false, venc_cb,
  288. inst, flags);
  289. if (rc) {
  290. WFD_MSG_ERR("vcd_open failed, rc = %d\n", rc);
  291. rc = -ENODEV;
  292. goto no_free_client;
  293. }
  294. wait_for_completion(&client_ctx->event);
  295. if (client_ctx->event_status) {
  296. WFD_MSG_ERR("callback for vcd_open returned error: %u",
  297. client_ctx->event_status);
  298. goto no_free_client;
  299. }
  300. WFD_MSG_ERR("NOTE: client_ctx = %p\n", client_ctx);
  301. vmops->cookie = inst;
  302. sd->dev_priv = inst;
  303. no_free_client:
  304. mutex_unlock(&venc_p.lock);
  305. return rc;
  306. }
  307. static long venc_close(struct v4l2_subdev *sd, void *arg)
  308. {
  309. long rc = 0;
  310. struct venc_inst *inst;
  311. struct video_client_ctx *client_ctx = NULL;
  312. mutex_lock(&venc_p.lock);
  313. inst = sd->dev_priv;
  314. client_ctx = &inst->venc_client;
  315. if (!client_ctx || !client_ctx->vcd_handle) {
  316. WFD_MSG_ERR("Invalid client context in close\n");
  317. rc = -ENODEV;
  318. goto end;
  319. }
  320. rc = vcd_close(client_ctx->vcd_handle);
  321. if (rc) {
  322. WFD_MSG_ERR("Failed to close encoder subdevice\n");
  323. goto end;
  324. }
  325. memset((void *)client_ctx, 0,
  326. sizeof(struct video_client_ctx));
  327. end:
  328. mutex_unlock(&venc_p.lock);
  329. return rc;
  330. }
  331. static long venc_get_buffer_req(struct v4l2_subdev *sd, void *arg)
  332. {
  333. int rc = 0;
  334. struct v4l2_requestbuffers *b = arg;
  335. struct vcd_buffer_requirement buf_req;
  336. struct venc_inst *inst = sd->dev_priv;
  337. struct video_client_ctx *client_ctx = &inst->venc_client;
  338. if (!client_ctx) {
  339. WFD_MSG_ERR("Invalid client context");
  340. rc = -EINVAL;
  341. goto err;
  342. }
  343. rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
  344. VCD_BUFFER_OUTPUT, &buf_req);
  345. if (rc) {
  346. WFD_MSG_ERR("Failed to get out buf reqs rc = %d", rc);
  347. goto err;
  348. }
  349. buf_req.actual_count = b->count = max(buf_req.min_count, b->count);
  350. rc = vcd_set_buffer_requirements(client_ctx->vcd_handle,
  351. VCD_BUFFER_OUTPUT, &buf_req);
  352. if (rc) {
  353. WFD_MSG_ERR("Failed to set out buf reqs rc = %d", rc);
  354. goto err;
  355. }
  356. err:
  357. return rc;
  358. }
  359. static long venc_set_buffer_req(struct v4l2_subdev *sd, void *arg)
  360. {
  361. int rc = 0;
  362. struct bufreq *b = arg;
  363. struct vcd_buffer_requirement buf_req;
  364. struct venc_inst *inst = sd->dev_priv;
  365. struct video_client_ctx *client_ctx = &inst->venc_client;
  366. int aligned_width, aligned_height;
  367. if (!client_ctx) {
  368. WFD_MSG_ERR("Invalid client context");
  369. rc = -EINVAL;
  370. goto err;
  371. }
  372. aligned_width = ALIGN(b->width, 16);
  373. aligned_height = ALIGN(b->height, 16);
  374. if (aligned_width != b->width) {
  375. WFD_MSG_ERR("Width not 16 byte aligned\n");
  376. rc = -EINVAL;
  377. goto err;
  378. }
  379. buf_req.actual_count = b->count;
  380. buf_req.min_count = b->count;
  381. buf_req.max_count = b->count;
  382. buf_req.sz = ALIGN(aligned_height * aligned_width, SZ_2K)
  383. + ALIGN(aligned_height * aligned_width * 1/2, SZ_2K);
  384. buf_req.align = SZ_4K;
  385. inst->width = b->width;
  386. inst->height = b->height;
  387. rc = vcd_set_buffer_requirements(client_ctx->vcd_handle,
  388. VCD_BUFFER_INPUT, &buf_req);
  389. if (rc) {
  390. WFD_MSG_ERR("Failed to get out buf reqs rc = %d", rc);
  391. goto err;
  392. }
  393. b->size = buf_req.sz;
  394. err:
  395. return rc;
  396. }
  397. static long venc_start(struct v4l2_subdev *sd)
  398. {
  399. struct venc_inst *inst = sd->dev_priv;
  400. struct video_client_ctx *client_ctx = &inst->venc_client;
  401. struct mem_region *curr = NULL, *temp = NULL;
  402. int rc;
  403. if (!client_ctx) {
  404. WFD_MSG_ERR("Client context is NULL");
  405. return -EINVAL;
  406. }
  407. rc = vcd_encode_start(client_ctx->vcd_handle);
  408. if (rc) {
  409. WFD_MSG_ERR("vcd_encode_start failed, rc = %d\n", rc);
  410. goto err;
  411. }
  412. wait_for_completion(&client_ctx->event);
  413. if (client_ctx->event_status)
  414. WFD_MSG_ERR("callback for vcd_encode_start returned error: %u",
  415. client_ctx->event_status);
  416. inst->streaming = true;
  417. /* Push any buffers that we have held back */
  418. list_for_each_entry_safe(curr, temp,
  419. &inst->unqueued_op_bufs.list, list) {
  420. venc_fill_outbuf(sd, curr);
  421. list_del(&curr->list);
  422. kfree(curr);
  423. }
  424. err:
  425. return rc;
  426. }
  427. static long venc_stop(struct v4l2_subdev *sd)
  428. {
  429. struct venc_inst *inst = sd->dev_priv;
  430. struct video_client_ctx *client_ctx = &inst->venc_client;
  431. struct mem_region *curr = NULL, *temp = NULL;
  432. int rc;
  433. if (!client_ctx) {
  434. WFD_MSG_ERR("Client context is NULL");
  435. return -EINVAL;
  436. }
  437. rc = vcd_stop(client_ctx->vcd_handle);
  438. wait_for_completion(&client_ctx->event);
  439. inst->streaming = false;
  440. /* Drop whatever frames we haven't queued */
  441. list_for_each_entry_safe(curr, temp,
  442. &inst->unqueued_op_bufs.list, list) {
  443. inst->op_buffer_done(inst->cbdata, 0,
  444. (struct vb2_buffer *)curr->cookie);
  445. list_del(&curr->list);
  446. kfree(curr);
  447. }
  448. return rc;
  449. }
  450. static long venc_set_codec(struct video_client_ctx *client_ctx, __s32 codec)
  451. {
  452. struct vcd_property_codec vcd_property_codec;
  453. struct vcd_property_hdr vcd_property_hdr;
  454. vcd_property_hdr.prop_id = VCD_I_CODEC;
  455. vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
  456. vcd_property_codec.codec = VCD_CODEC_H264;
  457. switch (codec) {
  458. case V4L2_PIX_FMT_H264:
  459. vcd_property_codec.codec = VCD_CODEC_H264;
  460. break;
  461. case V4L2_PIX_FMT_MPEG4:
  462. vcd_property_codec.codec = VCD_CODEC_MPEG4;
  463. break;
  464. default:
  465. WFD_MSG_ERR("Codec not supported, defaulting to h264\n");
  466. break;
  467. }
  468. return vcd_set_property(client_ctx->vcd_handle,
  469. &vcd_property_hdr, &vcd_property_codec);
  470. }
  471. static long venc_set_codec_level(struct video_client_ctx *client_ctx,
  472. __s32 codec, __s32 level)
  473. {
  474. struct vcd_property_level vcd_property_level;
  475. struct vcd_property_hdr vcd_property_hdr;
  476. struct vcd_property_codec vcd_property_codec;
  477. int rc = 0;
  478. int mpeg4_base = VCD_LEVEL_MPEG4_0;
  479. int h264_base = VCD_LEVEL_H264_1;
  480. /* Validate params */
  481. vcd_property_hdr.prop_id = VCD_I_CODEC;
  482. vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
  483. rc = vcd_get_property(client_ctx->vcd_handle,
  484. &vcd_property_hdr, &vcd_property_codec);
  485. if (rc < 0) {
  486. WFD_MSG_ERR("Error getting codec property");
  487. rc = -EINVAL;
  488. goto err;
  489. }
  490. if (!((vcd_property_codec.codec == VCD_CODEC_H264
  491. && codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) ||
  492. (vcd_property_codec.codec == VCD_CODEC_MPEG4
  493. && codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL))) {
  494. WFD_MSG_ERR("Attempting to set %d for codec type %d",
  495. codec, vcd_property_codec.codec);
  496. rc = -EINVAL;
  497. goto err;
  498. }
  499. /* Set property */
  500. vcd_property_hdr.prop_id = VCD_I_LEVEL;
  501. vcd_property_hdr.sz = sizeof(struct vcd_property_level);
  502. if (codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL) {
  503. vcd_property_level.level = mpeg4_base + level;
  504. if (vcd_property_level.level < VCD_LEVEL_MPEG4_0
  505. || vcd_property_level.level > VCD_LEVEL_MPEG4_X) {
  506. WFD_MSG_ERR("Level (%d) out of range for codec (%d)\n",
  507. level, codec);
  508. rc = -EINVAL;
  509. goto err;
  510. }
  511. } else if (codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
  512. vcd_property_level.level = h264_base + level;
  513. if (vcd_property_level.level < VCD_LEVEL_H264_1
  514. || vcd_property_level.level > VCD_LEVEL_H264_5p1) {
  515. WFD_MSG_ERR("Level (%d) out of range for codec (%d)\n",
  516. level, codec);
  517. rc = -EINVAL;
  518. goto err;
  519. }
  520. } else {
  521. WFD_MSG_ERR("Codec (%d) not supported, not setting level (%d)",
  522. codec, level);
  523. rc = -ENOTSUPP;
  524. goto err;
  525. }
  526. rc = vcd_set_property(client_ctx->vcd_handle,
  527. &vcd_property_hdr, &vcd_property_level);
  528. err:
  529. return rc;
  530. }
  531. static long venc_get_codec_level(struct video_client_ctx *client_ctx,
  532. __s32 codec, __s32 *level)
  533. {
  534. struct vcd_property_level vcd_property_level;
  535. struct vcd_property_hdr vcd_property_hdr;
  536. struct vcd_property_codec vcd_property_codec;
  537. int rc = 0;
  538. int mpeg4_base = VCD_LEVEL_MPEG4_0;
  539. int h264_base = VCD_LEVEL_H264_1;
  540. /* Validate params */
  541. vcd_property_hdr.prop_id = VCD_I_CODEC;
  542. vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
  543. rc = vcd_get_property(client_ctx->vcd_handle,
  544. &vcd_property_hdr, &vcd_property_codec);
  545. if (rc < 0) {
  546. WFD_MSG_ERR("Error getting codec property");
  547. rc = -EINVAL;
  548. goto err;
  549. }
  550. if (!((vcd_property_codec.codec == VCD_CODEC_H264
  551. && codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) ||
  552. (vcd_property_codec.codec == VCD_CODEC_MPEG4
  553. && codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL))) {
  554. WFD_MSG_ERR("Attempting to get %d for codec type %d",
  555. codec, vcd_property_codec.codec);
  556. rc = -EINVAL;
  557. goto err;
  558. }
  559. vcd_property_hdr.prop_id = VCD_I_LEVEL;
  560. vcd_property_hdr.sz = sizeof(struct vcd_property_level);
  561. rc = vcd_get_property(client_ctx->vcd_handle,
  562. &vcd_property_hdr, &vcd_property_level);
  563. if (rc < 0) {
  564. rc = -EINVAL;
  565. goto err;
  566. }
  567. if (codec == V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL) {
  568. *level = vcd_property_level.level - mpeg4_base;
  569. } else if (codec == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
  570. *level = vcd_property_level.level - h264_base;
  571. } else {
  572. WFD_MSG_ERR("Codec (%d) not supported", codec);
  573. rc = -ENOTSUPP;
  574. goto err;
  575. }
  576. err:
  577. return rc;
  578. }
  579. static long venc_set_codec_profile(struct video_client_ctx *client_ctx,
  580. __s32 codec, __s32 profile)
  581. {
  582. struct vcd_property_profile vcd_property_profile;
  583. struct vcd_property_hdr vcd_property_hdr;
  584. struct vcd_property_codec vcd_property_codec;
  585. struct vcd_property_i_period vcd_property_i_period;
  586. int rc = 0;
  587. /* Validate params */
  588. vcd_property_hdr.prop_id = VCD_I_CODEC;
  589. vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
  590. rc = vcd_get_property(client_ctx->vcd_handle,
  591. &vcd_property_hdr, &vcd_property_codec);
  592. if (rc < 0) {
  593. WFD_MSG_ERR("Error getting codec property");
  594. rc = -EINVAL;
  595. goto err_set_profile;
  596. }
  597. if (!((vcd_property_codec.codec == VCD_CODEC_H264
  598. && codec == V4L2_CID_MPEG_VIDEO_H264_PROFILE) ||
  599. (vcd_property_codec.codec == VCD_CODEC_MPEG4
  600. && codec == V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE))) {
  601. WFD_MSG_ERR("Attempting to set %d for codec type %d",
  602. codec, vcd_property_codec.codec);
  603. rc = -EINVAL;
  604. goto err_set_profile;
  605. }
  606. /* Set property */
  607. vcd_property_hdr.prop_id = VCD_I_PROFILE;
  608. vcd_property_hdr.sz = sizeof(struct vcd_property_profile);
  609. if (codec == V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE) {
  610. switch (profile) {
  611. case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
  612. vcd_property_profile.profile = VCD_PROFILE_MPEG4_SP;
  613. break;
  614. case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
  615. vcd_property_profile.profile = VCD_PROFILE_MPEG4_ASP;
  616. break;
  617. default:
  618. WFD_MSG_ERR("Profile %d not supported, defaulting " \
  619. "to simple (%d)", profile,
  620. VCD_PROFILE_MPEG4_SP);
  621. vcd_property_profile.profile = VCD_PROFILE_MPEG4_SP;
  622. break;
  623. }
  624. } else if (codec == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
  625. switch (profile) {
  626. case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
  627. vcd_property_profile.profile =
  628. VCD_PROFILE_H264_BASELINE;
  629. break;
  630. case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
  631. vcd_property_profile.profile = VCD_PROFILE_H264_MAIN;
  632. break;
  633. case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
  634. vcd_property_profile.profile = VCD_PROFILE_H264_HIGH;
  635. break;
  636. default:
  637. WFD_MSG_ERR("Profile %d not supported, defaulting " \
  638. "to baseline (%d)", profile,
  639. VCD_PROFILE_H264_BASELINE);
  640. vcd_property_profile.profile =
  641. VCD_PROFILE_H264_BASELINE;
  642. break;
  643. }
  644. } else {
  645. WFD_MSG_ERR("Codec (%d) not supported, not "\
  646. "setting profile (%d)", codec, profile);
  647. rc = -ENOTSUPP;
  648. goto err_set_profile;
  649. }
  650. rc = vcd_set_property(client_ctx->vcd_handle,
  651. &vcd_property_hdr, &vcd_property_profile);
  652. /* Disable B-frames, since VSG doesn't support out of order i/p bufs */
  653. vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD;
  654. vcd_property_hdr.sz = sizeof(struct vcd_property_i_period);
  655. rc = vcd_get_property(client_ctx->vcd_handle,
  656. &vcd_property_hdr, &vcd_property_i_period);
  657. if (rc) {
  658. WFD_MSG_ERR("Error getting I-period property");
  659. goto err_set_profile;
  660. }
  661. vcd_property_i_period.b_frames = 0;
  662. rc = vcd_set_property(client_ctx->vcd_handle,
  663. &vcd_property_hdr, &vcd_property_i_period);
  664. if (rc) {
  665. WFD_MSG_ERR("Error setting I-period property");
  666. goto err_set_profile;
  667. }
  668. err_set_profile:
  669. return rc;
  670. }
  671. static long venc_get_codec_profile(struct video_client_ctx *client_ctx,
  672. __s32 codec, __s32 *profile)
  673. {
  674. struct vcd_property_profile vcd_property_profile;
  675. struct vcd_property_hdr vcd_property_hdr;
  676. struct vcd_property_codec vcd_property_codec;
  677. int rc = 0;
  678. /* Validate params */
  679. vcd_property_hdr.prop_id = VCD_I_CODEC;
  680. vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
  681. rc = vcd_get_property(client_ctx->vcd_handle,
  682. &vcd_property_hdr, &vcd_property_codec);
  683. if (rc < 0) {
  684. WFD_MSG_ERR("Error getting codec property");
  685. rc = -EINVAL;
  686. goto err;
  687. }
  688. if (!((vcd_property_codec.codec == VCD_CODEC_H264
  689. && codec == V4L2_CID_MPEG_VIDEO_H264_PROFILE) ||
  690. (vcd_property_codec.codec == VCD_CODEC_MPEG4
  691. && codec == V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE))) {
  692. WFD_MSG_ERR("Attempting to set %d for codec type %d",
  693. codec, vcd_property_codec.codec);
  694. rc = -EINVAL;
  695. goto err;
  696. }
  697. /* Set property */
  698. vcd_property_hdr.prop_id = VCD_I_PROFILE;
  699. vcd_property_hdr.sz = sizeof(struct vcd_property_profile);
  700. rc = vcd_get_property(client_ctx->vcd_handle,
  701. &vcd_property_hdr, &vcd_property_profile);
  702. if (rc < 0) {
  703. WFD_MSG_ERR("Unable to get property");
  704. rc = -EINVAL;
  705. goto err;
  706. }
  707. switch (vcd_property_profile.profile) {
  708. case VCD_PROFILE_MPEG4_SP:
  709. *profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
  710. break;
  711. case VCD_PROFILE_MPEG4_ASP:
  712. *profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
  713. break;
  714. case VCD_PROFILE_H264_BASELINE:
  715. *profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
  716. break;
  717. case VCD_PROFILE_H264_MAIN:
  718. *profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
  719. break;
  720. case VCD_PROFILE_H264_HIGH:
  721. *profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
  722. break;
  723. default:
  724. WFD_MSG_ERR("Unexpected profile");
  725. rc = -EINVAL;
  726. goto err;
  727. break;
  728. }
  729. err:
  730. return rc;
  731. }
  732. static long venc_set_h264_intra_period(struct video_client_ctx *client_ctx,
  733. __s32 period)
  734. {
  735. struct vcd_property_i_period vcd_property_i_period;
  736. struct vcd_property_codec vcd_property_codec;
  737. struct vcd_property_hdr vcd_property_hdr;
  738. int rc = 0;
  739. vcd_property_hdr.prop_id = VCD_I_CODEC;
  740. vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
  741. rc = vcd_get_property(client_ctx->vcd_handle,
  742. &vcd_property_hdr, &vcd_property_codec);
  743. if (rc < 0) {
  744. WFD_MSG_ERR("Error getting codec property\n");
  745. goto err;
  746. }
  747. if (vcd_property_codec.codec != VCD_CODEC_H264) {
  748. rc = -ENOTSUPP;
  749. WFD_MSG_ERR("Control not supported for non H264 codec\n");
  750. goto err;
  751. }
  752. vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD;
  753. vcd_property_hdr.sz = sizeof(struct vcd_property_i_period);
  754. vcd_property_i_period.p_frames = period - 1;
  755. vcd_property_i_period.b_frames = 0;
  756. rc = vcd_set_property(client_ctx->vcd_handle,
  757. &vcd_property_hdr, &vcd_property_i_period);
  758. if (rc < 0) {
  759. WFD_MSG_ERR("Error setting intra period\n");
  760. goto err;
  761. }
  762. err:
  763. return rc;
  764. }
  765. static long venc_get_h264_intra_period(struct video_client_ctx *client_ctx,
  766. __s32 *period)
  767. {
  768. struct vcd_property_i_period vcd_property_i_period;
  769. struct vcd_property_codec vcd_property_codec;
  770. struct vcd_property_hdr vcd_property_hdr;
  771. int rc = 0;
  772. vcd_property_hdr.prop_id = VCD_I_CODEC;
  773. vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
  774. rc = vcd_get_property(client_ctx->vcd_handle,
  775. &vcd_property_hdr, &vcd_property_codec);
  776. if (rc < 0) {
  777. WFD_MSG_ERR("Error getting codec property\n");
  778. goto err;
  779. }
  780. if (vcd_property_codec.codec != VCD_CODEC_H264) {
  781. rc = -ENOTSUPP;
  782. WFD_MSG_ERR("Control not supported for non H264 codec\n");
  783. goto err;
  784. }
  785. vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD;
  786. vcd_property_hdr.sz = sizeof(struct vcd_property_i_period);
  787. rc = vcd_get_property(client_ctx->vcd_handle,
  788. &vcd_property_hdr, &vcd_property_i_period);
  789. if (rc < 0) {
  790. WFD_MSG_ERR("Error getting intra period\n");
  791. goto err;
  792. }
  793. *period = vcd_property_i_period.p_frames + 1;
  794. err:
  795. return rc;
  796. }
  797. static long venc_request_frame(struct video_client_ctx *client_ctx, __s32 type)
  798. {
  799. struct vcd_property_req_i_frame vcd_property_req_i_frame;
  800. struct vcd_property_hdr vcd_property_hdr;
  801. vcd_property_hdr.prop_id = VCD_I_REQ_IFRAME;
  802. vcd_property_hdr.sz = sizeof(struct vcd_property_req_i_frame);
  803. vcd_property_req_i_frame.req_i_frame = 1;
  804. return vcd_set_property(client_ctx->vcd_handle,
  805. &vcd_property_hdr, &vcd_property_req_i_frame);
  806. }
  807. static long venc_set_bitrate(struct video_client_ctx *client_ctx,
  808. __s32 bitrate)
  809. {
  810. struct vcd_property_hdr vcd_property_hdr;
  811. struct vcd_property_target_bitrate bit_rate;
  812. if (!client_ctx || !bitrate)
  813. return -EINVAL;
  814. vcd_property_hdr.prop_id = VCD_I_TARGET_BITRATE;
  815. vcd_property_hdr.sz =
  816. sizeof(struct vcd_property_target_bitrate);
  817. bit_rate.target_bitrate = bitrate;
  818. return vcd_set_property(client_ctx->vcd_handle,
  819. &vcd_property_hdr, &bit_rate);
  820. }
  821. static long venc_get_bitrate(struct video_client_ctx *client_ctx,
  822. __s32 *bitrate)
  823. {
  824. struct vcd_property_hdr vcd_property_hdr;
  825. struct vcd_property_target_bitrate bit_rate;
  826. int rc = 0;
  827. if (!client_ctx || !bitrate)
  828. return -EINVAL;
  829. vcd_property_hdr.prop_id = VCD_I_TARGET_BITRATE;
  830. vcd_property_hdr.sz =
  831. sizeof(struct vcd_property_target_bitrate);
  832. rc = vcd_get_property(client_ctx->vcd_handle,
  833. &vcd_property_hdr, &bit_rate);
  834. if (rc < 0) {
  835. WFD_MSG_ERR("Failed getting property for bitrate");
  836. return rc;
  837. }
  838. *bitrate = bit_rate.target_bitrate;
  839. return rc;
  840. }
  841. static long venc_set_bitrate_mode(struct video_client_ctx *client_ctx,
  842. __s32 mode)
  843. {
  844. struct vcd_property_hdr vcd_property_hdr;
  845. struct vcd_property_rate_control rate_control;
  846. int rc = 0;
  847. if (!client_ctx) {
  848. rc = -EINVAL;
  849. goto err;
  850. }
  851. vcd_property_hdr.prop_id = VCD_I_RATE_CONTROL;
  852. vcd_property_hdr.sz = sizeof(struct vcd_property_rate_control);
  853. /*
  854. * XXX: V4L doesn't seem have a control to toggle between CFR
  855. * and VFR, so assuming worse case VFR.
  856. */
  857. switch (mode) {
  858. case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
  859. rate_control.rate_control = VCD_RATE_CONTROL_VBR_VFR;
  860. break;
  861. case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
  862. rate_control.rate_control = VCD_RATE_CONTROL_CBR_VFR;
  863. break;
  864. default:
  865. WFD_MSG_ERR("unknown bitrate mode %d", mode);
  866. rc = -EINVAL;
  867. goto err;
  868. }
  869. rc = vcd_set_property(client_ctx->vcd_handle,
  870. &vcd_property_hdr, &rate_control);
  871. err:
  872. return rc;
  873. }
  874. static long venc_get_bitrate_mode(struct video_client_ctx *client_ctx,
  875. __s32 *mode)
  876. {
  877. struct vcd_property_hdr vcd_property_hdr;
  878. struct vcd_property_rate_control rate_control;
  879. int rc = 0;
  880. if (!client_ctx)
  881. return -EINVAL;
  882. vcd_property_hdr.prop_id = VCD_I_RATE_CONTROL;
  883. vcd_property_hdr.sz = sizeof(struct vcd_property_rate_control);
  884. rc = vcd_get_property(client_ctx->vcd_handle,
  885. &vcd_property_hdr, &rate_control);
  886. switch (rate_control.rate_control) {
  887. case VCD_RATE_CONTROL_CBR_VFR:
  888. case VCD_RATE_CONTROL_CBR_CFR:
  889. *mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
  890. break;
  891. case VCD_RATE_CONTROL_VBR_VFR:
  892. case VCD_RATE_CONTROL_VBR_CFR:
  893. *mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
  894. break;
  895. default:
  896. WFD_MSG_ERR("unknown bitrate mode %d",
  897. rate_control.rate_control);
  898. return -EINVAL;
  899. }
  900. return 0;
  901. }
  902. static long venc_set_frame_size(struct video_client_ctx *client_ctx,
  903. u32 height, u32 width)
  904. {
  905. struct vcd_property_hdr vcd_property_hdr;
  906. struct vcd_property_frame_size frame_size;
  907. vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
  908. vcd_property_hdr.sz =
  909. sizeof(struct vcd_property_frame_size);
  910. frame_size.height = height;
  911. frame_size.width = width;
  912. return vcd_set_property(client_ctx->vcd_handle,
  913. &vcd_property_hdr, &frame_size);
  914. }
  915. static long venc_set_format(struct v4l2_subdev *sd, void *arg)
  916. {
  917. struct venc_inst *inst;
  918. struct video_client_ctx *client_ctx;
  919. struct v4l2_format *fmt = arg;
  920. struct vcd_buffer_requirement buf_req;
  921. int rc = 0;
  922. inst = sd->dev_priv;
  923. client_ctx = &inst->venc_client;
  924. if (!inst || !client_ctx || !fmt) {
  925. WFD_MSG_ERR("Invalid parameters\n");
  926. return -EINVAL;
  927. }
  928. rc = venc_set_codec(client_ctx, fmt->fmt.pix.pixelformat);
  929. if (rc) {
  930. WFD_MSG_ERR("Failed to set codec, rc = %d\n", rc);
  931. goto err;
  932. }
  933. rc = venc_set_frame_size(client_ctx, fmt->fmt.pix.height,
  934. fmt->fmt.pix.width);
  935. if (rc) {
  936. WFD_MSG_ERR("Failed to set frame size, rc = %d\n", rc);
  937. goto err;
  938. }
  939. rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
  940. VCD_BUFFER_OUTPUT, &buf_req);
  941. if (rc) {
  942. WFD_MSG_ERR("Failed to get buf requrements, rc = %d\n", rc);
  943. goto err;
  944. }
  945. fmt->fmt.pix.sizeimage = buf_req.sz;
  946. err:
  947. return rc;
  948. }
  949. static long venc_set_framerate(struct v4l2_subdev *sd,
  950. void *arg)
  951. {
  952. struct venc_inst *inst = sd->dev_priv;
  953. struct video_client_ctx *client_ctx = &inst->venc_client;
  954. struct v4l2_fract *frate = arg;
  955. struct vcd_property_hdr vcd_property_hdr;
  956. struct vcd_property_frame_rate vcd_frame_rate;
  957. struct vcd_property_vop_timing_constant_delta vcd_delta;
  958. int rc;
  959. vcd_property_hdr.prop_id = VCD_I_FRAME_RATE;
  960. vcd_property_hdr.sz =
  961. sizeof(struct vcd_property_frame_rate);
  962. /* v4l2 passes in "fps" as "spf", so take reciprocal*/
  963. vcd_frame_rate.fps_denominator = frate->numerator;
  964. vcd_frame_rate.fps_numerator = frate->denominator;
  965. rc = vcd_set_property(client_ctx->vcd_handle,
  966. &vcd_property_hdr, &vcd_frame_rate);
  967. if (rc) {
  968. WFD_MSG_ERR("Failed to set frame rate, rc = %d\n", rc);
  969. goto set_framerate_fail;
  970. }
  971. vcd_property_hdr.prop_id = VCD_I_VOP_TIMING_CONSTANT_DELTA;
  972. vcd_property_hdr.sz = sizeof(vcd_delta);
  973. vcd_delta.constant_delta = (frate->numerator * USEC_PER_SEC) /
  974. frate->denominator;
  975. rc = vcd_set_property(client_ctx->vcd_handle,
  976. &vcd_property_hdr, &vcd_delta);
  977. if (rc) {
  978. WFD_MSG_ERR("Failed to set frame delta, rc = %d", rc);
  979. goto set_framerate_fail;
  980. }
  981. set_framerate_fail:
  982. return rc;
  983. }
  984. static long venc_set_framerate_mode(struct v4l2_subdev *sd,
  985. void *arg)
  986. {
  987. struct venc_inst *inst = sd->dev_priv;
  988. inst->framerate_mode = *(enum venc_framerate_modes *)arg;
  989. return 0;
  990. }
  991. static long venc_set_qp_value(struct video_client_ctx *client_ctx,
  992. __s32 frametype, __s32 qp)
  993. {
  994. struct vcd_property_hdr vcd_property_hdr;
  995. struct vcd_property_session_qp vcd_property_session_qp;
  996. int rc = 0;
  997. if (!client_ctx) {
  998. WFD_MSG_ERR("Invalid parameters\n");
  999. return -EINVAL;
  1000. }
  1001. vcd_property_hdr.prop_id = VCD_I_SESSION_QP;
  1002. vcd_property_hdr.sz = sizeof(vcd_property_session_qp);
  1003. rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1004. &vcd_property_session_qp);
  1005. if (rc) {
  1006. WFD_MSG_ERR("Failed to get session qp\n");
  1007. goto err;
  1008. }
  1009. switch (frametype) {
  1010. case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
  1011. vcd_property_session_qp.i_frame_qp = qp;
  1012. break;
  1013. case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
  1014. vcd_property_session_qp.p_frame_qp = qp;
  1015. break;
  1016. case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
  1017. vcd_property_session_qp.b_frame_qp = qp;
  1018. break;
  1019. case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
  1020. case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
  1021. case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
  1022. case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
  1023. case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
  1024. case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
  1025. rc = -ENOTSUPP;
  1026. goto err;
  1027. default:
  1028. rc = -EINVAL;
  1029. goto err;
  1030. }
  1031. rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1032. &vcd_property_session_qp);
  1033. if (rc) {
  1034. WFD_MSG_ERR("Failed to set session qp\n");
  1035. goto err;
  1036. }
  1037. err:
  1038. return rc;
  1039. }
  1040. static long venc_get_qp_value(struct video_client_ctx *client_ctx,
  1041. __s32 frametype, __s32 *qp)
  1042. {
  1043. struct vcd_property_hdr vcd_property_hdr;
  1044. struct vcd_property_session_qp vcd_property_session_qp;
  1045. int rc = 0;
  1046. if (!client_ctx) {
  1047. WFD_MSG_ERR("Invalid parameters\n");
  1048. return -EINVAL;
  1049. }
  1050. vcd_property_hdr.prop_id = VCD_I_SESSION_QP;
  1051. vcd_property_hdr.sz = sizeof(vcd_property_session_qp);
  1052. rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1053. &vcd_property_session_qp);
  1054. if (rc) {
  1055. WFD_MSG_ERR("Failed to get session qp\n");
  1056. goto err;
  1057. }
  1058. switch (frametype) {
  1059. case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
  1060. case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
  1061. case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
  1062. *qp = vcd_property_session_qp.i_frame_qp;
  1063. break;
  1064. case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
  1065. case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
  1066. case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
  1067. *qp = vcd_property_session_qp.p_frame_qp;
  1068. break;
  1069. case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
  1070. case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
  1071. case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
  1072. *qp = vcd_property_session_qp.b_frame_qp;
  1073. break;
  1074. default:
  1075. rc = -EINVAL;
  1076. goto err;
  1077. }
  1078. err:
  1079. return rc;
  1080. }
  1081. static long venc_set_qp_range(struct video_client_ctx *client_ctx,
  1082. __s32 type, __s32 qp)
  1083. {
  1084. struct vcd_property_hdr vcd_property_hdr;
  1085. struct vcd_property_qp_range vcd_property_qp_range;
  1086. int rc = 0;
  1087. if (!client_ctx) {
  1088. WFD_MSG_ERR("Invalid parameters\n");
  1089. return -EINVAL;
  1090. }
  1091. vcd_property_hdr.prop_id = VCD_I_QP_RANGE;
  1092. vcd_property_hdr.sz = sizeof(vcd_property_qp_range);
  1093. rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1094. &vcd_property_qp_range);
  1095. if (rc) {
  1096. WFD_MSG_ERR("Failed to get qp range\n");
  1097. goto err;
  1098. }
  1099. switch (type) {
  1100. case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
  1101. case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
  1102. case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
  1103. vcd_property_qp_range.min_qp = qp;
  1104. break;
  1105. case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
  1106. case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
  1107. case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
  1108. vcd_property_qp_range.max_qp = qp;
  1109. break;
  1110. default:
  1111. rc = -EINVAL;
  1112. goto err;
  1113. }
  1114. rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1115. &vcd_property_qp_range);
  1116. if (rc) {
  1117. WFD_MSG_ERR("Failed to set qp range\n");
  1118. goto err;
  1119. }
  1120. err:
  1121. return rc;
  1122. }
  1123. static long venc_get_qp_range(struct video_client_ctx *client_ctx,
  1124. __s32 type, __s32 *qp)
  1125. {
  1126. struct vcd_property_hdr vcd_property_hdr;
  1127. struct vcd_property_qp_range vcd_property_qp_range;
  1128. int rc = 0;
  1129. if (!client_ctx) {
  1130. WFD_MSG_ERR("Invalid parameters\n");
  1131. return -EINVAL;
  1132. }
  1133. vcd_property_hdr.prop_id = VCD_I_QP_RANGE;
  1134. vcd_property_hdr.sz = sizeof(vcd_property_qp_range);
  1135. rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1136. &vcd_property_qp_range);
  1137. if (rc) {
  1138. WFD_MSG_ERR("Failed to get qp range\n");
  1139. goto err;
  1140. }
  1141. switch (type) {
  1142. case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
  1143. case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
  1144. case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
  1145. *qp = vcd_property_qp_range.min_qp;
  1146. break;
  1147. case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
  1148. case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
  1149. case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
  1150. *qp = vcd_property_qp_range.max_qp;
  1151. break;
  1152. default:
  1153. rc = -EINVAL;
  1154. goto err;
  1155. }
  1156. rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1157. &vcd_property_qp_range);
  1158. if (rc) {
  1159. WFD_MSG_ERR("Failed to set qp range\n");
  1160. goto err;
  1161. }
  1162. err:
  1163. return rc;
  1164. }
  1165. static long venc_set_max_perf_level(struct video_client_ctx *client_ctx,
  1166. __s32 value)
  1167. {
  1168. int rc = 0;
  1169. struct vcd_property_hdr vcd_property_hdr;
  1170. struct vcd_property_perf_level perf;
  1171. int level = 0;
  1172. switch (value) {
  1173. case V4L2_CID_MPEG_VIDC_PERF_LEVEL_PERFORMANCE:
  1174. level = VCD_PERF_LEVEL2;
  1175. break;
  1176. case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
  1177. level = VCD_PERF_LEVEL_TURBO;
  1178. break;
  1179. default:
  1180. WFD_MSG_ERR("Unknown performance level: %d\n", value);
  1181. rc = -ENOTSUPP;
  1182. goto err_set_perf_level;
  1183. }
  1184. vcd_property_hdr.prop_id = VCD_REQ_PERF_LEVEL;
  1185. vcd_property_hdr.sz =
  1186. sizeof(struct vcd_property_perf_level);
  1187. perf.level = level;
  1188. rc = vcd_set_property(client_ctx->vcd_handle,
  1189. &vcd_property_hdr, &perf);
  1190. err_set_perf_level:
  1191. return rc;
  1192. }
  1193. static long venc_set_avc_delimiter(struct video_client_ctx *client_ctx,
  1194. __s32 flag)
  1195. {
  1196. struct vcd_property_hdr vcd_property_hdr;
  1197. struct vcd_property_avc_delimiter_enable delimiter_flag;
  1198. if (!client_ctx)
  1199. return -EINVAL;
  1200. vcd_property_hdr.prop_id = VCD_I_ENABLE_DELIMITER_FLAG;
  1201. vcd_property_hdr.sz =
  1202. sizeof(struct vcd_property_avc_delimiter_enable);
  1203. delimiter_flag.avc_delimiter_enable_flag = flag;
  1204. return vcd_set_property(client_ctx->vcd_handle,
  1205. &vcd_property_hdr, &delimiter_flag);
  1206. }
  1207. static long venc_get_avc_delimiter(struct video_client_ctx *client_ctx,
  1208. __s32 *flag)
  1209. {
  1210. struct vcd_property_hdr vcd_property_hdr;
  1211. struct vcd_property_avc_delimiter_enable delimiter_flag;
  1212. int rc = 0;
  1213. if (!client_ctx || !flag)
  1214. return -EINVAL;
  1215. vcd_property_hdr.prop_id = VCD_I_ENABLE_DELIMITER_FLAG;
  1216. vcd_property_hdr.sz =
  1217. sizeof(struct vcd_property_avc_delimiter_enable);
  1218. rc = vcd_get_property(client_ctx->vcd_handle,
  1219. &vcd_property_hdr, &delimiter_flag);
  1220. if (rc < 0) {
  1221. WFD_MSG_ERR("Failed getting property for delimiter");
  1222. return rc;
  1223. }
  1224. *flag = delimiter_flag.avc_delimiter_enable_flag;
  1225. return rc;
  1226. }
  1227. static long venc_set_vui_timing_info(struct video_client_ctx *client_ctx,
  1228. struct venc_inst *inst, __s32 flag)
  1229. {
  1230. struct vcd_property_hdr vcd_property_hdr;
  1231. struct vcd_property_vui_timing_info_enable vui_timing_info_enable;
  1232. if (!client_ctx)
  1233. return -EINVAL;
  1234. if (inst->framerate_mode == VENC_MODE_VFR) {
  1235. WFD_MSG_ERR("VUI timing info not suported in VFR mode ");
  1236. return -EINVAL;
  1237. }
  1238. vcd_property_hdr.prop_id = VCD_I_ENABLE_VUI_TIMING_INFO;
  1239. vcd_property_hdr.sz =
  1240. sizeof(struct vcd_property_vui_timing_info_enable);
  1241. vui_timing_info_enable.vui_timing_info = flag;
  1242. return vcd_set_property(client_ctx->vcd_handle,
  1243. &vcd_property_hdr, &vui_timing_info_enable);
  1244. }
  1245. static long venc_get_vui_timing_info(struct video_client_ctx *client_ctx,
  1246. __s32 *flag)
  1247. {
  1248. struct vcd_property_hdr vcd_property_hdr;
  1249. struct vcd_property_vui_timing_info_enable vui_timing_info_enable;
  1250. int rc = 0;
  1251. if (!client_ctx || !flag)
  1252. return -EINVAL;
  1253. vcd_property_hdr.prop_id = VCD_I_ENABLE_VUI_TIMING_INFO;
  1254. vcd_property_hdr.sz =
  1255. sizeof(struct vcd_property_vui_timing_info_enable);
  1256. rc = vcd_get_property(client_ctx->vcd_handle,
  1257. &vcd_property_hdr, &vui_timing_info_enable);
  1258. if (rc < 0) {
  1259. WFD_MSG_ERR("Failed getting property for VUI timing info");
  1260. return rc;
  1261. }
  1262. *flag = vui_timing_info_enable.vui_timing_info;
  1263. return rc;
  1264. }
  1265. static long venc_set_header_mode(struct video_client_ctx *client_ctx,
  1266. __s32 mode)
  1267. {
  1268. struct vcd_property_hdr vcd_property_hdr;
  1269. struct vcd_property_sps_pps_for_idr_enable sps_pps_for_idr_enable;
  1270. int rc = 0;
  1271. if (!client_ctx) {
  1272. WFD_MSG_ERR("Invalid parameters\n");
  1273. rc = -EINVAL;
  1274. goto err;
  1275. }
  1276. vcd_property_hdr.prop_id = VCD_I_ENABLE_SPS_PPS_FOR_IDR;
  1277. vcd_property_hdr.sz = sizeof(sps_pps_for_idr_enable);
  1278. switch (mode) {
  1279. case V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE:
  1280. sps_pps_for_idr_enable.sps_pps_for_idr_enable_flag = 0;
  1281. break;
  1282. case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME:
  1283. sps_pps_for_idr_enable.sps_pps_for_idr_enable_flag = 1;
  1284. break;
  1285. case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME:
  1286. default:
  1287. WFD_MSG_ERR("Video header mode %d not supported\n",
  1288. mode);
  1289. rc = -ENOTSUPP;
  1290. goto err;
  1291. }
  1292. rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1293. &sps_pps_for_idr_enable);
  1294. if (rc) {
  1295. WFD_MSG_ERR("Failed to set enable_sps_pps_for_idr\n");
  1296. goto err;
  1297. }
  1298. err:
  1299. return rc;
  1300. }
  1301. static long venc_get_header_mode(struct video_client_ctx *client_ctx,
  1302. __s32 *mode)
  1303. {
  1304. struct vcd_property_hdr vcd_property_hdr;
  1305. struct vcd_property_sps_pps_for_idr_enable sps_pps_for_idr_enable;
  1306. int rc = 0;
  1307. if (!client_ctx) {
  1308. WFD_MSG_ERR("Invalid parameters\n");
  1309. rc = -EINVAL;
  1310. goto err;
  1311. }
  1312. vcd_property_hdr.prop_id = VCD_I_ENABLE_SPS_PPS_FOR_IDR;
  1313. vcd_property_hdr.sz = sizeof(sps_pps_for_idr_enable);
  1314. rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1315. &sps_pps_for_idr_enable);
  1316. if (rc) {
  1317. WFD_MSG_ERR("Failed to get sps/pps for idr enable\n");
  1318. goto err;
  1319. }
  1320. *mode = sps_pps_for_idr_enable.sps_pps_for_idr_enable_flag ?
  1321. V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME :
  1322. V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
  1323. err:
  1324. return rc;
  1325. }
  1326. static long venc_set_multislicing_mode(struct video_client_ctx *client_ctx,
  1327. __u32 control, __s32 value)
  1328. {
  1329. int rc = 0;
  1330. struct vcd_property_hdr vcd_property_hdr;
  1331. struct vcd_property_frame_size vcd_frame_size;
  1332. struct vcd_buffer_requirement vcd_buf_req;
  1333. struct vcd_property_multi_slice vcd_multi_slice;
  1334. if (!client_ctx) {
  1335. WFD_MSG_ERR("Invalid parameters\n");
  1336. rc = -EINVAL;
  1337. goto set_multislicing_mode_fail;
  1338. }
  1339. vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
  1340. vcd_property_hdr.sz =
  1341. sizeof(vcd_frame_size);
  1342. rc = vcd_get_property(client_ctx->vcd_handle,
  1343. &vcd_property_hdr, &vcd_frame_size);
  1344. if (rc) {
  1345. WFD_MSG_ERR("Failed to get frame size\n");
  1346. goto set_multislicing_mode_fail;
  1347. }
  1348. rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
  1349. VCD_BUFFER_OUTPUT, &vcd_buf_req);
  1350. if (rc) {
  1351. WFD_MSG_ERR("Failed to get buf reqs\n");
  1352. goto set_multislicing_mode_fail;
  1353. }
  1354. vcd_property_hdr.prop_id = VCD_I_MULTI_SLICE;
  1355. vcd_property_hdr.sz = sizeof(vcd_multi_slice);
  1356. rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1357. &vcd_multi_slice);
  1358. if (rc) {
  1359. WFD_MSG_ERR("Failed to get multi slice\n");
  1360. goto set_multislicing_mode_fail;
  1361. }
  1362. switch (control) {
  1363. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
  1364. if (vcd_multi_slice.m_slice_sel !=
  1365. VCD_MSLICE_BY_BYTE_COUNT) {
  1366. WFD_MSG_ERR("Not in proper mode\n");
  1367. goto set_multislicing_mode_fail;
  1368. }
  1369. vcd_multi_slice.m_slice_size = value;
  1370. break;
  1371. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
  1372. if (vcd_multi_slice.m_slice_sel !=
  1373. VCD_MSLICE_BY_MB_COUNT) {
  1374. WFD_MSG_ERR("Not in proper mode\n");
  1375. goto set_multislicing_mode_fail;
  1376. }
  1377. vcd_multi_slice.m_slice_size = value;
  1378. break;
  1379. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
  1380. switch (value) {
  1381. case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE:
  1382. vcd_multi_slice.m_slice_sel = VCD_MSLICE_OFF;
  1383. break;
  1384. case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB:
  1385. vcd_multi_slice.m_slice_sel = VCD_MSLICE_BY_MB_COUNT;
  1386. /* Just a temporary size until client calls
  1387. * V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB */
  1388. vcd_multi_slice.m_slice_size =
  1389. (vcd_frame_size.stride / 16) *
  1390. (vcd_frame_size.scan_lines / 16);
  1391. break;
  1392. case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES:
  1393. vcd_multi_slice.m_slice_sel = VCD_MSLICE_BY_BYTE_COUNT;
  1394. /* Just a temporary size until client calls
  1395. * V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES */
  1396. vcd_multi_slice.m_slice_size = vcd_buf_req.sz;
  1397. break;
  1398. default:
  1399. WFD_MSG_ERR("Unrecognized mode %d\n", value);
  1400. rc = -ENOTSUPP;
  1401. goto set_multislicing_mode_fail;
  1402. }
  1403. break;
  1404. default:
  1405. rc = -EINVAL;
  1406. goto set_multislicing_mode_fail;
  1407. }
  1408. rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1409. &vcd_multi_slice);
  1410. if (rc) {
  1411. WFD_MSG_ERR("Failed to set multi slice\n");
  1412. goto set_multislicing_mode_fail;
  1413. }
  1414. set_multislicing_mode_fail:
  1415. return rc;
  1416. }
  1417. static long venc_get_multislicing_mode(struct video_client_ctx *client_ctx,
  1418. __u32 control, __s32 *value)
  1419. {
  1420. int rc = 0;
  1421. struct vcd_property_hdr vcd_property_hdr;
  1422. struct vcd_property_frame_size vcd_frame_size;
  1423. struct vcd_buffer_requirement vcd_buf_req;
  1424. struct vcd_property_multi_slice vcd_multi_slice;
  1425. if (!client_ctx) {
  1426. WFD_MSG_ERR("Invalid parameters\n");
  1427. rc = -EINVAL;
  1428. goto get_multislicing_mode_fail;
  1429. }
  1430. vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
  1431. vcd_property_hdr.sz =
  1432. sizeof(vcd_frame_size);
  1433. rc = vcd_get_property(client_ctx->vcd_handle,
  1434. &vcd_property_hdr, &vcd_frame_size);
  1435. if (rc) {
  1436. WFD_MSG_ERR("Failed to get frame size\n");
  1437. goto get_multislicing_mode_fail;
  1438. }
  1439. vcd_property_hdr.prop_id = VCD_I_MULTI_SLICE;
  1440. vcd_property_hdr.sz = sizeof(vcd_multi_slice);
  1441. rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1442. &vcd_multi_slice);
  1443. if (rc) {
  1444. WFD_MSG_ERR("Failed to get multi slice\n");
  1445. goto get_multislicing_mode_fail;
  1446. }
  1447. rc = vcd_get_buffer_requirements(client_ctx->vcd_handle,
  1448. VCD_BUFFER_OUTPUT, &vcd_buf_req);
  1449. if (rc) {
  1450. WFD_MSG_ERR("Failed to get buf reqs\n");
  1451. goto get_multislicing_mode_fail;
  1452. }
  1453. switch (control) {
  1454. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
  1455. if (vcd_multi_slice.m_slice_sel == VCD_MSLICE_BY_BYTE_COUNT)
  1456. *value = vcd_multi_slice.m_slice_size;
  1457. else {
  1458. WFD_MSG_ERR("Invalid query when in slice mode %d\n",
  1459. vcd_multi_slice.m_slice_sel);
  1460. rc = -EINVAL;
  1461. goto get_multislicing_mode_fail;
  1462. }
  1463. break;
  1464. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
  1465. if (vcd_multi_slice.m_slice_sel == VCD_MSLICE_BY_MB_COUNT)
  1466. *value = vcd_multi_slice.m_slice_size;
  1467. else {
  1468. WFD_MSG_ERR("Invalid query when in slice mode %d\n",
  1469. vcd_multi_slice.m_slice_sel);
  1470. rc = -EINVAL;
  1471. goto get_multislicing_mode_fail;
  1472. }
  1473. break;
  1474. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
  1475. switch (vcd_multi_slice.m_slice_sel) {
  1476. case VCD_MSLICE_OFF:
  1477. *value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
  1478. break;
  1479. case VCD_MSLICE_BY_MB_COUNT:
  1480. *value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
  1481. break;
  1482. case VCD_MSLICE_BY_BYTE_COUNT:
  1483. *value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
  1484. break;
  1485. default:
  1486. WFD_MSG_ERR("Encoder in an unknown mode %d\n",
  1487. vcd_multi_slice.m_slice_sel);
  1488. rc = -ENOENT;
  1489. goto get_multislicing_mode_fail;
  1490. }
  1491. break;
  1492. default:
  1493. rc = -EINVAL;
  1494. goto get_multislicing_mode_fail;
  1495. }
  1496. get_multislicing_mode_fail:
  1497. return rc;
  1498. }
  1499. static long venc_set_entropy_mode(struct video_client_ctx *client_ctx,
  1500. __s32 value)
  1501. {
  1502. struct vcd_property_hdr vcd_property_hdr;
  1503. struct vcd_property_entropy_control entropy_control;
  1504. int rc = 0;
  1505. if (!client_ctx) {
  1506. WFD_MSG_ERR("Invalid parameters\n");
  1507. rc = -EINVAL;
  1508. goto set_entropy_mode_fail;
  1509. }
  1510. vcd_property_hdr.prop_id = VCD_I_ENTROPY_CTRL;
  1511. vcd_property_hdr.sz = sizeof(entropy_control);
  1512. switch (value) {
  1513. case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC:
  1514. entropy_control.entropy_sel = VCD_ENTROPY_SEL_CAVLC;
  1515. break;
  1516. case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC:
  1517. entropy_control.entropy_sel = VCD_ENTROPY_SEL_CABAC;
  1518. entropy_control.cabac_model = VCD_CABAC_MODEL_NUMBER_0;
  1519. break;
  1520. default:
  1521. WFD_MSG_ERR("Entropy type %d not supported\n", value);
  1522. rc = -ENOTSUPP;
  1523. goto set_entropy_mode_fail;
  1524. }
  1525. rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1526. &entropy_control);
  1527. if (rc) {
  1528. WFD_MSG_ERR("Failed to set entropy mode\n");
  1529. goto set_entropy_mode_fail;
  1530. }
  1531. set_entropy_mode_fail:
  1532. return rc;
  1533. }
  1534. static long venc_get_entropy_mode(struct video_client_ctx *client_ctx,
  1535. __s32 *value)
  1536. {
  1537. struct vcd_property_hdr vcd_property_hdr;
  1538. struct vcd_property_entropy_control entropy_control;
  1539. int rc = 0;
  1540. if (!client_ctx || !value) {
  1541. WFD_MSG_ERR("Invalid parameters\n");
  1542. rc = -EINVAL;
  1543. goto get_entropy_mode_fail;
  1544. }
  1545. vcd_property_hdr.prop_id = VCD_I_ENTROPY_CTRL;
  1546. vcd_property_hdr.sz = sizeof(entropy_control);
  1547. rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1548. &entropy_control);
  1549. if (rc) {
  1550. WFD_MSG_ERR("Failed to get entropy mode\n");
  1551. goto get_entropy_mode_fail;
  1552. }
  1553. switch (entropy_control.entropy_sel) {
  1554. case VCD_ENTROPY_SEL_CAVLC:
  1555. *value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
  1556. break;
  1557. case VCD_ENTROPY_SEL_CABAC:
  1558. *value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
  1559. break;
  1560. default:
  1561. WFD_MSG_ERR("Entropy type %d not known\n",
  1562. entropy_control.entropy_sel);
  1563. rc = -EINVAL;
  1564. goto get_entropy_mode_fail;
  1565. }
  1566. get_entropy_mode_fail:
  1567. return rc;
  1568. }
  1569. static long venc_set_cyclic_intra_refresh_mb(
  1570. struct video_client_ctx *client_ctx,
  1571. __s32 value)
  1572. {
  1573. struct vcd_property_hdr vcd_property_hdr;
  1574. struct vcd_property_intra_refresh_mb_number cir_mb_num;
  1575. int rc = 0;
  1576. if (!client_ctx) {
  1577. WFD_MSG_ERR("Invalid parameters\n");
  1578. rc = -EINVAL;
  1579. goto set_cir_mbs_fail;
  1580. }
  1581. vcd_property_hdr.prop_id = VCD_I_INTRA_REFRESH;
  1582. vcd_property_hdr.sz = sizeof(cir_mb_num);
  1583. cir_mb_num.cir_mb_number = value;
  1584. rc = vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1585. &cir_mb_num);
  1586. if (rc) {
  1587. WFD_MSG_ERR("Failed to set CIR MBs\n");
  1588. goto set_cir_mbs_fail;
  1589. }
  1590. set_cir_mbs_fail:
  1591. return rc;
  1592. }
  1593. static long venc_get_cyclic_intra_refresh_mb(
  1594. struct video_client_ctx *client_ctx,
  1595. __s32 *value)
  1596. {
  1597. struct vcd_property_hdr vcd_property_hdr;
  1598. struct vcd_property_intra_refresh_mb_number cir_mb_num;
  1599. int rc = 0;
  1600. if (!client_ctx || !value) {
  1601. WFD_MSG_ERR("Invalid parameters\n");
  1602. rc = -EINVAL;
  1603. goto get_cir_mbs_fail;
  1604. }
  1605. vcd_property_hdr.prop_id = VCD_I_INTRA_REFRESH;
  1606. vcd_property_hdr.sz = sizeof(cir_mb_num);
  1607. rc = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
  1608. &cir_mb_num);
  1609. if (rc) {
  1610. WFD_MSG_ERR("Failed to set CIR MBs\n");
  1611. goto get_cir_mbs_fail;
  1612. }
  1613. *value = cir_mb_num.cir_mb_number;
  1614. get_cir_mbs_fail:
  1615. return rc;
  1616. }
  1617. static long venc_set_input_buffer(struct v4l2_subdev *sd, void *arg)
  1618. {
  1619. struct mem_region *mregion = arg;
  1620. struct venc_inst *inst = sd->dev_priv;
  1621. unsigned long paddr, kvaddr, temp;
  1622. struct video_client_ctx *client_ctx = &inst->venc_client;
  1623. int rc = 0;
  1624. if (!client_ctx || !mregion) {
  1625. WFD_MSG_ERR("Invalid input\n");
  1626. rc = -EINVAL;
  1627. goto ins_table_fail;
  1628. }
  1629. kvaddr = (unsigned long)mregion->kvaddr;
  1630. paddr = (unsigned long)mregion->paddr;
  1631. if (!kvaddr || !paddr) {
  1632. WFD_MSG_ERR("Invalid addresses\n");
  1633. rc = -EINVAL;
  1634. goto ins_table_fail;
  1635. }
  1636. /*
  1637. * Just a note: the third arg of vidc_insert_\
  1638. * addr_table_kernel is supposed to be a userspace
  1639. * address that is used as a key in the table. As
  1640. * these bufs never leave the kernel, we need to have
  1641. * an unique value to use as a key. So re-using kernel
  1642. * virtual addr for this purpose
  1643. */
  1644. rc = vidc_insert_addr_table_kernel(client_ctx,
  1645. BUFFER_TYPE_INPUT, kvaddr, kvaddr,
  1646. paddr, 32, mregion->size);
  1647. if (rc == (u32)false) {
  1648. WFD_MSG_ERR("Failed to insert input buffer into table\n");
  1649. rc = -EFAULT;
  1650. goto ins_table_fail;
  1651. }
  1652. rc = vcd_set_buffer(client_ctx->vcd_handle,
  1653. VCD_BUFFER_INPUT, (u8 *)kvaddr,
  1654. mregion->size);
  1655. if (rc) {
  1656. WFD_MSG_ERR("Failed to set input buffer\n");
  1657. rc = -EFAULT;
  1658. goto set_input_buf_fail;
  1659. }
  1660. return rc;
  1661. set_input_buf_fail:
  1662. vidc_delete_addr_table(client_ctx, BUFFER_TYPE_INPUT,
  1663. kvaddr, &temp);
  1664. ins_table_fail:
  1665. return rc;
  1666. }
  1667. static long venc_set_output_buffer(struct v4l2_subdev *sd, void *arg)
  1668. {
  1669. int rc = 0;
  1670. struct venc_inst *inst = sd->dev_priv;
  1671. struct video_client_ctx *client_ctx = &inst->venc_client;
  1672. struct mem_region *mregion = arg;
  1673. if (!client_ctx || !mregion) {
  1674. WFD_MSG_ERR("Invalid input\n");
  1675. return -EINVAL;
  1676. }
  1677. WFD_MSG_DBG("size = %u, offset = %u fd = %d\n", mregion->size,
  1678. mregion->offset, mregion->fd);
  1679. rc = vidc_insert_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
  1680. mregion->cookie,
  1681. (unsigned long *)&mregion->kvaddr,
  1682. mregion->fd,
  1683. mregion->offset,
  1684. 32,
  1685. mregion->size);
  1686. if (rc == (u32)false) {
  1687. WFD_MSG_ERR("Failed to insert outbuf in table\n");
  1688. rc = -EINVAL;
  1689. goto err;
  1690. }
  1691. WFD_MSG_DBG("size = %u, %p\n", mregion->size, mregion->kvaddr);
  1692. rc = vcd_set_buffer(client_ctx->vcd_handle,
  1693. VCD_BUFFER_OUTPUT, (u8 *) mregion->kvaddr,
  1694. mregion->size);
  1695. if (rc)
  1696. WFD_MSG_ERR("Failed to set outbuf on encoder\n");
  1697. err:
  1698. return rc;
  1699. }
  1700. static long venc_fill_outbuf(struct v4l2_subdev *sd, void *arg)
  1701. {
  1702. int rc = 0;
  1703. struct venc_inst *inst = sd->dev_priv;
  1704. struct video_client_ctx *client_ctx = &inst->venc_client;
  1705. struct mem_region *mregion = arg;
  1706. struct vcd_frame_data vcd_frame = {0};
  1707. unsigned long kernel_vaddr, phy_addr, user_vaddr;
  1708. int pmem_fd;
  1709. struct file *file;
  1710. s32 buffer_index = -1;
  1711. if (inst->streaming) {
  1712. user_vaddr = mregion->cookie;
  1713. rc = vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
  1714. true, &user_vaddr,
  1715. &kernel_vaddr, &phy_addr, &pmem_fd, &file,
  1716. &buffer_index);
  1717. if (!rc) {
  1718. WFD_MSG_ERR("Address lookup failed\n");
  1719. goto err;
  1720. }
  1721. vcd_frame.virtual = (u8 *) kernel_vaddr;
  1722. vcd_frame.frm_clnt_data = mregion->cookie;
  1723. vcd_frame.alloc_len = mregion->size;
  1724. rc = vcd_fill_output_buffer(client_ctx->vcd_handle, &vcd_frame);
  1725. if (rc)
  1726. WFD_MSG_ERR("Failed to fill output buffer on encoder");
  1727. } else {
  1728. struct mem_region *temp = kzalloc(sizeof(*temp), GFP_KERNEL);
  1729. *temp = *mregion;
  1730. INIT_LIST_HEAD(&temp->list);
  1731. list_add_tail(&temp->list, &inst->unqueued_op_bufs.list);
  1732. }
  1733. err:
  1734. return rc;
  1735. }
  1736. static long venc_encode_frame(struct v4l2_subdev *sd, void *arg)
  1737. {
  1738. int rc = 0;
  1739. struct venc_inst *inst = sd->dev_priv;
  1740. struct video_client_ctx *client_ctx = &inst->venc_client;
  1741. struct venc_buf_info *venc_buf = arg;
  1742. struct mem_region *mregion = venc_buf->mregion;
  1743. struct vcd_frame_data vcd_input_buffer = {0};
  1744. int64_t ts = 0;
  1745. ts = venc_buf->timestamp;
  1746. do_div(ts, NSEC_PER_USEC);
  1747. vcd_input_buffer.virtual = mregion->kvaddr;
  1748. vcd_input_buffer.frm_clnt_data = (u32)mregion;
  1749. vcd_input_buffer.ip_frm_tag = (u32)mregion;
  1750. vcd_input_buffer.data_len = mregion->size;
  1751. vcd_input_buffer.time_stamp = ts;
  1752. vcd_input_buffer.offset = 0;
  1753. rc = vcd_encode_frame(client_ctx->vcd_handle,
  1754. &vcd_input_buffer);
  1755. if (rc)
  1756. WFD_MSG_ERR("encode frame failed\n");
  1757. return rc;
  1758. }
  1759. static long venc_alloc_recon_buffers(struct v4l2_subdev *sd, void *arg)
  1760. {
  1761. int rc = 0;
  1762. struct venc_inst *inst = sd->dev_priv;
  1763. struct video_client_ctx *client_ctx = &inst->venc_client;
  1764. struct vcd_property_hdr vcd_property_hdr;
  1765. struct vcd_property_buffer_size control;
  1766. struct vcd_property_enc_recon_buffer *ctrl = NULL;
  1767. unsigned long phy_addr;
  1768. int i = 0;
  1769. int heap_mask = 0;
  1770. u32 ion_flags = 0;
  1771. u32 len;
  1772. control.width = inst->width;
  1773. control.height = inst->height;
  1774. vcd_property_hdr.prop_id = VCD_I_GET_RECON_BUFFER_SIZE;
  1775. vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
  1776. rc = vcd_get_property(client_ctx->vcd_handle,
  1777. &vcd_property_hdr, &control);
  1778. if (rc) {
  1779. WFD_MSG_ERR("Failed to get recon buf size\n");
  1780. goto err;
  1781. }
  1782. heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
  1783. heap_mask |= inst->secure ? 0 : ION_HEAP(ION_IOMMU_HEAP_ID);
  1784. ion_flags |= inst->secure ? ION_FLAG_SECURE : 0;
  1785. if (vcd_get_ion_status()) {
  1786. for (i = 0; i < 4; ++i) {
  1787. ctrl = &client_ctx->recon_buffer[i];
  1788. ctrl->buffer_size = control.size;
  1789. ctrl->pmem_fd = 0;
  1790. ctrl->offset = 0;
  1791. ctrl->user_virtual_addr = (void *)i;
  1792. client_ctx->recon_buffer_ion_handle[i]
  1793. = ion_alloc(client_ctx->user_ion_client,
  1794. control.size, SZ_8K, heap_mask, ion_flags);
  1795. ctrl->kernel_virtual_addr = ion_map_kernel(
  1796. client_ctx->user_ion_client,
  1797. client_ctx->recon_buffer_ion_handle[i]);
  1798. if (IS_ERR_OR_NULL(ctrl->kernel_virtual_addr)) {
  1799. WFD_MSG_ERR("ion map kernel failed\n");
  1800. rc = -EINVAL;
  1801. goto free_ion_alloc;
  1802. }
  1803. if (inst->secure) {
  1804. rc = ion_phys(client_ctx->user_ion_client,
  1805. client_ctx->recon_buffer_ion_handle[i],
  1806. &phy_addr, (size_t *)&len);
  1807. if (rc || !phy_addr) {
  1808. WFD_MSG_ERR("ion physical failed\n");
  1809. goto unmap_ion_alloc;
  1810. }
  1811. } else {
  1812. rc = ion_map_iommu(client_ctx->user_ion_client,
  1813. client_ctx->recon_buffer_ion_handle[i],
  1814. VIDEO_DOMAIN, VIDEO_MAIN_POOL, SZ_4K,
  1815. 0, &phy_addr, (unsigned long *)&len,
  1816. 0, 0);
  1817. if (rc || !phy_addr) {
  1818. WFD_MSG_ERR(
  1819. "ion map iommu failed, rc = %d, phy_addr = 0x%lx\n",
  1820. rc, phy_addr);
  1821. goto unmap_ion_alloc;
  1822. }
  1823. }
  1824. ctrl->physical_addr = (u8 *) phy_addr;
  1825. ctrl->dev_addr = ctrl->physical_addr;
  1826. vcd_property_hdr.prop_id = VCD_I_RECON_BUFFERS;
  1827. vcd_property_hdr.sz =
  1828. sizeof(struct vcd_property_enc_recon_buffer);
  1829. rc = vcd_set_property(client_ctx->vcd_handle,
  1830. &vcd_property_hdr, ctrl);
  1831. if (rc) {
  1832. WFD_MSG_ERR("Failed to set recon buffers\n");
  1833. goto unmap_ion_iommu;
  1834. }
  1835. }
  1836. } else {
  1837. WFD_MSG_ERR("PMEM not suported\n");
  1838. return -ENOMEM;
  1839. }
  1840. return rc;
  1841. unmap_ion_iommu:
  1842. if (!inst->secure) {
  1843. if (client_ctx->recon_buffer_ion_handle[i]) {
  1844. ion_unmap_iommu(client_ctx->user_ion_client,
  1845. client_ctx->recon_buffer_ion_handle[i],
  1846. VIDEO_DOMAIN, VIDEO_MAIN_POOL);
  1847. }
  1848. }
  1849. unmap_ion_alloc:
  1850. if (client_ctx->recon_buffer_ion_handle[i]) {
  1851. ion_unmap_kernel(client_ctx->user_ion_client,
  1852. client_ctx->recon_buffer_ion_handle[i]);
  1853. ctrl->kernel_virtual_addr = NULL;
  1854. ctrl->physical_addr = NULL;
  1855. }
  1856. free_ion_alloc:
  1857. if (client_ctx->recon_buffer_ion_handle[i]) {
  1858. ion_free(client_ctx->user_ion_client,
  1859. client_ctx->recon_buffer_ion_handle[i]);
  1860. client_ctx->recon_buffer_ion_handle[i] = NULL;
  1861. }
  1862. WFD_MSG_ERR("Failed to allo recon buffers\n");
  1863. err:
  1864. return rc;
  1865. }
  1866. static long venc_free_output_buffer(struct v4l2_subdev *sd, void *arg)
  1867. {
  1868. int rc = 0;
  1869. struct venc_inst *inst = sd->dev_priv;
  1870. struct video_client_ctx *client_ctx = &inst->venc_client;
  1871. struct mem_region *mregion = arg;
  1872. unsigned long kernel_vaddr, user_vaddr;
  1873. if (!client_ctx || !mregion) {
  1874. WFD_MSG_ERR("Invalid input\n");
  1875. return -EINVAL;
  1876. }
  1877. user_vaddr = mregion->cookie;
  1878. rc = vidc_delete_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
  1879. user_vaddr,
  1880. &kernel_vaddr);
  1881. if (!rc) {
  1882. WFD_MSG_ERR("Failed to delete buf from address table\n");
  1883. return -EINVAL;
  1884. }
  1885. return vcd_free_buffer(client_ctx->vcd_handle, VCD_BUFFER_OUTPUT,
  1886. (u8 *)kernel_vaddr);
  1887. }
  1888. static long venc_flush_buffers(struct v4l2_subdev *sd, void *arg)
  1889. {
  1890. int rc = 0;
  1891. struct venc_inst *inst = sd->dev_priv;
  1892. struct video_client_ctx *client_ctx = &inst->venc_client;
  1893. if (!client_ctx) {
  1894. WFD_MSG_ERR("Invalid input\n");
  1895. return -EINVAL;
  1896. }
  1897. rc = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_INPUT);
  1898. if (rc) {
  1899. WFD_MSG_ERR("Failed to flush input buffers\n");
  1900. rc = -EIO;
  1901. goto flush_failed;
  1902. }
  1903. wait_for_completion(&client_ctx->event);
  1904. if (client_ctx->event_status) {
  1905. WFD_MSG_ERR("callback for vcd_flush input returned error: %u",
  1906. client_ctx->event_status);
  1907. rc = -EIO;
  1908. goto flush_failed;
  1909. }
  1910. rc = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_OUTPUT);
  1911. if (rc) {
  1912. WFD_MSG_ERR("Failed to flush output buffers\n");
  1913. rc = -EIO;
  1914. goto flush_failed;
  1915. }
  1916. wait_for_completion(&client_ctx->event);
  1917. if (client_ctx->event_status) {
  1918. WFD_MSG_ERR("callback for vcd_flush output returned error: %u",
  1919. client_ctx->event_status);
  1920. rc = -EIO;
  1921. goto flush_failed;
  1922. }
  1923. flush_failed:
  1924. return rc;
  1925. }
  1926. static long venc_free_input_buffer(struct v4l2_subdev *sd, void *arg)
  1927. {
  1928. int del_rc = 0, free_rc = 0;
  1929. struct venc_inst *inst = sd->dev_priv;
  1930. struct video_client_ctx *client_ctx = &inst->venc_client;
  1931. struct mem_region *mregion = arg;
  1932. unsigned long vidc_kvaddr;
  1933. if (!client_ctx || !mregion) {
  1934. WFD_MSG_ERR("Invalid input\n");
  1935. return -EINVAL;
  1936. }
  1937. del_rc = vidc_delete_addr_table(client_ctx, BUFFER_TYPE_INPUT,
  1938. (unsigned long)mregion->kvaddr,
  1939. &vidc_kvaddr);
  1940. /*
  1941. * Even if something went wrong in when
  1942. * deleting from table, call vcd_free_buf
  1943. */
  1944. if (del_rc == (u32)false) {
  1945. WFD_MSG_ERR("Failed to delete buf from address table\n");
  1946. del_rc = -ENOKEY;
  1947. } else if ((u8 *)vidc_kvaddr != mregion->kvaddr) {
  1948. WFD_MSG_ERR("Failed to find expected buffer\n");
  1949. del_rc = -EINVAL;
  1950. } else
  1951. del_rc = 0;
  1952. free_rc = vcd_free_buffer(client_ctx->vcd_handle, VCD_BUFFER_INPUT,
  1953. (u8 *)vidc_kvaddr);
  1954. if (free_rc) {
  1955. WFD_MSG_ERR("Failed to free buffer from encoder\n");
  1956. free_rc = -EINVAL;
  1957. }
  1958. return del_rc ? del_rc : free_rc;
  1959. }
  1960. static long venc_free_recon_buffers(struct v4l2_subdev *sd, void *arg)
  1961. {
  1962. int rc = 0;
  1963. struct venc_inst *inst = sd->dev_priv;
  1964. struct video_client_ctx *client_ctx = &inst->venc_client;
  1965. struct vcd_property_hdr vcd_property_hdr;
  1966. int i;
  1967. if (vcd_get_ion_status()) {
  1968. for (i = 0; i < 4; i++) {
  1969. vcd_property_hdr.prop_id = VCD_I_FREE_RECON_BUFFERS;
  1970. vcd_property_hdr.sz =
  1971. sizeof(struct vcd_property_buffer_size);
  1972. rc = vcd_set_property(client_ctx->vcd_handle,
  1973. &vcd_property_hdr, &client_ctx->recon_buffer[i]);
  1974. if (rc)
  1975. WFD_MSG_ERR("Failed to free recon buffer\n");
  1976. if (!IS_ERR_OR_NULL(
  1977. client_ctx->recon_buffer_ion_handle[i])) {
  1978. if (!inst->secure) {
  1979. ion_unmap_iommu(
  1980. client_ctx->user_ion_client,
  1981. client_ctx->recon_buffer_ion_handle[i],
  1982. VIDEO_DOMAIN, VIDEO_MAIN_POOL);
  1983. }
  1984. ion_unmap_kernel(client_ctx->user_ion_client,
  1985. client_ctx->recon_buffer_ion_handle[i]);
  1986. ion_free(client_ctx->user_ion_client,
  1987. client_ctx->recon_buffer_ion_handle[i]);
  1988. client_ctx->recon_buffer_ion_handle[i] = NULL;
  1989. }
  1990. }
  1991. }
  1992. return rc;
  1993. }
  1994. static long venc_set_property(struct v4l2_subdev *sd, void *arg)
  1995. {
  1996. int rc = 0;
  1997. struct venc_inst *inst = sd->dev_priv;
  1998. struct v4l2_control *ctrl = arg;
  1999. struct video_client_ctx *client_ctx = &inst->venc_client;
  2000. switch (ctrl->id) {
  2001. case V4L2_CID_MPEG_VIDEO_BITRATE:
  2002. rc = venc_set_bitrate(client_ctx, ctrl->value);
  2003. break;
  2004. case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
  2005. rc = venc_set_bitrate_mode(client_ctx, ctrl->value);
  2006. break;
  2007. case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
  2008. rc = venc_set_h264_intra_period(client_ctx, ctrl->value);
  2009. break;
  2010. case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
  2011. rc = venc_set_codec_level(client_ctx, ctrl->id, ctrl->value);
  2012. break;
  2013. case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
  2014. rc = venc_set_codec_profile(client_ctx, ctrl->id, ctrl->value);
  2015. break;
  2016. case V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME:
  2017. rc = venc_request_frame(client_ctx, ctrl->value);
  2018. break;
  2019. case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
  2020. case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
  2021. case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
  2022. case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
  2023. case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
  2024. case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
  2025. case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
  2026. case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
  2027. case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
  2028. rc = venc_set_qp_value(client_ctx, ctrl->id, ctrl->value);
  2029. break;
  2030. case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
  2031. case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
  2032. case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
  2033. case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
  2034. case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
  2035. case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
  2036. rc = venc_set_qp_range(client_ctx, ctrl->id, ctrl->value);
  2037. break;
  2038. case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
  2039. rc = venc_set_header_mode(client_ctx, ctrl->value);
  2040. break;
  2041. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
  2042. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
  2043. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
  2044. rc = venc_set_multislicing_mode(client_ctx, ctrl->id,
  2045. ctrl->value);
  2046. break;
  2047. case V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL:
  2048. rc = venc_set_max_perf_level(client_ctx, ctrl->value);
  2049. break;
  2050. case V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER:
  2051. rc = venc_set_avc_delimiter(client_ctx, ctrl->value);
  2052. break;
  2053. case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO:
  2054. rc = venc_set_vui_timing_info(client_ctx, inst, ctrl->value);
  2055. break;
  2056. case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
  2057. rc = venc_set_entropy_mode(client_ctx, ctrl->value);
  2058. break;
  2059. case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
  2060. rc = venc_set_cyclic_intra_refresh_mb(client_ctx, ctrl->value);
  2061. break;
  2062. default:
  2063. WFD_MSG_ERR("Set property not suported: %d\n", ctrl->id);
  2064. rc = -ENOTSUPP;
  2065. break;
  2066. }
  2067. return rc;
  2068. }
  2069. static long venc_get_property(struct v4l2_subdev *sd, void *arg)
  2070. {
  2071. int rc = 0;
  2072. struct venc_inst *inst = sd->dev_priv;
  2073. struct v4l2_control *ctrl = arg;
  2074. struct video_client_ctx *client_ctx = &inst->venc_client;
  2075. switch (ctrl->id) {
  2076. case V4L2_CID_MPEG_VIDEO_BITRATE:
  2077. rc = venc_get_bitrate(client_ctx, &ctrl->value);
  2078. break;
  2079. case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
  2080. rc = venc_get_bitrate_mode(client_ctx, &ctrl->value);
  2081. break;
  2082. case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
  2083. rc = venc_get_codec_level(client_ctx, ctrl->id, &ctrl->value);
  2084. break;
  2085. case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
  2086. rc = venc_get_codec_profile(client_ctx, ctrl->id, &ctrl->value);
  2087. break;
  2088. case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
  2089. rc = venc_get_h264_intra_period(client_ctx, &ctrl->value);
  2090. break;
  2091. case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
  2092. case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
  2093. case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
  2094. case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
  2095. case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
  2096. case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
  2097. case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
  2098. case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
  2099. case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
  2100. rc = venc_get_qp_value(client_ctx, ctrl->id, &ctrl->value);
  2101. break;
  2102. case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
  2103. case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
  2104. case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
  2105. case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
  2106. case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
  2107. case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
  2108. rc = venc_get_qp_range(client_ctx, ctrl->id, &ctrl->value);
  2109. break;
  2110. case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
  2111. rc = venc_get_header_mode(client_ctx, &ctrl->value);
  2112. break;
  2113. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
  2114. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
  2115. case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
  2116. rc = venc_get_multislicing_mode(client_ctx, ctrl->id,
  2117. &ctrl->value);
  2118. break;
  2119. case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
  2120. rc = venc_get_entropy_mode(client_ctx, &ctrl->value);
  2121. break;
  2122. case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
  2123. rc = venc_get_cyclic_intra_refresh_mb(client_ctx, &ctrl->value);
  2124. break;
  2125. case V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER:
  2126. rc = venc_get_avc_delimiter(client_ctx, &ctrl->value);
  2127. break;
  2128. case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO:
  2129. rc = venc_get_vui_timing_info(client_ctx, &ctrl->value);
  2130. break;
  2131. default:
  2132. WFD_MSG_ERR("Get property not suported: %d\n", ctrl->id);
  2133. rc = -ENOTSUPP;
  2134. break;
  2135. }
  2136. return rc;
  2137. }
  2138. long venc_mmap(struct v4l2_subdev *sd, void *arg)
  2139. {
  2140. struct venc_inst *inst = sd->dev_priv;
  2141. struct mem_region_map *mmap = arg;
  2142. struct mem_region *mregion = NULL;
  2143. unsigned long rc = 0, size = 0;
  2144. void *paddr = NULL;
  2145. if (!sd) {
  2146. WFD_MSG_ERR("Subdevice required for %s\n", __func__);
  2147. return -EINVAL;
  2148. } else if (!mmap || !mmap->mregion) {
  2149. WFD_MSG_ERR("Memregion required for %s\n", __func__);
  2150. return -EINVAL;
  2151. }
  2152. mregion = mmap->mregion;
  2153. if (mregion->size % SZ_4K != 0) {
  2154. WFD_MSG_ERR("Memregion not aligned to %d\n", SZ_4K);
  2155. return -EINVAL;
  2156. }
  2157. if (inst->secure) {
  2158. rc = ion_phys(mmap->ion_client, mregion->ion_handle,
  2159. (unsigned long *)&paddr,
  2160. (size_t *)&size);
  2161. } else {
  2162. rc = ion_map_iommu(mmap->ion_client, mregion->ion_handle,
  2163. VIDEO_DOMAIN, VIDEO_MAIN_POOL, SZ_4K,
  2164. 0, (unsigned long *)&paddr,
  2165. &size, 0, 0);
  2166. }
  2167. if (rc) {
  2168. WFD_MSG_ERR("Failed to get physical addr\n");
  2169. paddr = NULL;
  2170. } else if (size < mregion->size) {
  2171. WFD_MSG_ERR("Failed to map enough memory\n");
  2172. rc = -ENOMEM;
  2173. }
  2174. mregion->paddr = paddr;
  2175. return rc;
  2176. }
  2177. long venc_munmap(struct v4l2_subdev *sd, void *arg)
  2178. {
  2179. struct venc_inst *inst = sd->dev_priv;
  2180. struct mem_region_map *mmap = arg;
  2181. struct mem_region *mregion = NULL;
  2182. if (!sd) {
  2183. WFD_MSG_ERR("Subdevice required for %s\n", __func__);
  2184. return -EINVAL;
  2185. } else if (!mregion) {
  2186. WFD_MSG_ERR("Memregion required for %s\n", __func__);
  2187. return -EINVAL;
  2188. }
  2189. mregion = mmap->mregion;
  2190. if (!inst->secure) {
  2191. ion_unmap_iommu(mmap->ion_client, mregion->ion_handle,
  2192. VIDEO_DOMAIN, VIDEO_MAIN_POOL);
  2193. }
  2194. return 0;
  2195. }
  2196. long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
  2197. {
  2198. long rc = 0;
  2199. switch (cmd) {
  2200. case OPEN:
  2201. rc = venc_open(sd, arg);
  2202. break;
  2203. case CLOSE:
  2204. rc = venc_close(sd, arg);
  2205. break;
  2206. case ENCODE_START:
  2207. rc = venc_start(sd);
  2208. break;
  2209. case ENCODE_FRAME:
  2210. venc_encode_frame(sd, arg);
  2211. break;
  2212. case ENCODE_STOP:
  2213. rc = venc_stop(sd);
  2214. break;
  2215. case SET_PROP:
  2216. rc = venc_set_property(sd, arg);
  2217. break;
  2218. case GET_PROP:
  2219. rc = venc_get_property(sd, arg);
  2220. break;
  2221. case GET_BUFFER_REQ:
  2222. rc = venc_get_buffer_req(sd, arg);
  2223. break;
  2224. case SET_BUFFER_REQ:
  2225. rc = venc_set_buffer_req(sd, arg);
  2226. break;
  2227. case FREE_BUFFER:
  2228. break;
  2229. case FILL_OUTPUT_BUFFER:
  2230. rc = venc_fill_outbuf(sd, arg);
  2231. break;
  2232. case SET_FORMAT:
  2233. rc = venc_set_format(sd, arg);
  2234. break;
  2235. case SET_FRAMERATE:
  2236. rc = venc_set_framerate(sd, arg);
  2237. break;
  2238. case SET_INPUT_BUFFER:
  2239. rc = venc_set_input_buffer(sd, arg);
  2240. break;
  2241. case SET_OUTPUT_BUFFER:
  2242. rc = venc_set_output_buffer(sd, arg);
  2243. break;
  2244. case ALLOC_RECON_BUFFERS:
  2245. rc = venc_alloc_recon_buffers(sd, arg);
  2246. break;
  2247. case FREE_OUTPUT_BUFFER:
  2248. rc = venc_free_output_buffer(sd, arg);
  2249. break;
  2250. case FREE_INPUT_BUFFER:
  2251. rc = venc_free_input_buffer(sd, arg);
  2252. break;
  2253. case FREE_RECON_BUFFERS:
  2254. rc = venc_free_recon_buffers(sd, arg);
  2255. break;
  2256. case ENCODE_FLUSH:
  2257. rc = venc_flush_buffers(sd, arg);
  2258. break;
  2259. case ENC_MMAP:
  2260. rc = venc_mmap(sd, arg);
  2261. break;
  2262. case ENC_MUNMAP:
  2263. rc = venc_munmap(sd, arg);
  2264. break;
  2265. case SET_FRAMERATE_MODE:
  2266. rc = venc_set_framerate_mode(sd, arg);
  2267. break;
  2268. default:
  2269. rc = -1;
  2270. break;
  2271. }
  2272. return rc;
  2273. }