msm_vidc_iris33.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2022, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include "msm_vidc_iris33.h"
  7. #include "msm_vidc_buffer_iris33.h"
  8. #include "msm_vidc_power_iris33.h"
  9. #include "venus_hfi.h"
  10. #include "msm_vidc_inst.h"
  11. #include "msm_vidc_core.h"
  12. #include "msm_vidc_driver.h"
  13. #include "msm_vidc_control.h"
  14. #include "msm_vidc_internal.h"
  15. #include "msm_vidc_buffer.h"
  16. #include "msm_vidc_debug.h"
  17. #include "msm_vidc_variant.h"
  18. #define VIDEO_ARCH_LX 1
  19. #define VCODEC_BASE_OFFS_IRIS33 0x00000000
  20. #define AON_MVP_NOC_RESET 0x0001F000
  21. #define CPU_BASE_OFFS_IRIS33 0x000A0000
  22. #define AON_BASE_OFFS 0x000E0000
  23. #define VCODEC_VIDEO_CC_BASE 0x00F00000
  24. #define CPU_CS_BASE_OFFS_IRIS33 (CPU_BASE_OFFS_IRIS33)
  25. #define CPU_IC_BASE_OFFS_IRIS33 (CPU_BASE_OFFS_IRIS33)
  26. #define CPU_CS_A2HSOFTINTCLR_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x1C)
  27. #define CPU_CS_VCICMD_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x20)
  28. #define CPU_CS_VCICMDARG0_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x24)
  29. #define CPU_CS_VCICMDARG1_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x28)
  30. #define CPU_CS_VCICMDARG2_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x2C)
  31. #define CPU_CS_VCICMDARG3_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x30)
  32. #define CPU_CS_VMIMSG_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x34)
  33. #define CPU_CS_VMIMSGAG0_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x38)
  34. #define CPU_CS_VMIMSGAG1_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x3C)
  35. #define CPU_CS_SCIACMD_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x48)
  36. #define CPU_CS_H2XSOFTINTEN_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x148)
  37. /* HFI_CTRL_STATUS */
  38. #define CPU_CS_SCIACMDARG0_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x4C)
  39. #define CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS33 0xfe
  40. #define CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS33 0x100
  41. #define CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS33 0x40000000
  42. /* HFI_QTBL_INFO */
  43. #define CPU_CS_SCIACMDARG1_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x50)
  44. /* HFI_QTBL_ADDR */
  45. #define CPU_CS_SCIACMDARG2_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x54)
  46. /* HFI_VERSION_INFO */
  47. #define CPU_CS_SCIACMDARG3_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x58)
  48. /* SFR_ADDR */
  49. #define CPU_CS_SCIBCMD_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x5C)
  50. /* MMAP_ADDR */
  51. #define CPU_CS_SCIBCMDARG0_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x60)
  52. /* UC_REGION_ADDR */
  53. #define CPU_CS_SCIBARG1_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x64)
  54. /* UC_REGION_ADDR */
  55. #define CPU_CS_SCIBARG2_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x68)
  56. #define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS_IRIS33 + 0x160)
  57. #define CPU_CS_AHB_BRIDGE_SYNC_RESET_STATUS (CPU_CS_BASE_OFFS_IRIS33 + 0x164)
  58. /* FAL10 Feature Control */
  59. #define CPU_CS_X2RPMh_IRIS33 (CPU_CS_BASE_OFFS_IRIS33 + 0x168)
  60. #define CPU_CS_X2RPMh_MASK0_BMSK_IRIS33 0x1
  61. #define CPU_CS_X2RPMh_MASK0_SHFT_IRIS33 0x0
  62. #define CPU_CS_X2RPMh_MASK1_BMSK_IRIS33 0x2
  63. #define CPU_CS_X2RPMh_MASK1_SHFT_IRIS33 0x1
  64. #define CPU_CS_X2RPMh_SWOVERRIDE_BMSK_IRIS33 0x4
  65. #define CPU_CS_X2RPMh_SWOVERRIDE_SHFT_IRIS33 0x3
  66. #define CPU_IC_SOFTINT_IRIS33 (CPU_IC_BASE_OFFS_IRIS33 + 0x150)
  67. #define CPU_IC_SOFTINT_H2A_SHFT_IRIS33 0x0
  68. /*
  69. * --------------------------------------------------------------------------
  70. * MODULE: AON_MVP_NOC_RESET_REGISTERS
  71. * --------------------------------------------------------------------------
  72. */
  73. #define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
  74. #define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
  75. /*
  76. * --------------------------------------------------------------------------
  77. * MODULE: wrapper
  78. * --------------------------------------------------------------------------
  79. */
  80. #define WRAPPER_BASE_OFFS_IRIS33 0x000B0000
  81. #define WRAPPER_INTR_STATUS_IRIS33 (WRAPPER_BASE_OFFS_IRIS33 + 0x0C)
  82. #define WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS33 0x8
  83. #define WRAPPER_INTR_STATUS_A2H_BMSK_IRIS33 0x4
  84. #define WRAPPER_INTR_MASK_IRIS33 (WRAPPER_BASE_OFFS_IRIS33 + 0x10)
  85. #define WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS33 0x8
  86. #define WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS33 0x4
  87. #define WRAPPER_CPU_CLOCK_CONFIG_IRIS33 (WRAPPER_BASE_OFFS_IRIS33 + 0x2000)
  88. #define WRAPPER_CPU_CGC_DIS_IRIS33 (WRAPPER_BASE_OFFS_IRIS33 + 0x2010)
  89. #define WRAPPER_CPU_STATUS_IRIS33 (WRAPPER_BASE_OFFS_IRIS33 + 0x2014)
  90. #define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS33 (WRAPPER_BASE_OFFS_IRIS33 + 0x54)
  91. #define WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS33 (WRAPPER_BASE_OFFS_IRIS33 + 0x58)
  92. #define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS_IRIS33 + 0x5C)
  93. #define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS_IRIS33 + 0x60)
  94. #define WRAPPER_CORE_POWER_STATUS (WRAPPER_BASE_OFFS_IRIS33 + 0x80)
  95. #define WRAPPER_CORE_CLOCK_CONFIG_IRIS33 (WRAPPER_BASE_OFFS_IRIS33 + 0x88)
  96. /*
  97. * --------------------------------------------------------------------------
  98. * MODULE: tz_wrapper
  99. * --------------------------------------------------------------------------
  100. */
  101. #define WRAPPER_TZ_BASE_OFFS 0x000C0000
  102. #define WRAPPER_TZ_CPU_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS)
  103. #define WRAPPER_TZ_CPU_STATUS (WRAPPER_TZ_BASE_OFFS + 0x10)
  104. #define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14)
  105. #define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18)
  106. #define CTRL_INIT_IRIS33 CPU_CS_SCIACMD_IRIS33
  107. #define CTRL_STATUS_IRIS33 CPU_CS_SCIACMDARG0_IRIS33
  108. #define CTRL_ERROR_STATUS__M_IRIS33 \
  109. CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS33
  110. #define CTRL_INIT_IDLE_MSG_BMSK_IRIS33 \
  111. CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS33
  112. #define CTRL_STATUS_PC_READY_IRIS33 \
  113. CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS33
  114. #define QTBL_INFO_IRIS33 CPU_CS_SCIACMDARG1_IRIS33
  115. #define QTBL_ADDR_IRIS33 CPU_CS_SCIACMDARG2_IRIS33
  116. #define VERSION_INFO_IRIS33 CPU_CS_SCIACMDARG3_IRIS33
  117. #define SFR_ADDR_IRIS33 CPU_CS_SCIBCMD_IRIS33
  118. #define MMAP_ADDR_IRIS33 CPU_CS_SCIBCMDARG0_IRIS33
  119. #define UC_REGION_ADDR_IRIS33 CPU_CS_SCIBARG1_IRIS33
  120. #define UC_REGION_SIZE_IRIS33 CPU_CS_SCIBARG2_IRIS33
  121. #define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
  122. #define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
  123. #define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18)
  124. #define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
  125. #define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
  126. /*
  127. * --------------------------------------------------------------------------
  128. * MODULE: VCODEC_SS registers
  129. * --------------------------------------------------------------------------
  130. */
  131. #define VCODEC_SS_IDLE_STATUSn (VCODEC_BASE_OFFS_IRIS33 + 0x70)
  132. /*
  133. * --------------------------------------------------------------------------
  134. * MODULE: vcodec noc error log registers (iris33)
  135. * --------------------------------------------------------------------------
  136. */
  137. #define VCODEC_NOC_VIDEO_A_NOC_BASE_OFFS 0x00010000
  138. #define VCODEC_NOC_ERL_MAIN_SWID_LOW 0x00011200
  139. #define VCODEC_NOC_ERL_MAIN_SWID_HIGH 0x00011204
  140. #define VCODEC_NOC_ERL_MAIN_MAINCTL_LOW 0x00011208
  141. #define VCODEC_NOC_ERL_MAIN_ERRVLD_LOW 0x00011210
  142. #define VCODEC_NOC_ERL_MAIN_ERRCLR_LOW 0x00011218
  143. #define VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW 0x00011220
  144. #define VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH 0x00011224
  145. #define VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW 0x00011228
  146. #define VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH 0x0001122C
  147. #define VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW 0x00011230
  148. #define VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH 0x00011234
  149. #define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238
  150. #define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C
  151. /*
  152. * --------------------------------------------------------------------------
  153. * MODULE: VCODEC_VIDEO_CC registers
  154. * --------------------------------------------------------------------------
  155. */
  156. #define VCODEC_VIDEO_CC_MVS0C_CBCR (VCODEC_VIDEO_CC_BASE + 0x8064)
  157. #define VCODEC_VIDEO_CC_XO_CBCR (VCODEC_VIDEO_CC_BASE + 0x8124)
  158. static int __interrupt_init_iris33(struct msm_vidc_core *vidc_core)
  159. {
  160. struct msm_vidc_core *core = vidc_core;
  161. u32 mask_val = 0;
  162. int rc = 0;
  163. if (!core) {
  164. d_vpr_e("%s: invalid params\n", __func__);
  165. return -EINVAL;
  166. }
  167. /* All interrupts should be disabled initially 0x1F6 : Reset value */
  168. rc = __read_register(core, WRAPPER_INTR_MASK_IRIS33, &mask_val);
  169. if (rc)
  170. return rc;
  171. /* Write 0 to unmask CPU and WD interrupts */
  172. mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS33|
  173. WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS33);
  174. rc = __write_register(core, WRAPPER_INTR_MASK_IRIS33, mask_val);
  175. if (rc)
  176. return rc;
  177. return 0;
  178. }
  179. static int __setup_ucregion_memory_map_iris33(struct msm_vidc_core *vidc_core)
  180. {
  181. struct msm_vidc_core *core = vidc_core;
  182. u32 value;
  183. int rc = 0;
  184. if (!core) {
  185. d_vpr_e("%s: invalid params\n", __func__);
  186. return -EINVAL;
  187. }
  188. value = (u32)core->iface_q_table.align_device_addr;
  189. rc = __write_register(core, UC_REGION_ADDR_IRIS33, value);
  190. if (rc)
  191. return rc;
  192. value = SHARED_QSIZE;
  193. rc = __write_register(core, UC_REGION_SIZE_IRIS33, value);
  194. if (rc)
  195. return rc;
  196. value = (u32)core->iface_q_table.align_device_addr;
  197. rc = __write_register(core, QTBL_ADDR_IRIS33, value);
  198. if (rc)
  199. return rc;
  200. rc = __write_register(core, QTBL_INFO_IRIS33, 0x01);
  201. if (rc)
  202. return rc;
  203. /* update queues vaddr for debug purpose */
  204. value = (u32)((u64)core->iface_q_table.align_virtual_addr);
  205. rc = __write_register(core, CPU_CS_VCICMDARG0_IRIS33, value);
  206. if (rc)
  207. return rc;
  208. value = (u32)((u64)core->iface_q_table.align_virtual_addr >> 32);
  209. rc = __write_register(core, CPU_CS_VCICMDARG1_IRIS33, value);
  210. if (rc)
  211. return rc;
  212. if (core->sfr.align_device_addr) {
  213. value = (u32)core->sfr.align_device_addr + VIDEO_ARCH_LX;
  214. rc = __write_register(core, SFR_ADDR_IRIS33, value);
  215. if (rc)
  216. return rc;
  217. }
  218. return 0;
  219. }
  220. static bool is_iris33_hw_power_collapsed(struct msm_vidc_core *core)
  221. {
  222. int rc = 0;
  223. u32 value = 0, pwr_status = 0;
  224. rc = __read_register(core, WRAPPER_CORE_POWER_STATUS, &value);
  225. if (rc)
  226. return false;
  227. /* if BIT(1) is 1 then video hw power is on else off */
  228. pwr_status = value & BIT(1);
  229. return pwr_status ? false : true;
  230. }
  231. static int __power_off_iris33_hardware(struct msm_vidc_core *core)
  232. {
  233. int rc = 0, i;
  234. u32 value = 0;
  235. bool pwr_collapsed = false;
  236. /*
  237. * Incase hw power control is enabled, when CPU WD occurred, check for power
  238. * status to decide on executing NOC reset sequence before disabling power.
  239. * If there is no CPU WD and hw_power_control is enabled, fw is expected
  240. * to power collapse video hw always.
  241. */
  242. if (core->hw_power_control) {
  243. pwr_collapsed = is_iris33_hw_power_collapsed(core);
  244. if (core->cpu_watchdog) {
  245. if (pwr_collapsed) {
  246. d_vpr_e("%s: CPU WD and video hw power collapsed\n", __func__);
  247. goto disable_power;
  248. } else {
  249. d_vpr_e("%s: CPU WD and video hw is power ON\n", __func__);
  250. }
  251. } else {
  252. if (!pwr_collapsed)
  253. d_vpr_e("%s: video hw is not power collapsed\n", __func__);
  254. goto disable_power;
  255. }
  256. }
  257. /*
  258. * check to make sure core clock branch enabled else
  259. * we cannot read vcodec top idle register
  260. */
  261. rc = __read_register(core, WRAPPER_CORE_CLOCK_CONFIG_IRIS33, &value);
  262. if (rc)
  263. return rc;
  264. if (value) {
  265. d_vpr_h("%s: core clock config not enabled, enabling it to read vcodec registers\n",
  266. __func__);
  267. rc = __write_register(core, WRAPPER_CORE_CLOCK_CONFIG_IRIS33, 0);
  268. if (rc)
  269. return rc;
  270. }
  271. /*
  272. * add MNoC idle check before collapsing MVS0 per HPG update
  273. * poll for NoC DMA idle -> HPG 6.1.1
  274. */
  275. for (i = 0; i < core->capabilities[NUM_VPP_PIPE].value; i++) {
  276. rc = __read_register_with_poll_timeout(core, VCODEC_SS_IDLE_STATUSn + 4*i,
  277. 0x400000, 0x400000, 2000, 20000);
  278. if (rc)
  279. d_vpr_h("%s: VCODEC_SS_IDLE_STATUSn (%d) is not idle (%#x)\n",
  280. __func__, i, value);
  281. }
  282. /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
  283. rc = __write_register_masked(core, AON_WRAPPER_MVP_NOC_LPI_CONTROL,
  284. 0x1, BIT(0));
  285. if (rc)
  286. return rc;
  287. rc = __read_register_with_poll_timeout(core, AON_WRAPPER_MVP_NOC_LPI_STATUS,
  288. 0x1, 0x1, 200, 2000);
  289. if (rc)
  290. d_vpr_h("%s: AON_WRAPPER_MVP_NOC_LPI_CONTROL failed\n", __func__);
  291. rc = __write_register_masked(core, AON_WRAPPER_MVP_NOC_LPI_CONTROL,
  292. 0x0, BIT(0));
  293. if (rc)
  294. return rc;
  295. /*
  296. * Reset both sides of 2 ahb2ahb_bridges (TZ and non-TZ)
  297. * do we need to check status register here?
  298. */
  299. rc = __write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x3);
  300. if (rc)
  301. return rc;
  302. rc = __write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x2);
  303. if (rc)
  304. return rc;
  305. rc = __write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x0);
  306. if (rc)
  307. return rc;
  308. disable_power:
  309. /* power down process */
  310. rc = call_res_op(core, gdsc_off, core, "vcodec");
  311. if (rc) {
  312. d_vpr_e("%s: disable regulator vcodec failed\n", __func__);
  313. rc = 0;
  314. }
  315. rc = call_res_op(core, clk_disable, core, "vcodec_clk");
  316. if (rc) {
  317. d_vpr_e("%s: disable unprepare vcodec_clk failed\n", __func__);
  318. rc = 0;
  319. }
  320. return rc;
  321. }
  322. static int __power_off_iris33_controller(struct msm_vidc_core *core)
  323. {
  324. int rc = 0;
  325. int value = 0;
  326. /*
  327. * mask fal10_veto QLPAC error since fal10_veto can go 1
  328. * when pwwait == 0 and clamped to 0 -> HPG 6.1.2
  329. */
  330. rc = __write_register(core, CPU_CS_X2RPMh_IRIS33, 0x3);
  331. if (rc)
  332. return rc;
  333. /* Set Iris CPU NoC to Low power */
  334. rc = __write_register_masked(core, WRAPPER_IRIS_CPU_NOC_LPI_CONTROL,
  335. 0x1, BIT(0));
  336. if (rc)
  337. return rc;
  338. rc = __read_register_with_poll_timeout(core, WRAPPER_IRIS_CPU_NOC_LPI_STATUS,
  339. 0x1, 0x1, 200, 2000);
  340. if (rc)
  341. d_vpr_h("%s: WRAPPER_IRIS_CPU_NOC_LPI_CONTROL failed\n", __func__);
  342. /* Debug bridge LPI release */
  343. rc = __write_register(core, WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS33, 0x0);
  344. if (rc)
  345. return rc;
  346. rc = __read_register_with_poll_timeout(core, WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS33,
  347. 0xffffffff, 0x0, 200, 2000);
  348. if (rc)
  349. d_vpr_h("%s: debug bridge release failed\n", __func__);
  350. /* Reset MVP QNS4PDXFIFO */
  351. rc = __write_register(core, WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG, 0x3);
  352. if (rc)
  353. return rc;
  354. rc = __write_register(core, WRAPPER_TZ_QNS4PDXFIFO_RESET, 0x1);
  355. if (rc)
  356. return rc;
  357. rc = __write_register(core, WRAPPER_TZ_QNS4PDXFIFO_RESET, 0x0);
  358. if (rc)
  359. return rc;
  360. rc = __write_register(core, WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG, 0x0);
  361. if (rc)
  362. return rc;
  363. /* Disable MVP NoC clock */
  364. rc = __write_register_masked(core, AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL,
  365. 0x1, BIT(0));
  366. if (rc)
  367. return rc;
  368. /* enable MVP_CTL reset and enable Force Sleep Retention */
  369. rc = __write_register(core, VCODEC_VIDEO_CC_MVS0C_CBCR, 0x6005);
  370. if (rc)
  371. return rc;
  372. /* enable MVP NoC reset */
  373. rc = __write_register_masked(core, AON_WRAPPER_MVP_NOC_CORE_SW_RESET,
  374. 0x1, BIT(0));
  375. if (rc)
  376. return rc;
  377. /* enable vcodec video_cc XO reset and disable video_cc XO clock */
  378. rc = __read_register(core, AON_WRAPPER_SPARE, &value);
  379. if (rc)
  380. return rc;
  381. rc = __write_register(core, AON_WRAPPER_SPARE, value|0x2);
  382. if (rc)
  383. return rc;
  384. rc = __write_register(core, VCODEC_VIDEO_CC_XO_CBCR, 0x4);
  385. if (rc)
  386. return rc;
  387. /* De-assert MVP_CTL reset and enable Force Sleep Retention */
  388. rc = __write_register(core, VCODEC_VIDEO_CC_MVS0C_CBCR, 0x6001);
  389. if (rc)
  390. return rc;
  391. /* De-assert MVP NoC reset */
  392. rc = __write_register_masked(core, AON_WRAPPER_MVP_NOC_CORE_SW_RESET,
  393. 0x0, BIT(0));
  394. if (rc)
  395. return rc;
  396. /* De-assert video_cc XO reset and enable video_cc XO clock after 80us */
  397. usleep_range(80, 100);
  398. rc = __write_register(core, VCODEC_VIDEO_CC_XO_CBCR, 0x1);
  399. if (rc)
  400. return rc;
  401. /* Enable MVP NoC clock */
  402. rc = __write_register_masked(core, AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL,
  403. 0x0, BIT(0));
  404. if (rc)
  405. return rc;
  406. /* De-assert MVP_CTL Force Sleep Retention */
  407. rc = __write_register(core, VCODEC_VIDEO_CC_MVS0C_CBCR, 0x1);
  408. if (rc)
  409. return rc;
  410. /* Turn off MVP MVS0C core clock */
  411. rc = call_res_op(core, clk_disable, core, "core_clk");
  412. if (rc) {
  413. d_vpr_e("%s: disable unprepare core_clk failed\n", __func__);
  414. rc = 0;
  415. }
  416. /* power down process */
  417. rc = call_res_op(core, gdsc_off, core, "iris-ctl");
  418. if (rc) {
  419. d_vpr_e("%s: disable regulator iris-ctl failed\n", __func__);
  420. rc = 0;
  421. }
  422. /* Turn off GCC AXI clock */
  423. rc = call_res_op(core, clk_disable, core, "gcc_video_axi0");
  424. if (rc) {
  425. d_vpr_e("%s: disable unprepare core_clk failed\n", __func__);
  426. rc = 0;
  427. }
  428. return rc;
  429. }
  430. static int __power_off_iris33(struct msm_vidc_core *core)
  431. {
  432. int rc = 0;
  433. if (!core || !core->capabilities) {
  434. d_vpr_e("%s: invalid params\n", __func__);
  435. return -EINVAL;
  436. }
  437. if (!core->power_enabled)
  438. return 0;
  439. /**
  440. * Reset video_cc_mvs0_clk_src value to resolve MMRM high video
  441. * clock projection issue.
  442. */
  443. rc = call_res_op(core, set_clks, core, 0);
  444. if (rc)
  445. d_vpr_e("%s: resetting clocks failed\n", __func__);
  446. if (__power_off_iris33_hardware(core))
  447. d_vpr_e("%s: failed to power off hardware\n", __func__);
  448. if (__power_off_iris33_controller(core))
  449. d_vpr_e("%s: failed to power off controller\n", __func__);
  450. rc = call_res_op(core, set_bw, core, 0, 0);
  451. if (rc)
  452. d_vpr_e("%s: failed to unvote buses\n", __func__);
  453. if (!(core->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS33))
  454. disable_irq_nosync(core->resource->irq);
  455. core->intr_status = 0;
  456. core->power_enabled = false;
  457. return rc;
  458. }
  459. static int __power_on_iris33_controller(struct msm_vidc_core *core)
  460. {
  461. int rc = 0;
  462. rc = call_res_op(core, gdsc_on, core, "iris-ctl");
  463. if (rc)
  464. goto fail_regulator;
  465. rc = call_res_op(core, reset_bridge, core);
  466. if (rc)
  467. goto fail_reset_ahb2axi;
  468. rc = call_res_op(core, clk_enable, core, "gcc_video_axi0");
  469. if (rc)
  470. goto fail_clk_axi;
  471. rc = call_res_op(core, clk_enable, core, "core_clk");
  472. if (rc)
  473. goto fail_clk_controller;
  474. return 0;
  475. fail_clk_controller:
  476. call_res_op(core, clk_disable, core, "gcc_video_axi0");
  477. fail_clk_axi:
  478. fail_reset_ahb2axi:
  479. call_res_op(core, gdsc_off, core, "iris-ctl");
  480. fail_regulator:
  481. return rc;
  482. }
  483. static int __power_on_iris33_hardware(struct msm_vidc_core *core)
  484. {
  485. int rc = 0;
  486. rc = call_res_op(core, gdsc_on, core, "vcodec");
  487. if (rc)
  488. goto fail_regulator;
  489. rc = call_res_op(core, clk_enable, core, "vcodec_clk");
  490. if (rc)
  491. goto fail_clk_controller;
  492. return 0;
  493. fail_clk_controller:
  494. call_res_op(core, gdsc_off, core, "vcodec");
  495. fail_regulator:
  496. return rc;
  497. }
  498. static int __power_on_iris33(struct msm_vidc_core *core)
  499. {
  500. struct frequency_table *freq_tbl;
  501. u32 freq = 0;
  502. int rc = 0;
  503. if (core->power_enabled)
  504. return 0;
  505. /* Vote for all hardware resources */
  506. rc = call_res_op(core, set_bw, core, INT_MAX, INT_MAX);
  507. if (rc) {
  508. d_vpr_e("%s: failed to vote buses, rc %d\n", __func__, rc);
  509. goto fail_vote_buses;
  510. }
  511. rc = __power_on_iris33_controller(core);
  512. if (rc) {
  513. d_vpr_e("%s: failed to power on iris33 controller\n", __func__);
  514. goto fail_power_on_controller;
  515. }
  516. rc = __power_on_iris33_hardware(core);
  517. if (rc) {
  518. d_vpr_e("%s: failed to power on iris33 hardware\n", __func__);
  519. goto fail_power_on_hardware;
  520. }
  521. /* video controller and hardware powered on successfully */
  522. core->power_enabled = true;
  523. freq_tbl = core->resource->freq_set.freq_tbl;
  524. freq = core->power.clk_freq ? core->power.clk_freq :
  525. freq_tbl[0].freq;
  526. rc = call_res_op(core, set_clks, core, freq);
  527. if (rc) {
  528. d_vpr_e("%s: failed to scale clocks\n", __func__);
  529. rc = 0;
  530. }
  531. /*
  532. * Re-program all of the registers that get reset as a result of
  533. * regulator_disable() and _enable()
  534. */
  535. __set_registers(core);
  536. __interrupt_init_iris33(core);
  537. core->intr_status = 0;
  538. enable_irq(core->resource->irq);
  539. return rc;
  540. fail_power_on_hardware:
  541. __power_off_iris33_controller(core);
  542. fail_power_on_controller:
  543. call_res_op(core, set_bw, core, 0, 0);
  544. fail_vote_buses:
  545. core->power_enabled = false;
  546. return rc;
  547. }
  548. static int __prepare_pc_iris33(struct msm_vidc_core *vidc_core)
  549. {
  550. int rc = 0;
  551. u32 wfi_status = 0, idle_status = 0, pc_ready = 0;
  552. u32 ctrl_status = 0;
  553. struct msm_vidc_core *core = vidc_core;
  554. if (!core) {
  555. d_vpr_e("%s: invalid params\n", __func__);
  556. return -EINVAL;
  557. }
  558. rc = __read_register(core, CTRL_STATUS_IRIS33, &ctrl_status);
  559. if (rc)
  560. return rc;
  561. pc_ready = ctrl_status & CTRL_STATUS_PC_READY_IRIS33;
  562. idle_status = ctrl_status & BIT(30);
  563. if (pc_ready) {
  564. d_vpr_h("Already in pc_ready state\n");
  565. return 0;
  566. }
  567. rc = __read_register(core, WRAPPER_TZ_CPU_STATUS, &wfi_status);
  568. if (rc)
  569. return rc;
  570. wfi_status &= BIT(0);
  571. if (!wfi_status || !idle_status) {
  572. d_vpr_e("Skipping PC, wfi status not set\n");
  573. goto skip_power_off;
  574. }
  575. rc = __prepare_pc(core);
  576. if (rc) {
  577. d_vpr_e("Failed __prepare_pc %d\n", rc);
  578. goto skip_power_off;
  579. }
  580. rc = __read_register_with_poll_timeout(core, CTRL_STATUS_IRIS33,
  581. CTRL_STATUS_PC_READY_IRIS33, CTRL_STATUS_PC_READY_IRIS33, 250, 2500);
  582. if (rc) {
  583. d_vpr_e("%s: Skip PC. Ctrl status not set\n", __func__);
  584. goto skip_power_off;
  585. }
  586. rc = __read_register_with_poll_timeout(core, WRAPPER_TZ_CPU_STATUS,
  587. BIT(0), 0x1, 250, 2500);
  588. if (rc) {
  589. d_vpr_e("%s: Skip PC. Wfi status not set\n", __func__);
  590. goto skip_power_off;
  591. }
  592. return rc;
  593. skip_power_off:
  594. rc = __read_register(core, CTRL_STATUS_IRIS33, &ctrl_status);
  595. if (rc)
  596. return rc;
  597. rc = __read_register(core, WRAPPER_TZ_CPU_STATUS, &wfi_status);
  598. if (rc)
  599. return rc;
  600. wfi_status &= BIT(0);
  601. d_vpr_e("Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n",
  602. wfi_status, idle_status, pc_ready, ctrl_status);
  603. return -EAGAIN;
  604. }
  605. static int __raise_interrupt_iris33(struct msm_vidc_core *vidc_core)
  606. {
  607. struct msm_vidc_core *core = vidc_core;
  608. int rc = 0;
  609. if (!core) {
  610. d_vpr_e("%s: invalid params\n", __func__);
  611. return -EINVAL;
  612. }
  613. rc = __write_register(core, CPU_IC_SOFTINT_IRIS33, 1 << CPU_IC_SOFTINT_H2A_SHFT_IRIS33);
  614. if (rc)
  615. return rc;
  616. return 0;
  617. }
  618. static int __watchdog_iris33(struct msm_vidc_core *vidc_core, u32 intr_status)
  619. {
  620. int rc = 0;
  621. struct msm_vidc_core *core = vidc_core;
  622. if (!core) {
  623. d_vpr_e("%s: invalid params\n", __func__);
  624. return -EINVAL;
  625. }
  626. if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS33) {
  627. d_vpr_e("%s: received watchdog interrupt\n", __func__);
  628. rc = 1;
  629. }
  630. return rc;
  631. }
  632. static int __noc_error_info_iris33(struct msm_vidc_core *vidc_core)
  633. {
  634. struct msm_vidc_core *core = vidc_core;
  635. if (!core) {
  636. d_vpr_e("%s: invalid params\n", __func__);
  637. return -EINVAL;
  638. }
  639. /*
  640. * we are not supposed to access vcodec subsystem registers
  641. * unless vcodec core clock WRAPPER_CORE_CLOCK_CONFIG_IRIS33 is enabled.
  642. * core clock might have been disabled by video firmware as part of
  643. * inter frame power collapse (power plane control feature).
  644. */
  645. /*
  646. val = __read_register(core, VCODEC_NOC_ERL_MAIN_SWID_LOW);
  647. d_vpr_e("VCODEC_NOC_ERL_MAIN_SWID_LOW: %#x\n", val);
  648. val = __read_register(core, VCODEC_NOC_ERL_MAIN_SWID_HIGH);
  649. d_vpr_e("VCODEC_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val);
  650. val = __read_register(core, VCODEC_NOC_ERL_MAIN_MAINCTL_LOW);
  651. d_vpr_e("VCODEC_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val);
  652. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW);
  653. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val);
  654. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRCLR_LOW);
  655. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val);
  656. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW);
  657. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val);
  658. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH);
  659. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val);
  660. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW);
  661. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val);
  662. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH);
  663. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val);
  664. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW);
  665. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val);
  666. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH);
  667. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val);
  668. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW);
  669. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val);
  670. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH);
  671. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val);
  672. */
  673. return 0;
  674. }
  675. static int __clear_interrupt_iris33(struct msm_vidc_core *vidc_core)
  676. {
  677. struct msm_vidc_core *core = vidc_core;
  678. u32 intr_status = 0, mask = 0;
  679. int rc = 0;
  680. if (!core) {
  681. d_vpr_e("%s: NULL core\n", __func__);
  682. return 0;
  683. }
  684. rc = __read_register(core, WRAPPER_INTR_STATUS_IRIS33, &intr_status);
  685. if (rc)
  686. return rc;
  687. mask = (WRAPPER_INTR_STATUS_A2H_BMSK_IRIS33|
  688. WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS33|
  689. CTRL_INIT_IDLE_MSG_BMSK_IRIS33);
  690. if (intr_status & mask) {
  691. core->intr_status |= intr_status;
  692. core->reg_count++;
  693. d_vpr_l("INTERRUPT: times: %d interrupt_status: %d\n",
  694. core->reg_count, intr_status);
  695. } else {
  696. core->spur_count++;
  697. }
  698. rc = __write_register(core, CPU_CS_A2HSOFTINTCLR_IRIS33, 1);
  699. if (rc)
  700. return rc;
  701. return 0;
  702. }
  703. static int __boot_firmware_iris33(struct msm_vidc_core *vidc_core)
  704. {
  705. int rc = 0;
  706. u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000;
  707. struct msm_vidc_core *core = vidc_core;
  708. if (!core) {
  709. d_vpr_e("%s: NULL core\n", __func__);
  710. return 0;
  711. }
  712. rc = __setup_ucregion_memory_map_iris33(core);
  713. if (rc)
  714. return rc;
  715. ctrl_init_val = BIT(0);
  716. rc = __write_register(core, CTRL_INIT_IRIS33, ctrl_init_val);
  717. if (rc)
  718. return rc;
  719. while (!ctrl_status && count < max_tries) {
  720. rc = __read_register(core, CTRL_STATUS_IRIS33, &ctrl_status);
  721. if (rc)
  722. return rc;
  723. if ((ctrl_status & CTRL_ERROR_STATUS__M_IRIS33) == 0x4) {
  724. d_vpr_e("invalid setting for UC_REGION\n");
  725. break;
  726. }
  727. usleep_range(50, 100);
  728. count++;
  729. }
  730. if (count >= max_tries) {
  731. d_vpr_e("Error booting up vidc firmware\n");
  732. return -ETIME;
  733. }
  734. /* Enable interrupt before sending commands to venus */
  735. rc = __write_register(core, CPU_CS_H2XSOFTINTEN_IRIS33, 0x1);
  736. if (rc)
  737. return rc;
  738. rc = __write_register(core, CPU_CS_X2RPMh_IRIS33, 0x0);
  739. if (rc)
  740. return rc;
  741. return rc;
  742. }
  743. int msm_vidc_decide_work_mode_iris33(struct msm_vidc_inst* inst)
  744. {
  745. u32 work_mode;
  746. struct v4l2_format *inp_f;
  747. u32 width, height;
  748. bool res_ok = false;
  749. if (!inst || !inst->capabilities) {
  750. d_vpr_e("%s: invalid params\n", __func__);
  751. return -EINVAL;
  752. }
  753. work_mode = MSM_VIDC_STAGE_2;
  754. inp_f = &inst->fmts[INPUT_PORT];
  755. if (is_image_decode_session(inst))
  756. work_mode = MSM_VIDC_STAGE_1;
  757. if (is_image_session(inst))
  758. goto exit;
  759. if (is_decode_session(inst)) {
  760. height = inp_f->fmt.pix_mp.height;
  761. width = inp_f->fmt.pix_mp.width;
  762. res_ok = res_is_less_than(width, height, 1280, 720);
  763. if (inst->capabilities->cap[CODED_FRAMES].value ==
  764. CODED_FRAMES_INTERLACE ||
  765. inst->capabilities->cap[LOWLATENCY_MODE].value ||
  766. res_ok) {
  767. work_mode = MSM_VIDC_STAGE_1;
  768. }
  769. } else if (is_encode_session(inst)) {
  770. height = inst->crop.height;
  771. width = inst->crop.width;
  772. res_ok = !res_is_greater_than(width, height, 4096, 2160);
  773. if (res_ok &&
  774. (inst->capabilities->cap[LOWLATENCY_MODE].value)) {
  775. work_mode = MSM_VIDC_STAGE_1;
  776. }
  777. if (inst->capabilities->cap[SLICE_MODE].value ==
  778. V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
  779. work_mode = MSM_VIDC_STAGE_1;
  780. }
  781. if (inst->capabilities->cap[LOSSLESS].value)
  782. work_mode = MSM_VIDC_STAGE_2;
  783. if (!inst->capabilities->cap[GOP_SIZE].value)
  784. work_mode = MSM_VIDC_STAGE_2;
  785. } else {
  786. i_vpr_e(inst, "%s: invalid session type\n", __func__);
  787. return -EINVAL;
  788. }
  789. exit:
  790. i_vpr_h(inst, "Configuring work mode = %u low latency = %u, gop size = %u\n",
  791. work_mode, inst->capabilities->cap[LOWLATENCY_MODE].value,
  792. inst->capabilities->cap[GOP_SIZE].value);
  793. msm_vidc_update_cap_value(inst, STAGE, work_mode, __func__);
  794. return 0;
  795. }
  796. int msm_vidc_decide_work_route_iris33(struct msm_vidc_inst* inst)
  797. {
  798. u32 work_route;
  799. struct msm_vidc_core* core;
  800. if (!inst || !inst->core) {
  801. d_vpr_e("%s: invalid params\n", __func__);
  802. return -EINVAL;
  803. }
  804. core = inst->core;
  805. work_route = core->capabilities[NUM_VPP_PIPE].value;
  806. if (is_image_session(inst))
  807. goto exit;
  808. if (is_decode_session(inst)) {
  809. if (inst->capabilities->cap[CODED_FRAMES].value ==
  810. CODED_FRAMES_INTERLACE)
  811. work_route = MSM_VIDC_PIPE_1;
  812. } else if (is_encode_session(inst)) {
  813. u32 slice_mode;
  814. slice_mode = inst->capabilities->cap[SLICE_MODE].value;
  815. /*TODO Pipe=1 for legacy CBR*/
  816. if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES)
  817. work_route = MSM_VIDC_PIPE_1;
  818. } else {
  819. i_vpr_e(inst, "%s: invalid session type\n", __func__);
  820. return -EINVAL;
  821. }
  822. exit:
  823. i_vpr_h(inst, "Configuring work route = %u", work_route);
  824. msm_vidc_update_cap_value(inst, PIPE, work_route, __func__);
  825. return 0;
  826. }
  827. int msm_vidc_decide_quality_mode_iris33(struct msm_vidc_inst* inst)
  828. {
  829. struct msm_vidc_inst_capability* capability = NULL;
  830. struct msm_vidc_core *core;
  831. u32 mbpf, mbps, max_hq_mbpf, max_hq_mbps;
  832. u32 mode = MSM_VIDC_POWER_SAVE_MODE;
  833. if (!inst || !inst->capabilities) {
  834. d_vpr_e("%s: invalid params\n", __func__);
  835. return -EINVAL;
  836. }
  837. capability = inst->capabilities;
  838. if (!is_encode_session(inst))
  839. return 0;
  840. /* image or lossless or all intra runs at quality mode */
  841. if (is_image_session(inst) || capability->cap[LOSSLESS].value ||
  842. capability->cap[ALL_INTRA].value) {
  843. mode = MSM_VIDC_MAX_QUALITY_MODE;
  844. goto decision_done;
  845. }
  846. /* for lesser complexity, make LP for all resolution */
  847. if (capability->cap[COMPLEXITY].value < DEFAULT_COMPLEXITY) {
  848. mode = MSM_VIDC_POWER_SAVE_MODE;
  849. goto decision_done;
  850. }
  851. mbpf = msm_vidc_get_mbs_per_frame(inst);
  852. mbps = mbpf * msm_vidc_get_fps(inst);
  853. core = inst->core;
  854. max_hq_mbpf = core->capabilities[MAX_MBPF_HQ].value;;
  855. max_hq_mbps = core->capabilities[MAX_MBPS_HQ].value;;
  856. if (!is_realtime_session(inst)) {
  857. if (((capability->cap[COMPLEXITY].flags & CAP_FLAG_CLIENT_SET) &&
  858. (capability->cap[COMPLEXITY].value >= DEFAULT_COMPLEXITY)) ||
  859. mbpf <= max_hq_mbpf) {
  860. mode = MSM_VIDC_MAX_QUALITY_MODE;
  861. goto decision_done;
  862. }
  863. }
  864. if (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps)
  865. mode = MSM_VIDC_MAX_QUALITY_MODE;
  866. decision_done:
  867. msm_vidc_update_cap_value(inst, QUALITY_MODE, mode, __func__);
  868. return 0;
  869. }
  870. int msm_vidc_adjust_bitrate_boost_iris33(void* instance, struct v4l2_ctrl *ctrl)
  871. {
  872. struct msm_vidc_inst_capability* capability = NULL;
  873. s32 adjusted_value;
  874. struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
  875. s32 rc_type = -1;
  876. u32 width, height, frame_rate;
  877. struct v4l2_format *f;
  878. u32 max_bitrate = 0, bitrate = 0;
  879. if (!inst || !inst->capabilities) {
  880. d_vpr_e("%s: invalid params\n", __func__);
  881. return -EINVAL;
  882. }
  883. capability = inst->capabilities;
  884. adjusted_value = ctrl ? ctrl->val :
  885. capability->cap[BITRATE_BOOST].value;
  886. if (inst->bufq[OUTPUT_PORT].vb2q->streaming)
  887. return 0;
  888. if (msm_vidc_get_parent_value(inst, BITRATE_BOOST,
  889. BITRATE_MODE, &rc_type, __func__))
  890. return -EINVAL;
  891. /*
  892. * Bitrate Boost are supported only for VBR rc type.
  893. * Hence, do not adjust or set to firmware for non VBR rc's
  894. */
  895. if (rc_type != HFI_RC_VBR_CFR) {
  896. adjusted_value = 0;
  897. goto adjust;
  898. }
  899. frame_rate = inst->capabilities->cap[FRAME_RATE].value >> 16;
  900. f= &inst->fmts[OUTPUT_PORT];
  901. width = f->fmt.pix_mp.width;
  902. height = f->fmt.pix_mp.height;
  903. /*
  904. * honor client set bitrate boost
  905. * if client did not set, keep max bitrate boost upto 4k@60fps
  906. * and remove bitrate boost after 4k@60fps
  907. */
  908. if (capability->cap[BITRATE_BOOST].flags & CAP_FLAG_CLIENT_SET) {
  909. /* accept client set bitrate boost value as is */
  910. } else {
  911. if (res_is_less_than_or_equal_to(width, height, 4096, 2176) &&
  912. frame_rate <= 60)
  913. adjusted_value = MAX_BITRATE_BOOST;
  914. else
  915. adjusted_value = 0;
  916. }
  917. max_bitrate = msm_vidc_get_max_bitrate(inst);
  918. bitrate = inst->capabilities->cap[BIT_RATE].value;
  919. if (adjusted_value) {
  920. if ((bitrate + bitrate / (100 / adjusted_value)) > max_bitrate) {
  921. i_vpr_h(inst,
  922. "%s: bitrate %d is beyond max bitrate %d, remove bitrate boost\n",
  923. __func__, max_bitrate, bitrate);
  924. adjusted_value = 0;
  925. }
  926. }
  927. adjust:
  928. msm_vidc_update_cap_value(inst, BITRATE_BOOST, adjusted_value, __func__);
  929. return 0;
  930. }
  931. static struct msm_vidc_venus_ops iris33_ops = {
  932. .boot_firmware = __boot_firmware_iris33,
  933. .raise_interrupt = __raise_interrupt_iris33,
  934. .clear_interrupt = __clear_interrupt_iris33,
  935. .power_on = __power_on_iris33,
  936. .power_off = __power_off_iris33,
  937. .prepare_pc = __prepare_pc_iris33,
  938. .watchdog = __watchdog_iris33,
  939. .noc_error_info = __noc_error_info_iris33,
  940. };
  941. static struct msm_vidc_session_ops msm_session_ops = {
  942. .buffer_size = msm_buffer_size_iris33,
  943. .min_count = msm_buffer_min_count_iris33,
  944. .extra_count = msm_buffer_extra_count_iris33,
  945. .calc_freq = msm_vidc_calc_freq_iris33,
  946. .calc_bw = msm_vidc_calc_bw_iris33,
  947. .decide_work_route = msm_vidc_decide_work_route_iris33,
  948. .decide_work_mode = msm_vidc_decide_work_mode_iris33,
  949. .decide_quality_mode = msm_vidc_decide_quality_mode_iris33,
  950. };
  951. int msm_vidc_init_iris33(struct msm_vidc_core *core)
  952. {
  953. if (!core) {
  954. d_vpr_e("%s: invalid params\n", __func__);
  955. return -EINVAL;
  956. }
  957. d_vpr_h("%s()\n", __func__);
  958. core->venus_ops = &iris33_ops;
  959. core->session_ops = &msm_session_ops;
  960. core->res_ops = get_resources_ops();
  961. return 0;
  962. }
  963. int msm_vidc_deinit_iris33(struct msm_vidc_core *core)
  964. {
  965. /* do nothing */
  966. return 0;
  967. }