msm_vdec.c 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  4. */
  5. #include <media/v4l2_vidc_extensions.h>
  6. #include <media/msm_media_info.h>
  7. #include "msm_vdec.h"
  8. #include "msm_vidc_core.h"
  9. #include "msm_vidc_inst.h"
  10. #include "msm_vidc_driver.h"
  11. #include "msm_vidc_internal.h"
  12. #include "msm_vidc_platform.h"
  13. #include "msm_vidc_control.h"
  14. #include "msm_vidc_debug.h"
  15. #include "msm_vidc_control.h"
  16. #include "venus_hfi.h"
  17. #include "hfi_packet.h"
  18. u32 msm_vdec_subscribe_for_port_settings_change[] = {
  19. HFI_PROP_BITSTREAM_RESOLUTION,
  20. HFI_PROP_CROP_OFFSETS,
  21. HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
  22. HFI_PROP_CABAC_SESSION,
  23. HFI_PROP_CODED_FRAMES,
  24. HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
  25. HFI_PROP_PIC_ORDER_CNT_TYPE,
  26. HFI_PROP_SIGNAL_COLOR_INFO,
  27. HFI_PROP_PROFILE,
  28. HFI_PROP_LEVEL,
  29. HFI_PROP_TIER,
  30. };
  31. u32 msm_vdec_subscribe_for_properties[] = {
  32. HFI_PROP_NO_OUTPUT,
  33. };
  34. u32 msm_vdec_subscribe_for_metadata[] = {
  35. HFI_PROP_BUFFER_TAG,
  36. };
  37. u32 msm_vdec_deliver_as_metadata[] = {
  38. HFI_PROP_BUFFER_TAG,
  39. };
  40. static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 v4l2_codec)
  41. {
  42. int rc = 0;
  43. if (inst->codec && inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat == v4l2_codec)
  44. return 0;
  45. s_vpr_h(inst->sid, "%s: codec changed from %#x to %#x\n",
  46. __func__, inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat, v4l2_codec);
  47. inst->codec = v4l2_codec_to_driver(v4l2_codec, __func__);
  48. rc = msm_vidc_get_inst_capability(inst);
  49. if (rc)
  50. goto exit;
  51. rc = msm_vidc_ctrl_deinit(inst);
  52. if (rc)
  53. goto exit;
  54. rc = msm_vidc_ctrl_init(inst);
  55. if(rc)
  56. goto exit;
  57. exit:
  58. return rc;
  59. }
  60. static int msm_vdec_set_bitstream_resolution(struct msm_vidc_inst *inst,
  61. enum msm_vidc_port_type port)
  62. {
  63. int rc = 0;
  64. u32 resolution;
  65. resolution = inst->fmts[INPUT_PORT].fmt.pix_mp.width << 16 |
  66. inst->fmts[INPUT_PORT].fmt.pix_mp.height;
  67. s_vpr_h(inst->sid, "%s: width: %d height: %d\n", __func__,
  68. inst->fmts[INPUT_PORT].fmt.pix_mp.width,
  69. inst->fmts[INPUT_PORT].fmt.pix_mp.height);
  70. inst->subcr_params[port].bitstream_resolution = resolution;
  71. rc = venus_hfi_session_property(inst,
  72. HFI_PROP_BITSTREAM_RESOLUTION,
  73. HFI_HOST_FLAGS_NONE,
  74. get_hfi_port(inst, port),
  75. HFI_PAYLOAD_U32,
  76. &resolution,
  77. sizeof(u32));
  78. if (rc)
  79. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  80. return rc;
  81. }
  82. static int msm_vdec_set_linear_stride_scanline(struct msm_vidc_inst *inst)
  83. {
  84. int rc = 0;
  85. u32 stride_y, scanline_y, stride_uv, scanline_uv;
  86. u32 payload[2];
  87. if (inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat !=
  88. V4L2_PIX_FMT_NV12 &&
  89. inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat !=
  90. V4L2_PIX_FMT_VIDC_P010)
  91. return 0;
  92. stride_y = inst->fmts[OUTPUT_PORT].fmt.pix_mp.width;
  93. scanline_y = inst->fmts[OUTPUT_PORT].fmt.pix_mp.height;
  94. stride_uv = stride_y;
  95. scanline_uv = scanline_y / 2;
  96. payload[0] = stride_y << 16 | scanline_y;
  97. payload[1] = stride_uv << 16 | scanline_uv;
  98. s_vpr_h(inst->sid, "%s: stride_y: %d scanline_y: %d "
  99. "stride_uv: %d, scanline_uv: %d", __func__,
  100. stride_y, scanline_y, stride_uv, scanline_uv);
  101. rc = venus_hfi_session_property(inst,
  102. HFI_PROP_LINEAR_STRIDE_SCANLINE,
  103. HFI_HOST_FLAGS_NONE,
  104. get_hfi_port(inst, OUTPUT_PORT),
  105. HFI_PAYLOAD_U64,
  106. &payload,
  107. sizeof(u64));
  108. if (rc)
  109. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  110. return rc;
  111. }
  112. static int msm_vdec_set_crop_offsets(struct msm_vidc_inst *inst,
  113. enum msm_vidc_port_type port)
  114. {
  115. int rc = 0;
  116. u32 left_offset, top_offset, right_offset, bottom_offset;
  117. u64 payload;
  118. if (inst->fmts[INPUT_PORT].fmt.pix_mp.width <
  119. inst->crop.width)
  120. return -EINVAL;
  121. if (inst->fmts[INPUT_PORT].fmt.pix_mp.height <
  122. inst->crop.height)
  123. return -EINVAL;
  124. left_offset = inst->crop.left;
  125. top_offset = inst->crop.top;
  126. right_offset = (inst->fmts[INPUT_PORT].fmt.pix_mp.width -
  127. inst->crop.width);
  128. bottom_offset = (inst->fmts[INPUT_PORT].fmt.pix_mp.height -
  129. inst->crop.height);
  130. payload = (u64)right_offset << 48 | (u64)bottom_offset << 32 |
  131. (u64)left_offset << 16 | top_offset;
  132. s_vpr_h(inst->sid, "%s: left_offset: %d top_offset: %d "
  133. "right_offset: %d bottom_offset: %d", __func__,
  134. left_offset, top_offset, right_offset, bottom_offset);
  135. inst->subcr_params[port].crop_offsets = payload;
  136. rc = venus_hfi_session_property(inst,
  137. HFI_PROP_CROP_OFFSETS,
  138. HFI_HOST_FLAGS_NONE,
  139. get_hfi_port(inst, port),
  140. HFI_PAYLOAD_64_PACKED,
  141. &payload,
  142. sizeof(u64));
  143. if (rc)
  144. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  145. return rc;
  146. }
  147. static int msm_vdec_set_bit_depth(struct msm_vidc_inst *inst,
  148. enum msm_vidc_port_type port)
  149. {
  150. int rc = 0;
  151. u32 colorformat;
  152. u32 bitdepth = 8 << 16 | 8;
  153. if (port != INPUT_PORT && port != OUTPUT_PORT) {
  154. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  155. return -EINVAL;
  156. }
  157. colorformat = inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat;
  158. if (colorformat == V4L2_PIX_FMT_VIDC_P010 ||
  159. colorformat == V4L2_PIX_FMT_VIDC_TP10C)
  160. bitdepth = 10 << 16 | 10;
  161. inst->subcr_params[port].bit_depth = bitdepth;
  162. s_vpr_h(inst->sid, "%s: bit depth: %d", __func__, bitdepth);
  163. rc = venus_hfi_session_property(inst,
  164. HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
  165. HFI_HOST_FLAGS_NONE,
  166. get_hfi_port(inst, port),
  167. HFI_PAYLOAD_U32,
  168. &bitdepth,
  169. sizeof(u32));
  170. if (rc)
  171. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  172. return rc;
  173. }
  174. static int msm_vdec_set_cabac(struct msm_vidc_inst *inst,
  175. enum msm_vidc_port_type port)
  176. {
  177. int rc = 0;
  178. u32 cabac = 0;
  179. if (port != INPUT_PORT && port != OUTPUT_PORT) {
  180. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  181. return -EINVAL;
  182. }
  183. rc = msm_vidc_v4l2_menu_to_hfi(inst, ENTROPY_MODE, &cabac);
  184. if (rc)
  185. return rc;
  186. inst->subcr_params[port].cabac = cabac;
  187. s_vpr_h(inst->sid, "%s: entropy mode: %d", __func__, cabac);
  188. rc = venus_hfi_session_property(inst,
  189. HFI_PROP_CABAC_SESSION,
  190. HFI_HOST_FLAGS_NONE,
  191. get_hfi_port(inst, port),
  192. HFI_PAYLOAD_U32,
  193. &cabac,
  194. sizeof(u32));
  195. if (rc)
  196. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  197. return rc;
  198. }
  199. static int msm_vdec_set_coded_frames(struct msm_vidc_inst *inst,
  200. enum msm_vidc_port_type port)
  201. {
  202. int rc = 0;
  203. u32 coded_frames;
  204. if (port != INPUT_PORT && port != OUTPUT_PORT) {
  205. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  206. return -EINVAL;
  207. }
  208. /* (mb_adaptive_frame_field_flag << 1) | frame_mbs_only_flag */
  209. coded_frames = 0;
  210. inst->subcr_params[port].coded_frames = coded_frames;
  211. s_vpr_h(inst->sid, "%s: coded frames: %d", __func__, coded_frames);
  212. rc = venus_hfi_session_property(inst,
  213. HFI_PROP_CODED_FRAMES,
  214. HFI_HOST_FLAGS_NONE,
  215. get_hfi_port(inst, port),
  216. HFI_PAYLOAD_U32,
  217. &coded_frames,
  218. sizeof(u32));
  219. if (rc)
  220. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  221. return rc;
  222. }
  223. static int msm_vdec_set_min_output_count(struct msm_vidc_inst *inst,
  224. enum msm_vidc_port_type port)
  225. {
  226. int rc = 0;
  227. u32 min_output;
  228. if (port != INPUT_PORT && port != OUTPUT_PORT) {
  229. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  230. return -EINVAL;
  231. }
  232. min_output = inst->buffers.output.min_count;
  233. inst->subcr_params[port].fw_min_count = min_output;
  234. s_vpr_h(inst->sid, "%s: firmware min output count: %d",
  235. __func__, min_output);
  236. rc = venus_hfi_session_property(inst,
  237. HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
  238. HFI_HOST_FLAGS_NONE,
  239. get_hfi_port(inst, port),
  240. HFI_PAYLOAD_U32,
  241. &min_output,
  242. sizeof(u32));
  243. if (rc)
  244. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  245. return rc;
  246. }
  247. static int msm_vdec_set_picture_order_count(struct msm_vidc_inst *inst,
  248. enum msm_vidc_port_type port)
  249. {
  250. int rc = 0;
  251. u32 poc = 0;
  252. if (port != INPUT_PORT && port != OUTPUT_PORT) {
  253. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  254. return -EINVAL;
  255. }
  256. inst->subcr_params[port].pic_order_cnt = poc;
  257. s_vpr_h(inst->sid, "%s: picture order count: %d", __func__, poc);
  258. rc = venus_hfi_session_property(inst,
  259. HFI_PROP_PIC_ORDER_CNT_TYPE,
  260. HFI_HOST_FLAGS_NONE,
  261. get_hfi_port(inst, port),
  262. HFI_PAYLOAD_U32,
  263. &poc,
  264. sizeof(u32));
  265. if (rc)
  266. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  267. return rc;
  268. }
  269. static int msm_vdec_set_colorspace(struct msm_vidc_inst *inst,
  270. enum msm_vidc_port_type port)
  271. {
  272. int rc = 0;
  273. u32 colorspace, xfer_func, ycbcr_enc, color_info;
  274. if (port != INPUT_PORT && port != OUTPUT_PORT) {
  275. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  276. return -EINVAL;
  277. }
  278. colorspace = inst->fmts[OUTPUT_PORT].fmt.pix_mp.colorspace;
  279. xfer_func = inst->fmts[OUTPUT_PORT].fmt.pix_mp.xfer_func;
  280. ycbcr_enc = inst->fmts[OUTPUT_PORT].fmt.pix_mp.ycbcr_enc;
  281. color_info = ((ycbcr_enc << 16) & 0xFF0000) |
  282. ((xfer_func << 8) & 0xFF00) | (colorspace & 0xFF);
  283. inst->subcr_params[port].color_info = color_info;
  284. s_vpr_h(inst->sid, "%s: color info: %d", __func__, color_info);
  285. rc = venus_hfi_session_property(inst,
  286. HFI_PROP_SIGNAL_COLOR_INFO,
  287. HFI_HOST_FLAGS_NONE,
  288. get_hfi_port(inst, port),
  289. HFI_PAYLOAD_U32,
  290. &color_info,
  291. sizeof(u32));
  292. if (rc)
  293. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  294. return rc;
  295. }
  296. static int msm_vdec_set_profile(struct msm_vidc_inst *inst,
  297. enum msm_vidc_port_type port)
  298. {
  299. int rc = 0;
  300. u32 profile;
  301. if (port != INPUT_PORT && port != OUTPUT_PORT) {
  302. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  303. return -EINVAL;
  304. }
  305. profile = inst->capabilities->cap[PROFILE].value;
  306. inst->subcr_params[port].profile = profile;
  307. s_vpr_h(inst->sid, "%s: profile: %d", __func__, profile);
  308. rc = venus_hfi_session_property(inst,
  309. HFI_PROP_PROFILE,
  310. HFI_HOST_FLAGS_NONE,
  311. get_hfi_port(inst, port),
  312. HFI_PAYLOAD_U32_ENUM,
  313. &profile,
  314. sizeof(u32));
  315. if (rc)
  316. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  317. return rc;
  318. }
  319. static int msm_vdec_set_level(struct msm_vidc_inst *inst,
  320. enum msm_vidc_port_type port)
  321. {
  322. int rc = 0;
  323. u32 level;
  324. if (port != INPUT_PORT && port != OUTPUT_PORT) {
  325. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  326. return -EINVAL;
  327. }
  328. level = inst->capabilities->cap[LEVEL].value;
  329. inst->subcr_params[port].level = level;
  330. s_vpr_h(inst->sid, "%s: level: %d", __func__, level);
  331. rc = venus_hfi_session_property(inst,
  332. HFI_PROP_LEVEL,
  333. HFI_HOST_FLAGS_NONE,
  334. get_hfi_port(inst, port),
  335. HFI_PAYLOAD_U32_ENUM,
  336. &level,
  337. sizeof(u32));
  338. if (rc)
  339. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  340. return rc;
  341. }
  342. static int msm_vdec_set_tier(struct msm_vidc_inst *inst,
  343. enum msm_vidc_port_type port)
  344. {
  345. int rc = 0;
  346. u32 tier;
  347. if (port != INPUT_PORT && port != OUTPUT_PORT) {
  348. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  349. return -EINVAL;
  350. }
  351. tier = inst->capabilities->cap[HEVC_TIER].value;
  352. inst->subcr_params[port].tier = tier;
  353. s_vpr_h(inst->sid, "%s: tier: %d", __func__, tier);
  354. rc = venus_hfi_session_property(inst,
  355. HFI_PROP_TIER,
  356. HFI_HOST_FLAGS_NONE,
  357. get_hfi_port(inst, port),
  358. HFI_PAYLOAD_U32_ENUM,
  359. &tier,
  360. sizeof(u32));
  361. if (rc)
  362. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  363. return rc;
  364. }
  365. static int msm_vdec_set_colorformat(struct msm_vidc_inst *inst)
  366. {
  367. int rc = 0;
  368. u32 pixelformat;
  369. enum msm_vidc_colorformat_type colorformat;
  370. u32 hfi_colorformat;
  371. pixelformat = inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat;
  372. colorformat = v4l2_colorformat_to_driver(pixelformat, __func__);
  373. hfi_colorformat = get_hfi_colorformat(inst, colorformat);
  374. s_vpr_h(inst->sid, "%s: hfi colorformat: %d",
  375. __func__, hfi_colorformat);
  376. rc = venus_hfi_session_property(inst,
  377. HFI_PROP_COLOR_FORMAT,
  378. HFI_HOST_FLAGS_NONE,
  379. get_hfi_port(inst, OUTPUT_PORT),
  380. HFI_PAYLOAD_U32,
  381. &hfi_colorformat,
  382. sizeof(u32));
  383. if (rc)
  384. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  385. return rc;
  386. }
  387. static int msm_vdec_set_stage(struct msm_vidc_inst *inst)
  388. {
  389. int rc = 0;
  390. u32 stage = 0;
  391. struct msm_vidc_core *core = inst->core;
  392. rc = call_session_op(core, decide_work_mode, inst);
  393. if (rc) {
  394. s_vpr_e(inst->sid, "%s: decide_work_mode failed %d\n",
  395. __func__);
  396. return -EINVAL;
  397. }
  398. stage = inst->stage;
  399. s_vpr_h(inst->sid, "%s: stage: %d", __func__, stage);
  400. rc = venus_hfi_session_property(inst,
  401. HFI_PROP_STAGE,
  402. HFI_HOST_FLAGS_NONE,
  403. HFI_PORT_NONE,
  404. HFI_PAYLOAD_U32,
  405. &stage,
  406. sizeof(u32));
  407. if (rc)
  408. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  409. return rc;
  410. }
  411. static int msm_vdec_set_pipe(struct msm_vidc_inst *inst)
  412. {
  413. int rc = 0;
  414. u32 pipe;
  415. struct msm_vidc_core *core = inst->core;
  416. rc = call_session_op(core, decide_work_route, inst);
  417. if (rc) {
  418. s_vpr_e(inst->sid, "%s: decide_work_route failed\n",
  419. __func__);
  420. return -EINVAL;
  421. }
  422. pipe = inst->pipe;
  423. s_vpr_h(inst->sid, "%s: pipe: %d", __func__, pipe);
  424. rc = venus_hfi_session_property(inst,
  425. HFI_PROP_PIPE,
  426. HFI_HOST_FLAGS_NONE,
  427. HFI_PORT_NONE,
  428. HFI_PAYLOAD_U32,
  429. &inst->pipe,
  430. sizeof(u32));
  431. if (rc)
  432. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  433. return rc;
  434. }
  435. static int msm_vdec_set_output_order(struct msm_vidc_inst *inst,
  436. enum msm_vidc_port_type port)
  437. {
  438. int rc = 0;
  439. u32 output_order;
  440. if (port != INPUT_PORT) {
  441. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  442. return -EINVAL;
  443. }
  444. output_order = inst->capabilities->cap[DISPLAY_DELAY_ENABLE].value;
  445. s_vpr_h(inst->sid, "%s: output order: %d", __func__, output_order);
  446. rc = venus_hfi_session_property(inst,
  447. HFI_PROP_DECODE_ORDER_OUTPUT,
  448. HFI_HOST_FLAGS_NONE,
  449. get_hfi_port(inst, port),
  450. HFI_PAYLOAD_U32,
  451. &output_order,
  452. sizeof(u32));
  453. if (rc)
  454. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  455. return rc;
  456. }
  457. static int msm_vdec_set_secure_mode(struct msm_vidc_inst *inst,
  458. enum msm_vidc_port_type port)
  459. {
  460. int rc = 0;
  461. u32 secure_mode;
  462. secure_mode = inst->capabilities->cap[SECURE_MODE].value;
  463. s_vpr_h(inst->sid, "%s: secure mode: %d", __func__, secure_mode);
  464. rc = venus_hfi_session_property(inst,
  465. HFI_PROP_SECURE,
  466. HFI_HOST_FLAGS_NONE,
  467. HFI_PORT_NONE,
  468. HFI_PAYLOAD_U32,
  469. &secure_mode,
  470. sizeof(u32));
  471. if (rc)
  472. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  473. return rc;
  474. }
  475. static int msm_vdec_set_thumbnail_mode(struct msm_vidc_inst *inst,
  476. enum msm_vidc_port_type port)
  477. {
  478. int rc = 0;
  479. u32 thumbnail_mode = 0;
  480. if (port != INPUT_PORT) {
  481. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  482. return -EINVAL;
  483. }
  484. s_vpr_h(inst->sid, "%s: thumbnail mode: %d", __func__, thumbnail_mode);
  485. rc = venus_hfi_session_property(inst,
  486. HFI_PROP_THUMBNAIL_MODE,
  487. HFI_HOST_FLAGS_NONE,
  488. get_hfi_port(inst, port),
  489. HFI_PAYLOAD_U32,
  490. &thumbnail_mode,
  491. sizeof(u32));
  492. if (rc)
  493. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  494. return rc;
  495. }
  496. static int msm_vdec_set_realtime(struct msm_vidc_inst *inst,
  497. enum msm_vidc_port_type port)
  498. {
  499. int rc = 0;
  500. u32 realtime = 1; //todo
  501. if (port != INPUT_PORT) {
  502. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  503. return -EINVAL;
  504. }
  505. s_vpr_h(inst->sid, "%s: priority: %d", __func__, realtime);
  506. rc = venus_hfi_session_property(inst,
  507. HFI_PROP_REALTIME,
  508. HFI_HOST_FLAGS_NONE,
  509. get_hfi_port(inst, port),
  510. HFI_PAYLOAD_U32,
  511. &realtime,
  512. sizeof(u32));
  513. if (rc)
  514. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  515. return rc;
  516. }
  517. static int msm_vdec_set_conceal_color_8bit(struct msm_vidc_inst *inst,
  518. enum msm_vidc_port_type port)
  519. {
  520. int rc = 0;
  521. u32 conceal_color_8bit;
  522. if (port != INPUT_PORT) {
  523. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  524. return -EINVAL;
  525. }
  526. conceal_color_8bit = inst->capabilities->cap[CONCEAL_COLOR_8BIT].value;
  527. s_vpr_h(inst->sid, "%s: conceal color 8bit: %#x",
  528. __func__, conceal_color_8bit);
  529. rc = venus_hfi_session_property(inst,
  530. HFI_PROP_CONCEAL_COLOR_8BIT,
  531. HFI_HOST_FLAGS_NONE,
  532. get_hfi_port(inst, port),
  533. HFI_PAYLOAD_32_PACKED,
  534. &conceal_color_8bit,
  535. sizeof(u32));
  536. if (rc)
  537. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  538. return rc;
  539. }
  540. static int msm_vdec_set_conceal_color_10bit(struct msm_vidc_inst *inst,
  541. enum msm_vidc_port_type port)
  542. {
  543. int rc = 0;
  544. u32 conceal_color_10bit;
  545. if (port != INPUT_PORT) {
  546. s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
  547. return -EINVAL;
  548. }
  549. conceal_color_10bit = inst->capabilities->cap[CONCEAL_COLOR_8BIT].value;
  550. s_vpr_h(inst->sid, "%s: conceal color 10bit: %#x",
  551. __func__, conceal_color_10bit);
  552. rc = venus_hfi_session_property(inst,
  553. HFI_PROP_CONCEAL_COLOR_10BIT,
  554. HFI_HOST_FLAGS_NONE,
  555. get_hfi_port(inst, port),
  556. HFI_PAYLOAD_32_PACKED,
  557. &conceal_color_10bit,
  558. sizeof(u32));
  559. if (rc)
  560. s_vpr_e(inst->sid, "%s: set property failed\n", __func__);
  561. return rc;
  562. }
  563. static int msm_vdec_set_input_properties(struct msm_vidc_inst *inst)
  564. {
  565. int rc = 0;
  566. if (!inst) {
  567. d_vpr_e("%s: invalid params\n", __func__);
  568. return -EINVAL;
  569. }
  570. rc = msm_vdec_set_output_order(inst, INPUT_PORT);
  571. if (rc)
  572. return rc;
  573. rc = msm_vdec_set_secure_mode(inst, INPUT_PORT);
  574. if (rc)
  575. return rc;
  576. rc = msm_vdec_set_thumbnail_mode(inst, INPUT_PORT);
  577. if (rc)
  578. return rc;
  579. rc = msm_vdec_set_realtime(inst, INPUT_PORT);
  580. if (rc)
  581. return rc;
  582. rc = msm_vdec_set_conceal_color_8bit(inst, INPUT_PORT);
  583. if (rc)
  584. return rc;
  585. rc = msm_vdec_set_conceal_color_10bit(inst, INPUT_PORT);
  586. if (rc)
  587. return rc;
  588. return rc;
  589. }
  590. static int msm_vdec_set_output_properties(struct msm_vidc_inst *inst)
  591. {
  592. int rc = 0;
  593. if (!inst) {
  594. d_vpr_e("%s: invalid params\n", __func__);
  595. return -EINVAL;
  596. }
  597. rc = msm_vdec_set_colorformat(inst);
  598. if (rc)
  599. return rc;
  600. rc = msm_vdec_set_stage(inst);
  601. if (rc)
  602. return rc;
  603. rc = msm_vdec_set_pipe(inst);
  604. if (rc)
  605. return rc;
  606. rc = msm_vdec_set_linear_stride_scanline(inst);
  607. if (rc)
  608. return rc;
  609. return rc;
  610. }
  611. static int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst)
  612. {
  613. int rc = 0;
  614. struct msm_vidc_core *core;
  615. if (!inst || !inst->core) {
  616. d_vpr_e("%s: invalid params\n", __func__);
  617. return -EINVAL;
  618. }
  619. core = inst->core;
  620. /*
  621. * TODO: Remove the hack of sending bigger buffer sizes
  622. * once internal buffer calculations are finalised
  623. */
  624. inst->buffers.bin.size = call_session_op(core, buffer_size,
  625. inst, MSM_VIDC_BUF_BIN) + 100000000;
  626. inst->buffers.comv.size = call_session_op(core, buffer_size,
  627. inst, MSM_VIDC_BUF_COMV) + 100000000;
  628. inst->buffers.non_comv.size = call_session_op(core, buffer_size,
  629. inst, MSM_VIDC_BUF_NON_COMV) + 100000000;
  630. inst->buffers.line.size = call_session_op(core, buffer_size,
  631. inst, MSM_VIDC_BUF_LINE) + 100000000;
  632. inst->buffers.persist.size = call_session_op(core, buffer_size,
  633. inst, MSM_VIDC_BUF_PERSIST) + 100000000;
  634. inst->buffers.bin.min_count = call_session_op(core, min_count,
  635. inst, MSM_VIDC_BUF_BIN);
  636. inst->buffers.comv.min_count = call_session_op(core, min_count,
  637. inst, MSM_VIDC_BUF_COMV);
  638. inst->buffers.non_comv.min_count = call_session_op(core, min_count,
  639. inst, MSM_VIDC_BUF_NON_COMV);
  640. inst->buffers.line.min_count = call_session_op(core, min_count,
  641. inst, MSM_VIDC_BUF_LINE);
  642. inst->buffers.persist.min_count = call_session_op(core, min_count,
  643. inst, MSM_VIDC_BUF_PERSIST);
  644. s_vpr_h(inst->sid, "internal buffer: min size\n");
  645. s_vpr_h(inst->sid, "bin buffer: %d %d\n",
  646. inst->buffers.bin.min_count,
  647. inst->buffers.bin.size);
  648. s_vpr_h(inst->sid, "comv buffer: %d %d\n",
  649. inst->buffers.comv.min_count,
  650. inst->buffers.comv.size);
  651. s_vpr_h(inst->sid, "non_comv buffer: %d %d\n",
  652. inst->buffers.non_comv.min_count,
  653. inst->buffers.non_comv.size);
  654. s_vpr_h(inst->sid, "line buffer: %d %d\n",
  655. inst->buffers.line.min_count,
  656. inst->buffers.line.size);
  657. s_vpr_h(inst->sid, "persist buffer: %d %d\n",
  658. inst->buffers.persist.min_count,
  659. inst->buffers.persist.size);
  660. return rc;
  661. }
  662. static int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst)
  663. {
  664. int rc = 0;
  665. d_vpr_h("%s()\n", __func__);
  666. if (!inst || !inst->core) {
  667. d_vpr_e("%s: invalid params\n", __func__);
  668. return -EINVAL;
  669. }
  670. rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_BIN);
  671. if (rc)
  672. return rc;
  673. rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_COMV);
  674. if (rc)
  675. return rc;
  676. rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_NON_COMV);
  677. if (rc)
  678. return rc;
  679. rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_LINE);
  680. if (rc)
  681. return rc;
  682. rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_PERSIST);
  683. if (rc)
  684. return rc;
  685. return 0;
  686. }
  687. static int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst)
  688. {
  689. int rc = 0;
  690. d_vpr_h("%s()\n", __func__);
  691. if (!inst || !inst->core) {
  692. d_vpr_e("%s: invalid params\n", __func__);
  693. return -EINVAL;
  694. }
  695. rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_BIN);
  696. if (rc)
  697. return rc;
  698. rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_COMV);
  699. if (rc)
  700. return rc;
  701. rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_NON_COMV);
  702. if (rc)
  703. return rc;
  704. rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_LINE);
  705. if (rc)
  706. return rc;
  707. rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_PERSIST);
  708. if (rc)
  709. return rc;
  710. return 0;
  711. }
  712. static int msm_vdec_release_input_internal_buffers(struct msm_vidc_inst *inst)
  713. {
  714. int rc = 0;
  715. d_vpr_h("%s()\n", __func__);
  716. if (!inst || !inst->core) {
  717. d_vpr_e("%s: invalid params\n", __func__);
  718. return -EINVAL;
  719. }
  720. rc = msm_vidc_release_internal_buffers(inst, MSM_VIDC_BUF_BIN);
  721. if (rc)
  722. return rc;
  723. rc = msm_vidc_release_internal_buffers(inst, MSM_VIDC_BUF_COMV);
  724. if (rc)
  725. return rc;
  726. rc = msm_vidc_release_internal_buffers(inst, MSM_VIDC_BUF_NON_COMV);
  727. if (rc)
  728. return rc;
  729. rc = msm_vidc_release_internal_buffers(inst, MSM_VIDC_BUF_LINE);
  730. if (rc)
  731. return rc;
  732. rc = msm_vidc_release_internal_buffers(inst, MSM_VIDC_BUF_PERSIST);
  733. if (rc)
  734. return rc;
  735. return 0;
  736. }
  737. int msm_vdec_subscribe_port_settings_change(struct msm_vidc_inst *inst,
  738. enum msm_vidc_port_type port)
  739. {
  740. int rc = 0;
  741. struct msm_vidc_core *core;
  742. u32 payload[32] = {0};
  743. u32 i;
  744. if (!inst || !inst->core) {
  745. d_vpr_e("%s: invalid params\n", __func__);
  746. return -EINVAL;
  747. }
  748. core = inst->core;
  749. d_vpr_h("%s()\n", __func__);
  750. payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
  751. for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change);
  752. i++)
  753. payload[i + 1] = msm_vdec_subscribe_for_port_settings_change[i];
  754. rc = venus_hfi_session_command(inst,
  755. HFI_CMD_SUBSCRIBE_MODE,
  756. port,
  757. HFI_PAYLOAD_U32_ARRAY,
  758. &payload[0],
  759. (ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change) + 1) *
  760. sizeof(u32));
  761. for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change);
  762. i++) {
  763. switch (msm_vdec_subscribe_for_port_settings_change[i]) {
  764. case HFI_PROP_BITSTREAM_RESOLUTION:
  765. rc = msm_vdec_set_bitstream_resolution(inst, port);
  766. break;
  767. case HFI_PROP_CROP_OFFSETS:
  768. rc = msm_vdec_set_crop_offsets(inst, port);
  769. break;
  770. case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
  771. rc = msm_vdec_set_bit_depth(inst, port);
  772. break;
  773. case HFI_PROP_CABAC_SESSION:
  774. rc = msm_vdec_set_cabac(inst, port);
  775. break;
  776. case HFI_PROP_CODED_FRAMES:
  777. rc = msm_vdec_set_coded_frames(inst, port);
  778. break;
  779. case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
  780. rc = msm_vdec_set_min_output_count(inst, port);
  781. break;
  782. case HFI_PROP_PIC_ORDER_CNT_TYPE:
  783. rc = msm_vdec_set_picture_order_count(inst, port);
  784. break;
  785. case HFI_PROP_SIGNAL_COLOR_INFO:
  786. rc = msm_vdec_set_colorspace(inst, port);
  787. break;
  788. case HFI_PROP_PROFILE:
  789. rc = msm_vdec_set_profile(inst, port);
  790. break;
  791. case HFI_PROP_LEVEL:
  792. rc = msm_vdec_set_level(inst, port);
  793. break;
  794. case HFI_PROP_TIER:
  795. rc = msm_vdec_set_tier(inst, port);
  796. break;
  797. default:
  798. d_vpr_e("%s: unknown property %#x\n", __func__,
  799. msm_vdec_subscribe_for_port_settings_change[i]);
  800. rc = -EINVAL;
  801. break;
  802. }
  803. }
  804. return rc;
  805. }
  806. static int msm_vdec_subscribe_property(struct msm_vidc_inst *inst,
  807. enum msm_vidc_port_type port)
  808. {
  809. int rc = 0;
  810. struct msm_vidc_core *core;
  811. u32 payload[32] = {0};
  812. u32 i;
  813. if (!inst || !inst->core) {
  814. d_vpr_e("%s: invalid params\n", __func__);
  815. return -EINVAL;
  816. }
  817. core = inst->core;
  818. d_vpr_h("%s()\n", __func__);
  819. payload[0] = HFI_MODE_PROPERTY;
  820. for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_properties); i++)
  821. payload[i + 1] = msm_vdec_subscribe_for_properties[i];
  822. rc = venus_hfi_session_command(inst,
  823. HFI_CMD_SUBSCRIBE_MODE,
  824. port,
  825. HFI_PAYLOAD_U32_ARRAY,
  826. &payload[0],
  827. (ARRAY_SIZE(msm_vdec_subscribe_for_properties) + 1) *
  828. sizeof(u32));
  829. return rc;
  830. }
  831. static int msm_vdec_subscribe_metadata(struct msm_vidc_inst *inst,
  832. enum msm_vidc_port_type port)
  833. {
  834. int rc = 0;
  835. struct msm_vidc_core *core;
  836. u32 payload[32] = {0};
  837. u32 i;
  838. if (!inst || !inst->core) {
  839. d_vpr_e("%s: invalid params\n", __func__);
  840. return -EINVAL;
  841. }
  842. core = inst->core;
  843. d_vpr_h("%s()\n", __func__);
  844. payload[0] = HFI_MODE_METADATA;
  845. for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_metadata); i++)
  846. payload[i + 1] = msm_vdec_subscribe_for_metadata[i];
  847. rc = venus_hfi_session_command(inst,
  848. HFI_CMD_SUBSCRIBE_MODE,
  849. port,
  850. HFI_PAYLOAD_U32_ARRAY,
  851. &payload[0],
  852. (ARRAY_SIZE(msm_vdec_subscribe_for_metadata) + 1) *
  853. sizeof(u32));
  854. return rc;
  855. }
  856. static int msm_vdec_set_delivery_mode_metadata(struct msm_vidc_inst *inst,
  857. enum msm_vidc_port_type port)
  858. {
  859. int rc = 0;
  860. struct msm_vidc_core *core;
  861. u32 payload[32] = {0};
  862. u32 i;
  863. if (!inst || !inst->core) {
  864. d_vpr_e("%s: invalid params\n", __func__);
  865. return -EINVAL;
  866. }
  867. core = inst->core;
  868. d_vpr_h("%s()\n", __func__);
  869. payload[0] = HFI_MODE_METADATA;
  870. for (i = 0; i < ARRAY_SIZE(msm_vdec_deliver_as_metadata); i++)
  871. payload[i + 1] = msm_vdec_deliver_as_metadata[i];
  872. rc = venus_hfi_session_command(inst,
  873. HFI_CMD_DELIVERY_MODE,
  874. port,
  875. HFI_PAYLOAD_U32_ARRAY,
  876. &payload[0],
  877. (ARRAY_SIZE(msm_vdec_deliver_as_metadata) + 1) *
  878. sizeof(u32));
  879. return rc;
  880. }
  881. static int msm_vdec_session_resume(struct msm_vidc_inst *inst,
  882. enum msm_vidc_port_type port)
  883. {
  884. int rc = 0;
  885. if (!inst) {
  886. d_vpr_e("%s: invalid params\n", __func__);
  887. return -EINVAL;
  888. }
  889. d_vpr_h("%s()\n", __func__);
  890. rc = venus_hfi_session_command(inst,
  891. HFI_CMD_RESUME,
  892. port,
  893. HFI_PAYLOAD_NONE,
  894. NULL,
  895. 0);
  896. return rc;
  897. }
  898. static msm_vdec_update_input_properties(struct msm_vidc_inst *inst)
  899. {
  900. struct msm_vidc_subscription_params subsc_params;
  901. u32 width, height;
  902. subsc_params = inst->subcr_params[INPUT_PORT];
  903. width = (subsc_params.bitstream_resolution &
  904. HFI_BITMASK_BITSTREAM_WIDTH) >> 16;
  905. height = subsc_params.bitstream_resolution &
  906. HFI_BITMASK_BITSTREAM_HEIGHT;
  907. inst->fmts[INPUT_PORT].fmt.pix_mp.width = width;
  908. inst->fmts[INPUT_PORT].fmt.pix_mp.height = height;
  909. inst->fmts[OUTPUT_PORT].fmt.pix_mp.width = VENUS_Y_STRIDE(
  910. v4l2_colorformat_to_media(
  911. inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat, __func__),
  912. width);
  913. inst->fmts[OUTPUT_PORT].fmt.pix_mp.height = VENUS_Y_SCANLINES(
  914. v4l2_colorformat_to_media(
  915. inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat, __func__),
  916. height);
  917. //inst->fmts[OUTPUT_PORT].fmt.pix_mp.bytesperline =
  918. //inst->fmts[OUTPUT_PORT].fmt.pix_mp.width;
  919. inst->fmts[OUTPUT_PORT].fmt.pix_mp.colorspace =
  920. (subsc_params.color_info & 0xFF0000) >> 16;
  921. inst->fmts[OUTPUT_PORT].fmt.pix_mp.xfer_func =
  922. (subsc_params.color_info & 0xFF00) >> 8;
  923. inst->fmts[OUTPUT_PORT].fmt.pix_mp.ycbcr_enc =
  924. subsc_params.color_info & 0xFF;
  925. inst->buffers.output.min_count = subsc_params.fw_min_count;
  926. inst->crop.top = subsc_params.crop_offsets & 0xFFFF;
  927. inst->crop.left = (subsc_params.crop_offsets >> 16) & 0xFFFF;
  928. inst->crop.height = inst->fmts[INPUT_PORT].fmt.pix_mp.height -
  929. ((subsc_params.crop_offsets >> 32) & 0xFFFF);
  930. inst->crop.width = inst->fmts[INPUT_PORT].fmt.pix_mp.width -
  931. ((subsc_params.crop_offsets >> 48) & 0xFFFF);
  932. inst->capabilities->cap[PROFILE].value = subsc_params.profile;
  933. inst->capabilities->cap[LEVEL].value = subsc_params.level;
  934. inst->capabilities->cap[HEVC_TIER].value = subsc_params.tier;
  935. inst->capabilities->cap[ENTROPY_MODE].value = subsc_params.cabac;
  936. inst->capabilities->cap[POC].value = subsc_params.pic_order_cnt;
  937. return 0;
  938. }
  939. int msm_vdec_input_port_settings_change(struct msm_vidc_inst *inst)
  940. {
  941. u32 rc = 0;
  942. struct v4l2_event event = {0};
  943. if (!inst->vb2q[INPUT_PORT].streaming) {
  944. s_vpr_e(inst->sid, "%s: input port not streaming\n",
  945. __func__);
  946. return 0;
  947. }
  948. rc = msm_vdec_update_input_properties(inst);
  949. if (rc)
  950. return rc;
  951. event.type = V4L2_EVENT_SOURCE_CHANGE;
  952. event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
  953. v4l2_event_queue_fh(&inst->event_handler, &event);
  954. rc = msm_vdec_release_input_internal_buffers(inst);
  955. if (rc)
  956. return rc;
  957. rc = msm_vdec_get_input_internal_buffers(inst);
  958. if (rc)
  959. return rc;
  960. rc = msm_vdec_create_input_internal_buffers(inst);
  961. if (rc)
  962. return rc;
  963. rc = msm_vdec_queue_input_internal_buffers(inst);
  964. if (rc)
  965. return rc;
  966. rc = msm_vdec_session_resume(inst, INPUT_PORT);
  967. if (rc)
  968. return rc;
  969. return rc;
  970. }
  971. int msm_vdec_output_port_settings_change(struct msm_vidc_inst *inst)
  972. {
  973. //todo
  974. return 0;
  975. }
  976. int msm_vdec_stop_input(struct msm_vidc_inst *inst)
  977. {
  978. int rc = 0;
  979. if (!inst || !inst->core) {
  980. d_vpr_e("%s: invalid params\n", __func__);
  981. return -EINVAL;
  982. }
  983. rc = msm_vidc_session_stop(inst, INPUT_PORT);
  984. if (rc)
  985. return rc;
  986. return 0;
  987. }
  988. int msm_vdec_start_input(struct msm_vidc_inst *inst)
  989. {
  990. int rc = 0;
  991. struct msm_vidc_core *core;
  992. if (!inst || !inst->core) {
  993. d_vpr_e("%s: invalid params\n", __func__);
  994. return -EINVAL;
  995. }
  996. core = inst->core;
  997. s_vpr_h(inst->sid, "%s()\n", __func__);
  998. //rc = msm_vidc_check_session_supported(inst);
  999. if (rc)
  1000. goto error;
  1001. //rc = msm_vidc_check_scaling_supported(inst);
  1002. if (rc)
  1003. goto error;
  1004. rc = msm_vdec_set_input_properties(inst);
  1005. if (rc)
  1006. goto error;
  1007. /* Decide bse vpp delay after work mode */
  1008. //msm_vidc_set_bse_vpp_delay(inst);
  1009. rc = msm_vdec_get_input_internal_buffers(inst);
  1010. if (rc)
  1011. goto error;
  1012. /* check for memory after all buffers calculation */
  1013. //rc = msm_vidc_check_memory_supported(inst);
  1014. if (rc)
  1015. goto error;
  1016. //msm_vidc_update_dcvs(inst);
  1017. //msm_vidc_update_batching(inst);
  1018. //msm_vidc_scale_power(inst);
  1019. rc = msm_vdec_create_input_internal_buffers(inst);
  1020. if (rc)
  1021. goto error;
  1022. rc = msm_vdec_queue_input_internal_buffers(inst);
  1023. if (rc)
  1024. goto error;
  1025. rc = msm_vdec_subscribe_property(inst, INPUT_PORT);
  1026. if (rc)
  1027. return rc;
  1028. rc = msm_vdec_set_delivery_mode_metadata(inst, INPUT_PORT);
  1029. if (rc)
  1030. return rc;
  1031. rc = venus_hfi_start(inst, INPUT_PORT);
  1032. if (rc)
  1033. goto error;
  1034. s_vpr_h(inst->sid, "%s: done\n", __func__);
  1035. return 0;
  1036. error:
  1037. s_vpr_e(inst->sid, "%s: failed\n", __func__);
  1038. msm_vdec_stop_input(inst);
  1039. return rc;
  1040. }
  1041. int msm_vdec_stop_output(struct msm_vidc_inst *inst)
  1042. {
  1043. int rc = 0;
  1044. if (!inst || !inst->core) {
  1045. d_vpr_e("%s: invalid params\n", __func__);
  1046. return -EINVAL;
  1047. }
  1048. rc = msm_vidc_session_stop(inst, OUTPUT_PORT);
  1049. if (rc)
  1050. return rc;
  1051. return 0;
  1052. }
  1053. int msm_vdec_start_output(struct msm_vidc_inst *inst)
  1054. {
  1055. int rc = 0;
  1056. d_vpr_h("%s()\n", __func__);
  1057. if (!inst || !inst->core) {
  1058. d_vpr_e("%s: invalid params\n", __func__);
  1059. return -EINVAL;
  1060. }
  1061. rc = msm_vdec_set_output_properties(inst);
  1062. if (rc)
  1063. goto error;
  1064. rc = msm_vdec_subscribe_metadata(inst, OUTPUT_PORT);
  1065. if (rc)
  1066. return rc;
  1067. rc = venus_hfi_start(inst, OUTPUT_PORT);
  1068. if (rc)
  1069. goto error;
  1070. d_vpr_h("%s: done\n", __func__);
  1071. return 0;
  1072. error:
  1073. msm_vdec_stop_output(inst);
  1074. return rc;
  1075. }
  1076. static int msm_vdec_qbuf_batch(struct msm_vidc_inst *inst,
  1077. struct vb2_buffer *vb2)
  1078. {
  1079. int rc = 0;
  1080. if (!inst || !vb2) {
  1081. d_vpr_e("%s: invalid params\n", __func__);
  1082. return -EINVAL;
  1083. }
  1084. d_vpr_h("%s()\n", __func__);
  1085. return rc;
  1086. }
  1087. int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
  1088. {
  1089. int rc = 0;
  1090. if (inst->decode_batch.enable)
  1091. rc = msm_vdec_qbuf_batch(inst, vb2);
  1092. else
  1093. rc = msm_vidc_queue_buffer(inst, vb2);
  1094. return rc;
  1095. }
  1096. int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
  1097. {
  1098. int rc = 0;
  1099. if (!inst || !inst->core) {
  1100. d_vpr_e("%s: invalid params\n", __func__);
  1101. return -EINVAL;
  1102. }
  1103. if (cmd == V4L2_DEC_CMD_STOP) {
  1104. rc = venus_hfi_session_command(inst,
  1105. HFI_CMD_DRAIN,
  1106. INPUT_PORT,
  1107. HFI_PAYLOAD_NONE,
  1108. NULL,
  1109. 0);
  1110. if (rc)
  1111. return rc;
  1112. } else {
  1113. d_vpr_e("%s: unknown cmd %d\n", __func__, cmd);
  1114. return -EINVAL;
  1115. }
  1116. return 0;
  1117. }
  1118. int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
  1119. {
  1120. int rc = 0;
  1121. struct msm_vidc_core *core;
  1122. struct v4l2_format *fmt;
  1123. d_vpr_h("%s()\n", __func__);
  1124. if (!inst || !inst->core) {
  1125. d_vpr_e("%s: invalid params\n", __func__);
  1126. return -EINVAL;
  1127. }
  1128. core = inst->core;
  1129. if (inst->state == MSM_VIDC_START) {
  1130. d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
  1131. return -EINVAL;
  1132. }
  1133. if (f->type == INPUT_MPLANE) {
  1134. if (inst->state == MSM_VIDC_START_INPUT) {
  1135. d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
  1136. return -EINVAL;
  1137. }
  1138. if (inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat !=
  1139. f->fmt.pix_mp.pixelformat) {
  1140. s_vpr_e(inst->sid,
  1141. "%s: codec changed from %#x to %#x\n", __func__,
  1142. inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat,
  1143. f->fmt.pix_mp.pixelformat);
  1144. rc = msm_vdec_codec_change(inst, f->fmt.pix_mp.pixelformat);
  1145. if (rc)
  1146. goto err_invalid_fmt;
  1147. }
  1148. fmt = &inst->fmts[INPUT_PORT];
  1149. fmt->type = INPUT_MPLANE;
  1150. fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 16);
  1151. fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 16);
  1152. fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
  1153. fmt->fmt.pix_mp.num_planes = 1;
  1154. fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
  1155. fmt->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core,
  1156. buffer_size, inst, MSM_VIDC_BUF_INPUT);
  1157. inst->buffers.input.min_count = call_session_op(core,
  1158. min_count, inst, MSM_VIDC_BUF_INPUT);
  1159. inst->buffers.input.extra_count = call_session_op(core,
  1160. extra_count, inst, MSM_VIDC_BUF_INPUT);
  1161. if (inst->buffers.input.actual_count <
  1162. inst->buffers.input.min_count +
  1163. inst->buffers.input.extra_count) {
  1164. inst->buffers.input.actual_count =
  1165. inst->buffers.input.min_count +
  1166. inst->buffers.input.extra_count;
  1167. }
  1168. inst->buffers.input.size =
  1169. fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
  1170. /* update crop dimensions */
  1171. inst->crop.left = inst->crop.top = 0;
  1172. inst->crop.width = f->fmt.pix_mp.width;
  1173. inst->crop.height = f->fmt.pix_mp.height;
  1174. //rc = msm_vidc_check_session_supported(inst);
  1175. if (rc)
  1176. goto err_invalid_fmt;
  1177. //update_log_ctxt(inst->sid, inst->session_type,
  1178. // mplane->pixelformat);
  1179. s_vpr_h(inst->sid,
  1180. "%s: input: codec %#x width %d height %d size %d min_count %d extra_count %d\n",
  1181. __func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width,
  1182. f->fmt.pix_mp.height,
  1183. fmt->fmt.pix_mp.plane_fmt[0].sizeimage,
  1184. inst->buffers.input.min_count,
  1185. inst->buffers.input.extra_count);
  1186. //msm_vidc_update_dcvs(inst);
  1187. //msm_vidc_update_batching(inst);
  1188. } else if (f->type == INPUT_META_PLANE) {
  1189. if (inst->state == MSM_VIDC_START_INPUT) {
  1190. d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
  1191. return -EINVAL;
  1192. }
  1193. fmt = &inst->fmts[INPUT_META_PORT];
  1194. fmt->type = INPUT_META_PLANE;
  1195. fmt->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  1196. fmt->fmt.meta.buffersize = call_session_op(core, buffer_size,
  1197. inst, MSM_VIDC_BUF_INPUT_META);
  1198. inst->buffers.input_meta.min_count =
  1199. inst->buffers.input.min_count;
  1200. inst->buffers.input_meta.extra_count =
  1201. inst->buffers.input.extra_count;
  1202. inst->buffers.input_meta.actual_count =
  1203. inst->buffers.input.actual_count;
  1204. inst->buffers.input_meta.size = fmt->fmt.meta.buffersize;
  1205. s_vpr_h(inst->sid,
  1206. "%s: input meta: size %d min_count %d extra_count %d\n",
  1207. __func__, fmt->fmt.meta.buffersize,
  1208. inst->buffers.input_meta.min_count,
  1209. inst->buffers.input_meta.extra_count);
  1210. } else if (f->type == OUTPUT_MPLANE) {
  1211. if (inst->state == MSM_VIDC_START_OUTPUT) {
  1212. d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
  1213. return -EINVAL;
  1214. }
  1215. fmt = &inst->fmts[OUTPUT_PORT];
  1216. fmt->type = OUTPUT_MPLANE;
  1217. fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
  1218. fmt->fmt.pix_mp.width = VENUS_Y_STRIDE(
  1219. v4l2_colorformat_to_media(
  1220. fmt->fmt.pix_mp.pixelformat, __func__),
  1221. f->fmt.pix_mp.width);
  1222. fmt->fmt.pix_mp.height = VENUS_Y_SCANLINES(
  1223. v4l2_colorformat_to_media(
  1224. fmt->fmt.pix_mp.pixelformat, __func__),
  1225. f->fmt.pix_mp.height);
  1226. fmt->fmt.pix_mp.num_planes = 1;
  1227. fmt->fmt.pix_mp.plane_fmt[0].bytesperline =
  1228. fmt->fmt.pix_mp.width;
  1229. fmt->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core,
  1230. buffer_size, inst, MSM_VIDC_BUF_OUTPUT);
  1231. inst->buffers.output.min_count = call_session_op(core,
  1232. min_count, inst, MSM_VIDC_BUF_OUTPUT);
  1233. inst->buffers.output.extra_count = call_session_op(core,
  1234. extra_count, inst, MSM_VIDC_BUF_OUTPUT);
  1235. if (inst->buffers.output.actual_count <
  1236. inst->buffers.output.min_count +
  1237. inst->buffers.output.extra_count) {
  1238. inst->buffers.output.actual_count =
  1239. inst->buffers.output.min_count +
  1240. inst->buffers.output.extra_count;
  1241. }
  1242. inst->buffers.output.size =
  1243. fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
  1244. //rc = msm_vidc_check_session_supported(inst);
  1245. if (rc)
  1246. goto err_invalid_fmt;
  1247. s_vpr_h(inst->sid,
  1248. "%s: output: format %#x width %d height %d size %d min_count %d extra_count %d\n",
  1249. __func__, fmt->fmt.pix_mp.pixelformat, fmt->fmt.pix_mp.width,
  1250. fmt->fmt.pix_mp.height,
  1251. fmt->fmt.pix_mp.plane_fmt[0].sizeimage,
  1252. inst->buffers.output.min_count,
  1253. inst->buffers.output.extra_count);
  1254. } else if (f->type == OUTPUT_META_PLANE) {
  1255. if (inst->state == MSM_VIDC_START_OUTPUT) {
  1256. d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
  1257. return -EINVAL;
  1258. }
  1259. fmt = &inst->fmts[OUTPUT_META_PORT];
  1260. fmt->type = OUTPUT_META_PLANE;
  1261. fmt->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  1262. fmt->fmt.meta.buffersize = call_session_op(core, buffer_size,
  1263. inst, MSM_VIDC_BUF_OUTPUT_META);
  1264. inst->buffers.output_meta.min_count =
  1265. inst->buffers.output.min_count;
  1266. inst->buffers.output_meta.extra_count =
  1267. inst->buffers.output.extra_count;
  1268. inst->buffers.output_meta.actual_count =
  1269. inst->buffers.output.actual_count;
  1270. inst->buffers.output_meta.size = fmt->fmt.meta.buffersize;
  1271. s_vpr_h(inst->sid,
  1272. "%s: output meta: size %d min_count %d extra_count %d\n",
  1273. __func__, fmt->fmt.meta.buffersize,
  1274. inst->buffers.output_meta.min_count,
  1275. inst->buffers.output_meta.extra_count);
  1276. } else {
  1277. s_vpr_e(inst->sid, "%s: invalid type %d\n", __func__, f->type);
  1278. goto err_invalid_fmt;
  1279. }
  1280. memcpy(f, fmt, sizeof(struct v4l2_format));
  1281. err_invalid_fmt:
  1282. return rc;
  1283. }
  1284. int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
  1285. {
  1286. int rc = 0;
  1287. int port;
  1288. d_vpr_h("%s()\n", __func__);
  1289. if (!inst) {
  1290. d_vpr_e("%s: invalid params\n", __func__);
  1291. return -EINVAL;
  1292. }
  1293. port = v4l2_type_to_driver_port(inst, f->type, __func__);
  1294. if (port < 0)
  1295. return -EINVAL;
  1296. memcpy(f, &inst->fmts[port], sizeof(struct v4l2_format));
  1297. return rc;
  1298. }
  1299. int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
  1300. {
  1301. int rc = 0;
  1302. struct msm_vidc_core *core;
  1303. u32 array[32] = {0};
  1304. u32 i = 0, idx = 0;
  1305. if (!inst || !inst->core || !inst->capabilities || !f) {
  1306. d_vpr_e("%s: invalid params\n", __func__);
  1307. return -EINVAL;
  1308. }
  1309. core = inst->core;
  1310. if (f->type == INPUT_MPLANE) {
  1311. u32 codecs = core->capabilities[DEC_CODECS].value;
  1312. while (codecs) {
  1313. if (idx > 31)
  1314. break;
  1315. if (codecs & BIT(i)) {
  1316. array[idx] = codecs & BIT(i);
  1317. idx++;
  1318. }
  1319. i++;
  1320. codecs >>= 1;
  1321. }
  1322. f->pixelformat = v4l2_codec_from_driver(array[f->index],
  1323. __func__);
  1324. if (!f->pixelformat)
  1325. return -EINVAL;
  1326. f->flags = V4L2_FMT_FLAG_COMPRESSED;
  1327. strlcpy(f->description, "codec", sizeof(f->description));
  1328. } else if (f->type == OUTPUT_MPLANE) {
  1329. u32 formats = inst->capabilities->cap[PIX_FMTS].step_or_mask;
  1330. while (formats) {
  1331. if (idx > 31)
  1332. break;
  1333. if (formats & BIT(i)) {
  1334. array[idx] = formats & BIT(i);
  1335. idx++;
  1336. }
  1337. i++;
  1338. formats >>= 1;
  1339. }
  1340. f->pixelformat = v4l2_colorformat_from_driver(array[f->index],
  1341. __func__);
  1342. if (!f->pixelformat)
  1343. return -EINVAL;
  1344. strlcpy(f->description, "colorformat", sizeof(f->description));
  1345. } else if (f->type == INPUT_META_PLANE || f->type == OUTPUT_META_PLANE) {
  1346. if (!f->index) {
  1347. f->pixelformat = V4L2_META_FMT_VIDC;
  1348. strlcpy(f->description, "metadata", sizeof(f->description));
  1349. } else {
  1350. return -EINVAL;
  1351. }
  1352. }
  1353. memset(f->reserved, 0, sizeof(f->reserved));
  1354. s_vpr_h(inst->sid, "%s: index %d, %s : %#x, flags %#x\n",
  1355. __func__, f->index, f->description, f->pixelformat, f->flags);
  1356. return rc;
  1357. }
  1358. int msm_vdec_inst_init(struct msm_vidc_inst *inst)
  1359. {
  1360. int rc = 0;
  1361. struct msm_vidc_core *core;
  1362. struct v4l2_format *f;
  1363. d_vpr_h("%s()\n", __func__);
  1364. if (!inst || !inst->core) {
  1365. d_vpr_e("%s: invalid params\n", __func__);
  1366. return -EINVAL;
  1367. }
  1368. core = inst->core;
  1369. INIT_DELAYED_WORK(&inst->decode_batch.work, msm_vidc_batch_handler);
  1370. f = &inst->fmts[INPUT_PORT];
  1371. f->type = INPUT_MPLANE;
  1372. f->fmt.pix_mp.width = DEFAULT_WIDTH;
  1373. f->fmt.pix_mp.height = DEFAULT_HEIGHT;
  1374. f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
  1375. f->fmt.pix_mp.num_planes = 1;
  1376. f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
  1377. f->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core,
  1378. buffer_size, inst, MSM_VIDC_BUF_INPUT);
  1379. inst->buffers.input.min_count = call_session_op(core,
  1380. min_count, inst, MSM_VIDC_BUF_INPUT);
  1381. inst->buffers.input.extra_count = call_session_op(core,
  1382. extra_count, inst, MSM_VIDC_BUF_INPUT);
  1383. inst->buffers.input.actual_count =
  1384. inst->buffers.input.min_count +
  1385. inst->buffers.input.extra_count;
  1386. inst->buffers.input.size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
  1387. inst->crop.left = inst->crop.top = 0;
  1388. inst->crop.width = f->fmt.pix_mp.width;
  1389. inst->crop.height = f->fmt.pix_mp.height;
  1390. f = &inst->fmts[INPUT_META_PORT];
  1391. f->type = INPUT_META_PLANE;
  1392. f->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  1393. f->fmt.meta.buffersize = call_session_op(core, buffer_size,
  1394. inst, MSM_VIDC_BUF_INPUT_META);
  1395. inst->buffers.input_meta.min_count = inst->buffers.input.min_count;
  1396. inst->buffers.input_meta.extra_count = inst->buffers.input.extra_count;
  1397. inst->buffers.input_meta.actual_count = inst->buffers.input.actual_count;
  1398. inst->buffers.input_meta.size = f->fmt.meta.buffersize;
  1399. f = &inst->fmts[OUTPUT_PORT];
  1400. f->type = OUTPUT_MPLANE;
  1401. f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VIDC_NV12C;
  1402. f->fmt.pix_mp.width = VENUS_Y_STRIDE(
  1403. v4l2_colorformat_to_media(f->fmt.pix_mp.pixelformat, __func__),
  1404. DEFAULT_WIDTH);
  1405. f->fmt.pix_mp.height = VENUS_Y_SCANLINES(
  1406. v4l2_colorformat_to_media(f->fmt.pix_mp.pixelformat, __func__),
  1407. DEFAULT_HEIGHT);
  1408. f->fmt.pix_mp.num_planes = 1;
  1409. f->fmt.pix_mp.plane_fmt[0].bytesperline = f->fmt.pix_mp.width;
  1410. f->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core,
  1411. buffer_size, inst, MSM_VIDC_BUF_OUTPUT);
  1412. inst->buffers.output.min_count = call_session_op(core,
  1413. min_count, inst, MSM_VIDC_BUF_OUTPUT);
  1414. inst->buffers.output.extra_count = call_session_op(core,
  1415. extra_count, inst, MSM_VIDC_BUF_OUTPUT);
  1416. inst->buffers.output.actual_count =
  1417. inst->buffers.output.min_count +
  1418. inst->buffers.output.extra_count;
  1419. inst->buffers.output.size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
  1420. f = &inst->fmts[OUTPUT_META_PORT];
  1421. f->type = OUTPUT_META_PLANE;
  1422. f->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
  1423. f->fmt.meta.buffersize = call_session_op(core, buffer_size,
  1424. inst, MSM_VIDC_BUF_OUTPUT_META);
  1425. inst->buffers.output_meta.min_count = inst->buffers.output.min_count;
  1426. inst->buffers.output_meta.extra_count = inst->buffers.output.extra_count;
  1427. inst->buffers.output_meta.actual_count = inst->buffers.output.actual_count;
  1428. inst->buffers.output_meta.size = f->fmt.meta.buffersize;
  1429. inst->prop.frame_rate = DEFAULT_FPS << 16;
  1430. inst->prop.operating_rate = DEFAULT_FPS << 16;
  1431. inst->stage = MSM_VIDC_STAGE_2;
  1432. inst->pipe = MSM_VIDC_PIPE_4;
  1433. rc = msm_vdec_codec_change(inst,
  1434. inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat);
  1435. return rc;
  1436. }