msm_vidc_iris2.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021,, The Linux Foundation. All rights reserved.
  4. */
  5. #include "msm_vidc_iris2.h"
  6. #include "msm_vidc_buffer_iris2.h"
  7. #include "msm_vidc_power_iris2.h"
  8. #include "venus_hfi.h"
  9. #include "msm_vidc_inst.h"
  10. #include "msm_vidc_core.h"
  11. #include "msm_vidc_driver.h"
  12. #include "msm_vidc_control.h"
  13. #include "msm_vidc_dt.h"
  14. #include "msm_vidc_internal.h"
  15. #include "msm_vidc_buffer.h"
  16. #include "msm_vidc_debug.h"
  17. #define VIDEO_ARCH_LX 1
  18. #define VCODEC_BASE_OFFS_IRIS2 0x00000000
  19. #define AON_MVP_NOC_RESET 0x0001F000
  20. #define CPU_BASE_OFFS_IRIS2 0x000A0000
  21. #define AON_BASE_OFFS 0x000E0000
  22. #define CPU_CS_BASE_OFFS_IRIS2 (CPU_BASE_OFFS_IRIS2)
  23. #define CPU_IC_BASE_OFFS_IRIS2 (CPU_BASE_OFFS_IRIS2)
  24. #define CPU_CS_A2HSOFTINTCLR_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x1C)
  25. #define CPU_CS_VCICMD_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x20)
  26. #define CPU_CS_VCICMDARG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x24)
  27. #define CPU_CS_VCICMDARG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x28)
  28. #define CPU_CS_VCICMDARG2_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x2C)
  29. #define CPU_CS_VCICMDARG3_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x30)
  30. #define CPU_CS_VMIMSG_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x34)
  31. #define CPU_CS_VMIMSGAG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x38)
  32. #define CPU_CS_VMIMSGAG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x3C)
  33. #define CPU_CS_SCIACMD_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x48)
  34. #define CPU_CS_H2XSOFTINTEN_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x148)
  35. /* HFI_CTRL_STATUS */
  36. #define CPU_CS_SCIACMDARG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x4C)
  37. #define CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS2 0xfe
  38. #define CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS2 0x100
  39. #define CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS2 0x40000000
  40. /* HFI_QTBL_INFO */
  41. #define CPU_CS_SCIACMDARG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x50)
  42. /* HFI_QTBL_ADDR */
  43. #define CPU_CS_SCIACMDARG2_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x54)
  44. /* HFI_VERSION_INFO */
  45. #define CPU_CS_SCIACMDARG3_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x58)
  46. /* SFR_ADDR */
  47. #define CPU_CS_SCIBCMD_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x5C)
  48. /* MMAP_ADDR */
  49. #define CPU_CS_SCIBCMDARG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x60)
  50. /* UC_REGION_ADDR */
  51. #define CPU_CS_SCIBARG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x64)
  52. /* UC_REGION_ADDR */
  53. #define CPU_CS_SCIBARG2_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x68)
  54. #define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS_IRIS2 + 0x160)
  55. #define CPU_CS_AHB_BRIDGE_SYNC_RESET_STATUS (CPU_CS_BASE_OFFS_IRIS2 + 0x164)
  56. /* FAL10 Feature Control */
  57. #define CPU_CS_X2RPMh_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x168)
  58. #define CPU_CS_X2RPMh_MASK0_BMSK_IRIS2 0x1
  59. #define CPU_CS_X2RPMh_MASK0_SHFT_IRIS2 0x0
  60. #define CPU_CS_X2RPMh_MASK1_BMSK_IRIS2 0x2
  61. #define CPU_CS_X2RPMh_MASK1_SHFT_IRIS2 0x1
  62. #define CPU_CS_X2RPMh_SWOVERRIDE_BMSK_IRIS2 0x4
  63. #define CPU_CS_X2RPMh_SWOVERRIDE_SHFT_IRIS2 0x3
  64. #define CPU_IC_SOFTINT_IRIS2 (CPU_IC_BASE_OFFS_IRIS2 + 0x150)
  65. #define CPU_IC_SOFTINT_H2A_SHFT_IRIS2 0x0
  66. /*
  67. * --------------------------------------------------------------------------
  68. * MODULE: AON_MVP_NOC_RESET_REGISTERS
  69. * --------------------------------------------------------------------------
  70. */
  71. #define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
  72. #define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
  73. /*
  74. * --------------------------------------------------------------------------
  75. * MODULE: wrapper
  76. * --------------------------------------------------------------------------
  77. */
  78. #define WRAPPER_BASE_OFFS_IRIS2 0x000B0000
  79. #define WRAPPER_INTR_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x0C)
  80. #define WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2 0x8
  81. #define WRAPPER_INTR_STATUS_A2H_BMSK_IRIS2 0x4
  82. #define WRAPPER_INTR_MASK_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x10)
  83. #define WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS2 0x8
  84. #define WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS2 0x4
  85. #define WRAPPER_CPU_CLOCK_CONFIG_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2000)
  86. #define WRAPPER_CPU_CGC_DIS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2010)
  87. #define WRAPPER_CPU_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2014)
  88. #define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x54)
  89. #define WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x58)
  90. #define WRAPPER_CORE_CLOCK_CONFIG_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x88)
  91. /*
  92. * --------------------------------------------------------------------------
  93. * MODULE: tz_wrapper
  94. * --------------------------------------------------------------------------
  95. */
  96. #define WRAPPER_TZ_BASE_OFFS 0x000C0000
  97. #define WRAPPER_TZ_CPU_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS)
  98. #define WRAPPER_TZ_CPU_STATUS (WRAPPER_TZ_BASE_OFFS + 0x10)
  99. #define CTRL_INIT_IRIS2 CPU_CS_SCIACMD_IRIS2
  100. #define CTRL_STATUS_IRIS2 CPU_CS_SCIACMDARG0_IRIS2
  101. #define CTRL_ERROR_STATUS__M_IRIS2 \
  102. CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS2
  103. #define CTRL_INIT_IDLE_MSG_BMSK_IRIS2 \
  104. CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS2
  105. #define CTRL_STATUS_PC_READY_IRIS2 \
  106. CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS2
  107. #define QTBL_INFO_IRIS2 CPU_CS_SCIACMDARG1_IRIS2
  108. #define QTBL_ADDR_IRIS2 CPU_CS_SCIACMDARG2_IRIS2
  109. #define VERSION_INFO_IRIS2 CPU_CS_SCIACMDARG3_IRIS2
  110. #define SFR_ADDR_IRIS2 CPU_CS_SCIBCMD_IRIS2
  111. #define MMAP_ADDR_IRIS2 CPU_CS_SCIBCMDARG0_IRIS2
  112. #define UC_REGION_ADDR_IRIS2 CPU_CS_SCIBARG1_IRIS2
  113. #define UC_REGION_SIZE_IRIS2 CPU_CS_SCIBARG2_IRIS2
  114. #define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
  115. #define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
  116. /*
  117. * --------------------------------------------------------------------------
  118. * MODULE: VCODEC_SS registers
  119. * --------------------------------------------------------------------------
  120. */
  121. #define VCODEC_SS_IDLE_STATUSn (VCODEC_BASE_OFFS_IRIS2 + 0x70)
  122. /*
  123. * --------------------------------------------------------------------------
  124. * MODULE: vcodec noc error log registers (iris2)
  125. * --------------------------------------------------------------------------
  126. */
  127. #define VCODEC_NOC_VIDEO_A_NOC_BASE_OFFS 0x00010000
  128. #define VCODEC_NOC_ERL_MAIN_SWID_LOW 0x00011200
  129. #define VCODEC_NOC_ERL_MAIN_SWID_HIGH 0x00011204
  130. #define VCODEC_NOC_ERL_MAIN_MAINCTL_LOW 0x00011208
  131. #define VCODEC_NOC_ERL_MAIN_ERRVLD_LOW 0x00011210
  132. #define VCODEC_NOC_ERL_MAIN_ERRCLR_LOW 0x00011218
  133. #define VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW 0x00011220
  134. #define VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH 0x00011224
  135. #define VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW 0x00011228
  136. #define VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH 0x0001122C
  137. #define VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW 0x00011230
  138. #define VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH 0x00011234
  139. #define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238
  140. #define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C
  141. static int __disable_unprepare_clock_iris2(struct msm_vidc_core *core,
  142. const char *clk_name)
  143. {
  144. int rc = 0;
  145. struct clock_info *cl;
  146. bool found;
  147. if (!core || !clk_name) {
  148. d_vpr_e("%s: invalid params\n", __func__);
  149. return -EINVAL;
  150. }
  151. found = false;
  152. venus_hfi_for_each_clock(core, cl) {
  153. if (!cl->clk) {
  154. d_vpr_e("%s: invalid clock %s\n", __func__, cl->name);
  155. return -EINVAL;
  156. }
  157. if (strcmp(cl->name, clk_name))
  158. continue;
  159. found = true;
  160. clk_disable_unprepare(cl->clk);
  161. cl->prev = 0;
  162. d_vpr_h("%s: clock %s disable unprepared\n", __func__, cl->name);
  163. break;
  164. }
  165. if (!found) {
  166. d_vpr_e("%s: clock %s not found\n", __func__, clk_name);
  167. return -EINVAL;
  168. }
  169. return rc;
  170. }
  171. static int __prepare_enable_clock_iris2(struct msm_vidc_core *core,
  172. const char *clk_name)
  173. {
  174. int rc = 0;
  175. struct clock_info *cl;
  176. bool found;
  177. if (!core || !clk_name) {
  178. d_vpr_e("%s: invalid params\n", __func__);
  179. return -EINVAL;
  180. }
  181. found = false;
  182. venus_hfi_for_each_clock(core, cl) {
  183. if (!cl->clk) {
  184. d_vpr_e("%s: invalid clock\n", __func__);
  185. return -EINVAL;
  186. }
  187. if (strcmp(cl->name, clk_name))
  188. continue;
  189. found = true;
  190. /*
  191. * For the clocks we control, set the rate prior to preparing
  192. * them. Since we don't really have a load at this point, scale
  193. * it to the lowest frequency possible
  194. */
  195. if (cl->has_scaling)
  196. __set_clk_rate(core, cl, clk_round_rate(cl->clk, 0));
  197. rc = clk_prepare_enable(cl->clk);
  198. if (rc) {
  199. d_vpr_e("%s: failed to enable clock %s\n",
  200. __func__, cl->name);
  201. return rc;
  202. }
  203. if (!__clk_is_enabled(cl->clk)) {
  204. d_vpr_e("%s: clock %s not enabled\n",
  205. __func__, cl->name);
  206. clk_disable_unprepare(cl->clk);
  207. return -EINVAL;
  208. }
  209. d_vpr_h("%s: clock %s prepare enabled\n", __func__, cl->name);
  210. break;
  211. }
  212. if (!found) {
  213. d_vpr_e("%s: clock %s not found\n", __func__, clk_name);
  214. return -EINVAL;
  215. }
  216. return rc;
  217. }
  218. static int __disable_regulator_iris2(struct msm_vidc_core *core,
  219. const char *reg_name)
  220. {
  221. int rc = 0;
  222. struct regulator_info *rinfo;
  223. bool found;
  224. if (!core || !reg_name) {
  225. d_vpr_e("%s: invalid params\n", __func__);
  226. return -EINVAL;
  227. }
  228. found = false;
  229. venus_hfi_for_each_regulator(core, rinfo) {
  230. if (!rinfo->regulator) {
  231. d_vpr_e("%s: invalid regulator %s\n",
  232. __func__, rinfo->name);
  233. return -EINVAL;
  234. }
  235. if (strcmp(rinfo->name, reg_name))
  236. continue;
  237. found = true;
  238. rc = __acquire_regulator(core, rinfo);
  239. if (rc) {
  240. d_vpr_e("%s: failed to acquire %s, rc = %d\n",
  241. rinfo->name, rc);
  242. /* Bring attention to this issue */
  243. WARN_ON(true);
  244. return rc;
  245. }
  246. core->handoff_done = false;
  247. rc = regulator_disable(rinfo->regulator);
  248. if (rc) {
  249. d_vpr_e("%s: failed to disable %s, rc = %d\n",
  250. rinfo->name, rc);
  251. return rc;
  252. }
  253. d_vpr_h("%s: disabled regulator %s\n", __func__, rinfo->name);
  254. break;
  255. }
  256. if (!found) {
  257. d_vpr_e("%s: regulator %s not found\n", __func__, reg_name);
  258. return -EINVAL;
  259. }
  260. return rc;
  261. }
  262. static int __enable_regulator_iris2(struct msm_vidc_core *core,
  263. const char *reg_name)
  264. {
  265. int rc = 0;
  266. struct regulator_info *rinfo;
  267. bool found;
  268. if (!core || !reg_name) {
  269. d_vpr_e("%s: invalid params\n", __func__);
  270. return -EINVAL;
  271. }
  272. found = false;
  273. venus_hfi_for_each_regulator(core, rinfo) {
  274. if (!rinfo->regulator) {
  275. d_vpr_e("%s: invalid regulator %s\n",
  276. __func__, rinfo->name);
  277. return -EINVAL;
  278. }
  279. if (strcmp(rinfo->name, reg_name))
  280. continue;
  281. found = true;
  282. rc = regulator_enable(rinfo->regulator);
  283. if (rc) {
  284. d_vpr_e("%s: failed to enable %s, rc = %d\n",
  285. __func__, rinfo->name, rc);
  286. return rc;
  287. }
  288. if (!regulator_is_enabled(rinfo->regulator)) {
  289. d_vpr_e("%s: regulator %s not enabled\n",
  290. __func__, rinfo->name);
  291. regulator_disable(rinfo->regulator);
  292. return -EINVAL;
  293. }
  294. d_vpr_h("%s: enabled regulator %s\n", __func__, rinfo->name);
  295. break;
  296. }
  297. if (!found) {
  298. d_vpr_e("%s: regulator %s not found\n", __func__, reg_name);
  299. return -EINVAL;
  300. }
  301. return rc;
  302. }
  303. static int __interrupt_init_iris2(struct msm_vidc_core *vidc_core)
  304. {
  305. struct msm_vidc_core *core = vidc_core;
  306. u32 mask_val = 0;
  307. int rc = 0;
  308. if (!core) {
  309. d_vpr_e("%s: invalid params\n", __func__);
  310. return -EINVAL;
  311. }
  312. /* All interrupts should be disabled initially 0x1F6 : Reset value */
  313. mask_val = __read_register(core, WRAPPER_INTR_MASK_IRIS2);
  314. /* Write 0 to unmask CPU and WD interrupts */
  315. mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS2|
  316. WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS2);
  317. rc = __write_register(core, WRAPPER_INTR_MASK_IRIS2, mask_val);
  318. if (rc)
  319. return rc;
  320. return 0;
  321. }
  322. static int __setup_ucregion_memory_map_iris2(struct msm_vidc_core *vidc_core)
  323. {
  324. struct msm_vidc_core *core = vidc_core;
  325. u32 value;
  326. int rc = 0;
  327. if (!core) {
  328. d_vpr_e("%s: invalid params\n", __func__);
  329. return -EINVAL;
  330. }
  331. value = (u32)core->iface_q_table.align_device_addr;
  332. rc = __write_register(core, UC_REGION_ADDR_IRIS2, value);
  333. if (rc)
  334. return rc;
  335. value = SHARED_QSIZE;
  336. rc = __write_register(core, UC_REGION_SIZE_IRIS2, value);
  337. if (rc)
  338. return rc;
  339. value = (u32)core->iface_q_table.align_device_addr;
  340. rc = __write_register(core, QTBL_ADDR_IRIS2, value);
  341. if (rc)
  342. return rc;
  343. rc = __write_register(core, QTBL_INFO_IRIS2, 0x01);
  344. if (rc)
  345. return rc;
  346. /* update queues vaddr for debug purpose */
  347. value = (u32)((u64)core->iface_q_table.align_virtual_addr);
  348. rc = __write_register(core, CPU_CS_VCICMDARG0_IRIS2, value);
  349. if (rc)
  350. return rc;
  351. value = (u32)((u64)core->iface_q_table.align_virtual_addr >> 32);
  352. rc = __write_register(core, CPU_CS_VCICMDARG1_IRIS2, value);
  353. if (rc)
  354. return rc;
  355. if (core->sfr.align_device_addr) {
  356. value = (u32)core->sfr.align_device_addr + VIDEO_ARCH_LX;
  357. rc = __write_register(core, SFR_ADDR_IRIS2, value);
  358. if (rc)
  359. return rc;
  360. }
  361. return 0;
  362. }
  363. static int __power_off_iris2_hardware(struct msm_vidc_core *core)
  364. {
  365. int rc = 0, i;
  366. u32 value = 0;
  367. if (core->hw_power_control) {
  368. d_vpr_h("%s: hardware power control enabled\n", __func__);
  369. goto disable_power;
  370. }
  371. /*
  372. * check to make sure core clock branch enabled else
  373. * we cannot read vcodec top idle register
  374. */
  375. value = __read_register(core, WRAPPER_CORE_CLOCK_CONFIG_IRIS2);
  376. if (value) {
  377. d_vpr_h(
  378. "%s: core clock config not enabled, enabling it to read vcodec registers\n",
  379. __func__);
  380. rc = __write_register(core, WRAPPER_CORE_CLOCK_CONFIG_IRIS2, 0);
  381. if (rc)
  382. return rc;
  383. }
  384. /*
  385. * add MNoC idle check before collapsing MVS0 per HPG update
  386. * poll for NoC DMA idle -> HPG 6.1.1
  387. */
  388. for (i = 0; i < core->capabilities[NUM_VPP_PIPE].value; i++) {
  389. rc = __read_register_with_poll_timeout(core, VCODEC_SS_IDLE_STATUSn + 4*i,
  390. 0x400000, 0x400000, 2000, 20000);
  391. if (rc)
  392. d_vpr_h("%s: VCODEC_SS_IDLE_STATUSn (%d) is not idle (%#x)\n",
  393. __func__, i, value);
  394. }
  395. /* Apply partial reset on MSF interface and wait for ACK */
  396. rc = __write_register(core, AON_WRAPPER_MVP_NOC_RESET_REQ, 0x3);
  397. if (rc)
  398. return rc;
  399. rc = __read_register_with_poll_timeout(core, AON_WRAPPER_MVP_NOC_RESET_ACK,
  400. 0x3, 0x3, 200, 2000);
  401. if (rc)
  402. d_vpr_h("%s: AON_WRAPPER_MVP_NOC_RESET assert failed\n", __func__);
  403. /* De-assert partial reset on MSF interface and wait for ACK */
  404. rc = __write_register(core, AON_WRAPPER_MVP_NOC_RESET_REQ, 0x0);
  405. if (rc)
  406. return rc;
  407. rc = __read_register_with_poll_timeout(core, AON_WRAPPER_MVP_NOC_RESET_ACK,
  408. 0x3, 0x0, 200, 2000);
  409. if (rc)
  410. d_vpr_h("%s: AON_WRAPPER_MVP_NOC_RESET de-assert failed\n", __func__);
  411. /*
  412. * Reset both sides of 2 ahb2ahb_bridges (TZ and non-TZ)
  413. * do we need to check status register here?
  414. */
  415. rc = __write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x3);
  416. if (rc)
  417. return rc;
  418. rc = __write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x2);
  419. if (rc)
  420. return rc;
  421. rc = __write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x0);
  422. if (rc)
  423. return rc;
  424. disable_power:
  425. /* power down process */
  426. rc = __disable_regulator_iris2(core, "vcodec");
  427. if (rc) {
  428. d_vpr_e("%s: disable regulator vcodec failed\n", __func__);
  429. rc = 0;
  430. }
  431. rc = __disable_unprepare_clock_iris2(core, "vcodec_clk");
  432. if (rc) {
  433. d_vpr_e("%s: disable unprepare vcodec_clk failed\n", __func__);
  434. rc = 0;
  435. }
  436. return rc;
  437. }
  438. static int __power_off_iris2_controller(struct msm_vidc_core *core)
  439. {
  440. int rc = 0;
  441. /*
  442. * mask fal10_veto QLPAC error since fal10_veto can go 1
  443. * when pwwait == 0 and clamped to 0 -> HPG 6.1.2
  444. */
  445. rc = __write_register(core, CPU_CS_X2RPMh_IRIS2, 0x3);
  446. if (rc)
  447. return rc;
  448. /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
  449. rc = __write_register_masked(core, AON_WRAPPER_MVP_NOC_LPI_CONTROL,
  450. 0x1, BIT(0));
  451. if (rc)
  452. return rc;
  453. rc = __read_register_with_poll_timeout(core, AON_WRAPPER_MVP_NOC_LPI_STATUS,
  454. 0x1, 0x1, 200, 2000);
  455. if (rc)
  456. d_vpr_h("%s: AON_WRAPPER_MVP_NOC_LPI_CONTROL failed\n", __func__);
  457. /* Set Debug bridge Low power */
  458. rc = __write_register(core, WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x7);
  459. if (rc)
  460. return rc;
  461. rc = __read_register_with_poll_timeout(core, WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2,
  462. 0x7, 0x7, 200, 2000);
  463. if (rc)
  464. d_vpr_h("%s: debug bridge low power failed\n", __func__);
  465. /* Debug bridge LPI release */
  466. rc = __write_register(core, WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x0);
  467. if (rc)
  468. return rc;
  469. rc = __read_register_with_poll_timeout(core, WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2,
  470. 0xffffffff, 0x0, 200, 2000);
  471. if (rc)
  472. d_vpr_h("%s: debug bridge release failed\n", __func__);
  473. /* power down process */
  474. rc = __disable_regulator_iris2(core, "iris-ctl");
  475. if (rc) {
  476. d_vpr_e("%s: disable regulator iris-ctl failed\n", __func__);
  477. rc = 0;
  478. }
  479. /* Disable GCC_VIDEO_AXI0_CLK clock */
  480. rc = __disable_unprepare_clock_iris2(core, "gcc_video_axi0");
  481. if (rc) {
  482. d_vpr_e("%s: disable unprepare gcc_video_axi0 failed\n", __func__);
  483. rc = 0;
  484. }
  485. /* Turn off MVP MVS0C core clock */
  486. rc = __disable_unprepare_clock_iris2(core, "core_clk");
  487. if (rc) {
  488. d_vpr_e("%s: disable unprepare core_clk failed\n", __func__);
  489. rc = 0;
  490. }
  491. return rc;
  492. }
  493. static int __power_off_iris2(struct msm_vidc_core *core)
  494. {
  495. int rc = 0;
  496. if (!core || !core->capabilities) {
  497. d_vpr_e("%s: invalid params\n", __func__);
  498. return -EINVAL;
  499. }
  500. if (!core->power_enabled)
  501. return 0;
  502. if (__power_off_iris2_hardware(core))
  503. d_vpr_e("%s: failed to power off hardware\n", __func__);
  504. if (__power_off_iris2_controller(core))
  505. d_vpr_e("%s: failed to power off controller\n", __func__);
  506. if (__unvote_buses(core))
  507. d_vpr_e("%s: failed to unvote buses\n", __func__);
  508. if (!(core->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2))
  509. disable_irq_nosync(core->dt->irq);
  510. core->intr_status = 0;
  511. core->power_enabled = false;
  512. return rc;
  513. }
  514. static int __power_on_iris2_controller(struct msm_vidc_core *core)
  515. {
  516. int rc = 0;
  517. rc = __enable_regulator_iris2(core, "iris-ctl");
  518. if (rc)
  519. goto fail_regulator;
  520. rc = call_venus_op(core, reset_ahb2axi_bridge, core);
  521. if (rc)
  522. goto fail_reset_ahb2axi;
  523. rc = __prepare_enable_clock_iris2(core, "gcc_video_axi0");
  524. if (rc)
  525. goto fail_clk_axi;
  526. rc = __prepare_enable_clock_iris2(core, "core_clk");
  527. if (rc)
  528. goto fail_clk_controller;
  529. return 0;
  530. fail_clk_controller:
  531. __disable_unprepare_clock_iris2(core, "gcc_video_axi0");
  532. fail_clk_axi:
  533. fail_reset_ahb2axi:
  534. __disable_regulator_iris2(core, "iris-ctl");
  535. fail_regulator:
  536. return rc;
  537. }
  538. static int __power_on_iris2_hardware(struct msm_vidc_core *core)
  539. {
  540. int rc = 0;
  541. rc = __enable_regulator_iris2(core, "vcodec");
  542. if (rc)
  543. goto fail_regulator;
  544. rc = __prepare_enable_clock_iris2(core, "vcodec_clk");
  545. if (rc)
  546. goto fail_clk_controller;
  547. return 0;
  548. fail_clk_controller:
  549. __disable_regulator_iris2(core, "vcodec");
  550. fail_regulator:
  551. return rc;
  552. }
  553. static int __power_on_iris2(struct msm_vidc_core *core)
  554. {
  555. int rc = 0;
  556. if (core->power_enabled)
  557. return 0;
  558. /* Vote for all hardware resources */
  559. rc = __vote_buses(core, INT_MAX, INT_MAX);
  560. if (rc) {
  561. d_vpr_e("%s: failed to vote buses, rc %d\n", __func__, rc);
  562. goto fail_vote_buses;
  563. }
  564. rc = __power_on_iris2_controller(core);
  565. if (rc) {
  566. d_vpr_e("%s: failed to power on iris2 controller\n", __func__);
  567. goto fail_power_on_controller;
  568. }
  569. rc = __power_on_iris2_hardware(core);
  570. if (rc) {
  571. d_vpr_e("%s: failed to power on iris2 hardware\n", __func__);
  572. goto fail_power_on_hardware;
  573. }
  574. /* video controller and hardware powered on successfully */
  575. core->power_enabled = true;
  576. rc = __scale_clocks(core);
  577. if (rc) {
  578. d_vpr_e("%s: failed to scale clocks\n", __func__);
  579. rc = 0;
  580. }
  581. /*
  582. * Re-program all of the registers that get reset as a result of
  583. * regulator_disable() and _enable()
  584. */
  585. __set_registers(core);
  586. call_venus_op(core, interrupt_init, core);
  587. core->intr_status = 0;
  588. enable_irq(core->dt->irq);
  589. return rc;
  590. fail_power_on_hardware:
  591. __power_off_iris2_controller(core);
  592. fail_power_on_controller:
  593. __unvote_buses(core);
  594. fail_vote_buses:
  595. core->power_enabled = false;
  596. return rc;
  597. }
  598. static int __prepare_pc_iris2(struct msm_vidc_core *vidc_core)
  599. {
  600. int rc = 0;
  601. u32 wfi_status = 0, idle_status = 0, pc_ready = 0;
  602. u32 ctrl_status = 0;
  603. struct msm_vidc_core *core = vidc_core;
  604. if (!core) {
  605. d_vpr_e("%s: invalid params\n", __func__);
  606. return -EINVAL;
  607. }
  608. ctrl_status = __read_register(core, CTRL_STATUS_IRIS2);
  609. pc_ready = ctrl_status & CTRL_STATUS_PC_READY_IRIS2;
  610. idle_status = ctrl_status & BIT(30);
  611. if (pc_ready) {
  612. d_vpr_h("Already in pc_ready state\n");
  613. return 0;
  614. }
  615. wfi_status = BIT(0) & __read_register(core, WRAPPER_TZ_CPU_STATUS);
  616. if (!wfi_status || !idle_status) {
  617. d_vpr_e("Skipping PC, wfi status not set\n");
  618. goto skip_power_off;
  619. }
  620. rc = __prepare_pc(core);
  621. if (rc) {
  622. d_vpr_e("Failed __prepare_pc %d\n", rc);
  623. goto skip_power_off;
  624. }
  625. rc = __read_register_with_poll_timeout(core, CTRL_STATUS_IRIS2,
  626. CTRL_STATUS_PC_READY_IRIS2, CTRL_STATUS_PC_READY_IRIS2, 250, 2500);
  627. if (rc) {
  628. d_vpr_e("%s: Skip PC. Ctrl status not set\n", __func__);
  629. goto skip_power_off;
  630. }
  631. rc = __read_register_with_poll_timeout(core, WRAPPER_TZ_CPU_STATUS,
  632. BIT(0), 0x1, 250, 2500);
  633. if (rc) {
  634. d_vpr_e("%s: Skip PC. Wfi status not set\n", __func__);
  635. goto skip_power_off;
  636. }
  637. return rc;
  638. skip_power_off:
  639. wfi_status = BIT(0) & __read_register(core, WRAPPER_TZ_CPU_STATUS);
  640. ctrl_status = __read_register(core, CTRL_STATUS_IRIS2);
  641. d_vpr_e("Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n",
  642. wfi_status, idle_status, pc_ready, ctrl_status);
  643. return -EAGAIN;
  644. }
  645. static int __raise_interrupt_iris2(struct msm_vidc_core *vidc_core)
  646. {
  647. struct msm_vidc_core *core = vidc_core;
  648. int rc = 0;
  649. if (!core) {
  650. d_vpr_e("%s: invalid params\n", __func__);
  651. return -EINVAL;
  652. }
  653. rc = __write_register(core, CPU_IC_SOFTINT_IRIS2, 1 << CPU_IC_SOFTINT_H2A_SHFT_IRIS2);
  654. if (rc)
  655. return rc;
  656. return 0;
  657. }
  658. static int __watchdog_iris2(struct msm_vidc_core *vidc_core, u32 intr_status)
  659. {
  660. int rc = 0;
  661. struct msm_vidc_core *core = vidc_core;
  662. if (!core) {
  663. d_vpr_e("%s: invalid params\n", __func__);
  664. return -EINVAL;
  665. }
  666. if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2) {
  667. d_vpr_e("%s: received watchdog interrupt\n", __func__);
  668. rc = 1;
  669. }
  670. return rc;
  671. }
  672. static int __noc_error_info_iris2(struct msm_vidc_core *vidc_core)
  673. {
  674. struct msm_vidc_core *core = vidc_core;
  675. if (!core) {
  676. d_vpr_e("%s: invalid params\n", __func__);
  677. return -EINVAL;
  678. }
  679. /*
  680. * we are not supposed to access vcodec subsystem registers
  681. * unless vcodec core clock WRAPPER_CORE_CLOCK_CONFIG_IRIS2 is enabled.
  682. * core clock might have been disabled by video firmware as part of
  683. * inter frame power collapse (power plane control feature).
  684. */
  685. /*
  686. val = __read_register(core, VCODEC_NOC_ERL_MAIN_SWID_LOW);
  687. d_vpr_e("VCODEC_NOC_ERL_MAIN_SWID_LOW: %#x\n", val);
  688. val = __read_register(core, VCODEC_NOC_ERL_MAIN_SWID_HIGH);
  689. d_vpr_e("VCODEC_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val);
  690. val = __read_register(core, VCODEC_NOC_ERL_MAIN_MAINCTL_LOW);
  691. d_vpr_e("VCODEC_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val);
  692. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW);
  693. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val);
  694. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRCLR_LOW);
  695. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val);
  696. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW);
  697. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val);
  698. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH);
  699. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val);
  700. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW);
  701. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val);
  702. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH);
  703. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val);
  704. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW);
  705. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val);
  706. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH);
  707. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val);
  708. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW);
  709. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val);
  710. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH);
  711. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val);
  712. */
  713. return 0;
  714. }
  715. static int __clear_interrupt_iris2(struct msm_vidc_core *vidc_core)
  716. {
  717. struct msm_vidc_core *core = vidc_core;
  718. u32 intr_status = 0, mask = 0;
  719. int rc = 0;
  720. if (!core) {
  721. d_vpr_e("%s: NULL core\n", __func__);
  722. return 0;
  723. }
  724. intr_status = __read_register(core, WRAPPER_INTR_STATUS_IRIS2);
  725. mask = (WRAPPER_INTR_STATUS_A2H_BMSK_IRIS2|
  726. WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2|
  727. CTRL_INIT_IDLE_MSG_BMSK_IRIS2);
  728. if (intr_status & mask) {
  729. core->intr_status |= intr_status;
  730. core->reg_count++;
  731. d_vpr_l("INTERRUPT: times: %d interrupt_status: %d\n",
  732. core->reg_count, intr_status);
  733. } else {
  734. core->spur_count++;
  735. }
  736. rc = __write_register(core, CPU_CS_A2HSOFTINTCLR_IRIS2, 1);
  737. if (rc)
  738. return rc;
  739. return 0;
  740. }
  741. static int __boot_firmware_iris2(struct msm_vidc_core *vidc_core)
  742. {
  743. int rc = 0;
  744. u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000;
  745. struct msm_vidc_core *core = vidc_core;
  746. if (!core) {
  747. d_vpr_e("%s: NULL core\n", __func__);
  748. return 0;
  749. }
  750. ctrl_init_val = BIT(0);
  751. rc = __write_register(core, CTRL_INIT_IRIS2, ctrl_init_val);
  752. if (rc)
  753. return rc;
  754. while (!ctrl_status && count < max_tries) {
  755. ctrl_status = __read_register(core, CTRL_STATUS_IRIS2);
  756. if ((ctrl_status & CTRL_ERROR_STATUS__M_IRIS2) == 0x4) {
  757. d_vpr_e("invalid setting for UC_REGION\n");
  758. break;
  759. }
  760. usleep_range(50, 100);
  761. count++;
  762. }
  763. if (count >= max_tries) {
  764. d_vpr_e("Error booting up vidc firmware\n");
  765. return -ETIME;
  766. }
  767. /* Enable interrupt before sending commands to venus */
  768. rc = __write_register(core, CPU_CS_H2XSOFTINTEN_IRIS2, 0x1);
  769. if (rc)
  770. return rc;
  771. rc = __write_register(core, CPU_CS_X2RPMh_IRIS2, 0x0);
  772. if (rc)
  773. return rc;
  774. return rc;
  775. }
  776. int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst* inst)
  777. {
  778. u32 work_mode;
  779. struct v4l2_format *inp_f;
  780. u32 width, height;
  781. bool res_ok = false;
  782. if (!inst || !inst->capabilities) {
  783. d_vpr_e("%s: invalid params\n", __func__);
  784. return -EINVAL;
  785. }
  786. work_mode = MSM_VIDC_STAGE_2;
  787. inp_f = &inst->fmts[INPUT_PORT];
  788. if (is_image_decode_session(inst))
  789. work_mode = MSM_VIDC_STAGE_1;
  790. if (is_image_session(inst))
  791. goto exit;
  792. if (is_decode_session(inst)) {
  793. height = inp_f->fmt.pix_mp.height;
  794. width = inp_f->fmt.pix_mp.width;
  795. res_ok = res_is_less_than(width, height, 1280, 720);
  796. if (inst->capabilities->cap[CODED_FRAMES].value ==
  797. CODED_FRAMES_INTERLACE ||
  798. inst->capabilities->cap[LOWLATENCY_MODE].value ||
  799. res_ok) {
  800. work_mode = MSM_VIDC_STAGE_1;
  801. }
  802. } else if (is_encode_session(inst)) {
  803. height = inst->crop.height;
  804. width = inst->crop.width;
  805. res_ok = !res_is_greater_than(width, height, 4096, 2160);
  806. if (res_ok &&
  807. (inst->capabilities->cap[LOWLATENCY_MODE].value)) {
  808. work_mode = MSM_VIDC_STAGE_1;
  809. }
  810. if (inst->capabilities->cap[LOSSLESS].value)
  811. work_mode = MSM_VIDC_STAGE_2;
  812. if (!inst->capabilities->cap[GOP_SIZE].value)
  813. work_mode = MSM_VIDC_STAGE_2;
  814. } else {
  815. i_vpr_e(inst, "%s: invalid session type\n", __func__);
  816. return -EINVAL;
  817. }
  818. exit:
  819. i_vpr_h(inst, "Configuring work mode = %u low latency = %u, gop size = %u\n",
  820. work_mode, inst->capabilities->cap[LOWLATENCY_MODE].value,
  821. inst->capabilities->cap[GOP_SIZE].value);
  822. msm_vidc_update_cap_value(inst, STAGE, work_mode, __func__);
  823. return 0;
  824. }
  825. int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst* inst)
  826. {
  827. u32 work_route;
  828. struct msm_vidc_core* core;
  829. if (!inst || !inst->core) {
  830. d_vpr_e("%s: invalid params\n", __func__);
  831. return -EINVAL;
  832. }
  833. core = inst->core;
  834. work_route = core->capabilities[NUM_VPP_PIPE].value;
  835. if (is_image_session(inst))
  836. goto exit;
  837. if (is_decode_session(inst)) {
  838. if (inst->capabilities->cap[CODED_FRAMES].value ==
  839. CODED_FRAMES_INTERLACE)
  840. work_route = MSM_VIDC_PIPE_1;
  841. } else if (is_encode_session(inst)) {
  842. u32 slice_mode, width, height;
  843. struct v4l2_format* f;
  844. f = &inst->fmts[INPUT_PORT];
  845. height = f->fmt.pix_mp.height;
  846. width = f->fmt.pix_mp.width;
  847. slice_mode = inst->capabilities->cap[SLICE_MODE].value;
  848. /*TODO Pipe=1 for legacy CBR*/
  849. if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES)
  850. work_route = MSM_VIDC_PIPE_1;
  851. } else {
  852. i_vpr_e(inst, "%s: invalid session type\n", __func__);
  853. return -EINVAL;
  854. }
  855. exit:
  856. i_vpr_h(inst, "Configuring work route = %u", work_route);
  857. msm_vidc_update_cap_value(inst, PIPE, work_route, __func__);
  858. return 0;
  859. }
  860. int msm_vidc_decide_quality_mode_iris2(struct msm_vidc_inst* inst)
  861. {
  862. struct msm_vidc_inst_capability* capability = NULL;
  863. struct msm_vidc_core *core;
  864. u32 mbpf, mbps, max_hq_mbpf, max_hq_mbps;
  865. u32 mode = MSM_VIDC_POWER_SAVE_MODE;
  866. if (!inst || !inst->capabilities) {
  867. d_vpr_e("%s: invalid params\n", __func__);
  868. return -EINVAL;
  869. }
  870. capability = inst->capabilities;
  871. if (!is_encode_session(inst))
  872. return 0;
  873. /* image session always runs at quality mode */
  874. if (is_image_session(inst)) {
  875. mode = MSM_VIDC_MAX_QUALITY_MODE;
  876. goto exit;
  877. }
  878. mbpf = msm_vidc_get_mbs_per_frame(inst);
  879. mbps = mbpf * msm_vidc_get_fps(inst);
  880. core = inst->core;
  881. max_hq_mbpf = core->capabilities[MAX_MBPF_HQ].value;;
  882. max_hq_mbps = core->capabilities[MAX_MBPS_HQ].value;;
  883. /* NRT session to have max quality unless client configures least complexity */
  884. if (!is_realtime_session(inst) && mbpf <= max_hq_mbpf) {
  885. mode = MSM_VIDC_MAX_QUALITY_MODE;
  886. if (!capability->cap[COMPLEXITY].value)
  887. mode = MSM_VIDC_POWER_SAVE_MODE;
  888. goto exit;
  889. }
  890. /* Power saving always disabled for CQ and LOSSLESS RC modes. */
  891. if (capability->cap[LOSSLESS].value ||
  892. (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps))
  893. mode = MSM_VIDC_MAX_QUALITY_MODE;
  894. exit:
  895. msm_vidc_update_cap_value(inst, QUALITY_MODE, mode, __func__);
  896. return 0;
  897. }
  898. static struct msm_vidc_venus_ops iris2_ops = {
  899. .boot_firmware = __boot_firmware_iris2,
  900. .interrupt_init = __interrupt_init_iris2,
  901. .raise_interrupt = __raise_interrupt_iris2,
  902. .clear_interrupt = __clear_interrupt_iris2,
  903. .setup_ucregion_memmap = __setup_ucregion_memory_map_iris2,
  904. .clock_config_on_enable = NULL,
  905. .reset_ahb2axi_bridge = __reset_ahb2axi_bridge,
  906. .power_on = __power_on_iris2,
  907. .power_off = __power_off_iris2,
  908. .prepare_pc = __prepare_pc_iris2,
  909. .watchdog = __watchdog_iris2,
  910. .noc_error_info = __noc_error_info_iris2,
  911. };
  912. static struct msm_vidc_session_ops msm_session_ops = {
  913. .buffer_size = msm_buffer_size_iris2,
  914. .min_count = msm_buffer_min_count_iris2,
  915. .extra_count = msm_buffer_extra_count_iris2,
  916. .calc_freq = msm_vidc_calc_freq_iris2,
  917. .calc_bw = msm_vidc_calc_bw_iris2,
  918. .decide_work_route = msm_vidc_decide_work_route_iris2,
  919. .decide_work_mode = msm_vidc_decide_work_mode_iris2,
  920. .decide_quality_mode = msm_vidc_decide_quality_mode_iris2,
  921. };
  922. int msm_vidc_init_iris2(struct msm_vidc_core *core)
  923. {
  924. if (!core) {
  925. d_vpr_e("%s: invalid params\n", __func__);
  926. return -EINVAL;
  927. }
  928. d_vpr_h("%s()\n", __func__);
  929. core->venus_ops = &iris2_ops;
  930. core->session_ops = &msm_session_ops;
  931. return 0;
  932. }
  933. int msm_vidc_deinit_iris2(struct msm_vidc_core *core)
  934. {
  935. /* do nothing */
  936. return 0;
  937. }