msm_vidc_iris2.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021,, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/interrupt.h>
  6. #include "msm_vidc_iris2.h"
  7. #include "msm_vidc_buffer_iris2.h"
  8. #include "msm_vidc_power_iris2.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_dt.h"
  15. #include "msm_vidc_internal.h"
  16. #include "msm_vidc_buffer.h"
  17. #include "msm_vidc_debug.h"
  18. #define VIDEO_ARCH_LX 1
  19. #define VBIF_BASE_OFFS_IRIS2 0x00080000
  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. /* FAL10 Feature Control */
  55. #define CPU_CS_X2RPMh_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x168)
  56. #define CPU_CS_X2RPMh_MASK0_BMSK_IRIS2 0x1
  57. #define CPU_CS_X2RPMh_MASK0_SHFT_IRIS2 0x0
  58. #define CPU_CS_X2RPMh_MASK1_BMSK_IRIS2 0x2
  59. #define CPU_CS_X2RPMh_MASK1_SHFT_IRIS2 0x1
  60. #define CPU_CS_X2RPMh_SWOVERRIDE_BMSK_IRIS2 0x4
  61. #define CPU_CS_X2RPMh_SWOVERRIDE_SHFT_IRIS2 0x3
  62. #define CPU_IC_SOFTINT_IRIS2 (CPU_IC_BASE_OFFS_IRIS2 + 0x150)
  63. #define CPU_IC_SOFTINT_H2A_SHFT_IRIS2 0x0
  64. /*
  65. * --------------------------------------------------------------------------
  66. * MODULE: wrapper
  67. * --------------------------------------------------------------------------
  68. */
  69. #define WRAPPER_BASE_OFFS_IRIS2 0x000B0000
  70. #define WRAPPER_INTR_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x0C)
  71. #define WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2 0x8
  72. #define WRAPPER_INTR_STATUS_A2H_BMSK_IRIS2 0x4
  73. #define WRAPPER_INTR_MASK_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x10)
  74. #define WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS2 0x8
  75. #define WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS2 0x4
  76. #define WRAPPER_CPU_CLOCK_CONFIG_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2000)
  77. #define WRAPPER_CPU_CGC_DIS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2010)
  78. #define WRAPPER_CPU_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2014)
  79. #define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x54)
  80. #define WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x58)
  81. /*
  82. * --------------------------------------------------------------------------
  83. * MODULE: tz_wrapper
  84. * --------------------------------------------------------------------------
  85. */
  86. #define WRAPPER_TZ_BASE_OFFS 0x000C0000
  87. #define WRAPPER_TZ_CPU_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS)
  88. #define WRAPPER_TZ_CPU_STATUS (WRAPPER_TZ_BASE_OFFS + 0x10)
  89. #define CTRL_INIT_IRIS2 CPU_CS_SCIACMD_IRIS2
  90. #define CTRL_STATUS_IRIS2 CPU_CS_SCIACMDARG0_IRIS2
  91. #define CTRL_ERROR_STATUS__M_IRIS2 \
  92. CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS2
  93. #define CTRL_INIT_IDLE_MSG_BMSK_IRIS2 \
  94. CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS2
  95. #define CTRL_STATUS_PC_READY_IRIS2 \
  96. CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS2
  97. #define QTBL_INFO_IRIS2 CPU_CS_SCIACMDARG1_IRIS2
  98. #define QTBL_ADDR_IRIS2 CPU_CS_SCIACMDARG2_IRIS2
  99. #define VERSION_INFO_IRIS2 CPU_CS_SCIACMDARG3_IRIS2
  100. #define SFR_ADDR_IRIS2 CPU_CS_SCIBCMD_IRIS2
  101. #define MMAP_ADDR_IRIS2 CPU_CS_SCIBCMDARG0_IRIS2
  102. #define UC_REGION_ADDR_IRIS2 CPU_CS_SCIBARG1_IRIS2
  103. #define UC_REGION_SIZE_IRIS2 CPU_CS_SCIBARG2_IRIS2
  104. #define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
  105. #define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
  106. /*
  107. * --------------------------------------------------------------------------
  108. * MODULE: vcodec noc error log registers (iris2)
  109. * --------------------------------------------------------------------------
  110. */
  111. #define VCODEC_NOC_VIDEO_A_NOC_BASE_OFFS 0x00010000
  112. #define VCODEC_NOC_ERL_MAIN_SWID_LOW 0x00011200
  113. #define VCODEC_NOC_ERL_MAIN_SWID_HIGH 0x00011204
  114. #define VCODEC_NOC_ERL_MAIN_MAINCTL_LOW 0x00011208
  115. #define VCODEC_NOC_ERL_MAIN_ERRVLD_LOW 0x00011210
  116. #define VCODEC_NOC_ERL_MAIN_ERRCLR_LOW 0x00011218
  117. #define VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW 0x00011220
  118. #define VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH 0x00011224
  119. #define VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW 0x00011228
  120. #define VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH 0x0001122C
  121. #define VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW 0x00011230
  122. #define VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH 0x00011234
  123. #define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238
  124. #define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C
  125. static int __interrupt_init_iris2(struct msm_vidc_core *vidc_core)
  126. {
  127. struct msm_vidc_core *core = vidc_core;
  128. u32 mask_val = 0;
  129. int rc = 0;
  130. if (!core) {
  131. d_vpr_e("%s: invalid params\n", __func__);
  132. return -EINVAL;
  133. }
  134. /* All interrupts should be disabled initially 0x1F6 : Reset value */
  135. mask_val = __read_register(core, WRAPPER_INTR_MASK_IRIS2);
  136. /* Write 0 to unmask CPU and WD interrupts */
  137. mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS2|
  138. WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS2);
  139. rc = __write_register(core, WRAPPER_INTR_MASK_IRIS2, mask_val);
  140. if (rc)
  141. return rc;
  142. return 0;
  143. }
  144. static int __setup_ucregion_memory_map_iris2(struct msm_vidc_core *vidc_core)
  145. {
  146. struct msm_vidc_core *core = vidc_core;
  147. u32 value;
  148. int rc = 0;
  149. if (!core) {
  150. d_vpr_e("%s: invalid params\n", __func__);
  151. return -EINVAL;
  152. }
  153. value = (u32)core->iface_q_table.align_device_addr;
  154. rc = __write_register(core, UC_REGION_ADDR_IRIS2, value);
  155. if (rc)
  156. return rc;
  157. value = SHARED_QSIZE;
  158. rc = __write_register(core, UC_REGION_SIZE_IRIS2, value);
  159. if (rc)
  160. return rc;
  161. value = (u32)core->iface_q_table.align_device_addr;
  162. rc = __write_register(core, QTBL_ADDR_IRIS2, value);
  163. if (rc)
  164. return rc;
  165. rc = __write_register(core, QTBL_INFO_IRIS2, 0x01);
  166. if (rc)
  167. return rc;
  168. /* update queues vaddr for debug purpose */
  169. value = (u32)((u64)core->iface_q_table.align_virtual_addr);
  170. rc = __write_register(core, CPU_CS_VCICMDARG0_IRIS2, value);
  171. if (rc)
  172. return rc;
  173. value = (u32)((u64)core->iface_q_table.align_virtual_addr >> 32);
  174. rc = __write_register(core, CPU_CS_VCICMDARG1_IRIS2, value);
  175. if (rc)
  176. return rc;
  177. if (core->sfr.align_device_addr) {
  178. value = (u32)core->sfr.align_device_addr + VIDEO_ARCH_LX;
  179. rc = __write_register(core, SFR_ADDR_IRIS2, value);
  180. if (rc)
  181. return rc;
  182. }
  183. return 0;
  184. }
  185. static int __power_off_iris2(struct msm_vidc_core *vidc_core)
  186. {
  187. u32 lpi_status, reg_status = 0, count = 0, max_count = 10;
  188. struct msm_vidc_core *core = vidc_core;
  189. int rc = 0;
  190. if (!core) {
  191. d_vpr_e("%s: invalid params\n", __func__);
  192. return -EINVAL;
  193. }
  194. if (!core->power_enabled)
  195. return 0;
  196. if (!(core->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2))
  197. disable_irq_nosync(core->dt->irq);
  198. core->intr_status = 0;
  199. /* HPG 6.1.2 Step 1 */
  200. rc = __write_register(core, CPU_CS_X2RPMh_IRIS2, 0x3);
  201. if (rc)
  202. return rc;
  203. /* HPG 6.1.2 Step 2, noc to low power */
  204. //if (core->res->vpu_ver == VPU_VERSION_IRIS2_1)
  205. // goto skip_aon_mvp_noc;
  206. rc = __write_register(core, AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1);
  207. if (rc)
  208. return rc;
  209. while (!reg_status && count < max_count) {
  210. lpi_status =
  211. __read_register(core,
  212. AON_WRAPPER_MVP_NOC_LPI_STATUS);
  213. reg_status = lpi_status & BIT(0);
  214. d_vpr_l("Noc: lpi_status %d noc_status %d (count %d)\n",
  215. lpi_status, reg_status, count);
  216. usleep_range(50, 100);
  217. count++;
  218. }
  219. if (count == max_count)
  220. d_vpr_e("NOC not in qaccept status %d\n", reg_status);
  221. //skip_aon_mvp_noc:
  222. /* HPG 6.1.2 Step 3, debug bridge to low power */
  223. rc = __write_register(core, WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x7);
  224. if (rc)
  225. return rc;
  226. reg_status = 0;
  227. count = 0;
  228. while ((reg_status != 0x7) && count < max_count) {
  229. lpi_status = __read_register(core,
  230. WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2);
  231. reg_status = lpi_status & 0x7;
  232. d_vpr_l("DBLP Set : lpi_status %d reg_status %d (count %d)\n",
  233. lpi_status, reg_status, count);
  234. usleep_range(50, 100);
  235. count++;
  236. }
  237. if (count == max_count)
  238. d_vpr_e("DBLP Set: status %d\n", reg_status);
  239. /* HPG 6.1.2 Step 4, debug bridge to lpi release */
  240. rc = __write_register(core, WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x0);
  241. if (rc)
  242. return rc;
  243. lpi_status = 0x1;
  244. count = 0;
  245. while (lpi_status && count < max_count) {
  246. lpi_status = __read_register(core,
  247. WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2);
  248. d_vpr_l("DBLP Release: lpi_status %d(count %d)\n",
  249. lpi_status, count);
  250. usleep_range(50, 100);
  251. count++;
  252. }
  253. if (count == max_count)
  254. d_vpr_e("DBLP Release: lpi_status %d\n", lpi_status);
  255. /* HPG 6.1.2 Step 6 */
  256. __disable_unprepare_clks(core);
  257. /* HPG 6.1.2 Step 5 */
  258. if (__disable_regulators(core))
  259. d_vpr_e("%s: Failed to disable regulators\n", __func__);
  260. if (__unvote_buses(core))
  261. d_vpr_e("%s: Failed to unvote for buses\n", __func__);
  262. core->power_enabled = false;
  263. return 0;
  264. }
  265. static int __prepare_pc_iris2(struct msm_vidc_core *vidc_core)
  266. {
  267. int rc = 0;
  268. u32 wfi_status = 0, idle_status = 0, pc_ready = 0;
  269. u32 ctrl_status = 0;
  270. int count = 0;
  271. const int max_tries = 10;
  272. struct msm_vidc_core *core = vidc_core;
  273. if (!core) {
  274. d_vpr_e("%s: invalid params\n", __func__);
  275. return -EINVAL;
  276. }
  277. ctrl_status = __read_register(core, CTRL_STATUS_IRIS2);
  278. pc_ready = ctrl_status & CTRL_STATUS_PC_READY_IRIS2;
  279. idle_status = ctrl_status & BIT(30);
  280. if (pc_ready) {
  281. d_vpr_h("Already in pc_ready state\n");
  282. return 0;
  283. }
  284. wfi_status = BIT(0) & __read_register(core, WRAPPER_TZ_CPU_STATUS);
  285. if (!wfi_status || !idle_status) {
  286. d_vpr_e("Skipping PC, wfi status not set\n");
  287. goto skip_power_off;
  288. }
  289. rc = __prepare_pc(core);
  290. if (rc) {
  291. d_vpr_e("Failed __prepare_pc %d\n", rc);
  292. goto skip_power_off;
  293. }
  294. while (count < max_tries) {
  295. wfi_status = BIT(0) & __read_register(core,
  296. WRAPPER_TZ_CPU_STATUS);
  297. ctrl_status = __read_register(core,
  298. CTRL_STATUS_IRIS2);
  299. if (wfi_status && (ctrl_status & CTRL_STATUS_PC_READY_IRIS2))
  300. break;
  301. usleep_range(150, 250);
  302. count++;
  303. }
  304. if (count == max_tries) {
  305. d_vpr_e("Skip PC. Core is not in right state\n");
  306. goto skip_power_off;
  307. }
  308. return rc;
  309. skip_power_off:
  310. d_vpr_e("Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n",
  311. wfi_status, idle_status, pc_ready, ctrl_status);
  312. return -EAGAIN;
  313. }
  314. static int __raise_interrupt_iris2(struct msm_vidc_core *vidc_core)
  315. {
  316. struct msm_vidc_core *core = vidc_core;
  317. int rc = 0;
  318. if (!core) {
  319. d_vpr_e("%s: invalid params\n", __func__);
  320. return -EINVAL;
  321. }
  322. rc = __write_register(core, CPU_IC_SOFTINT_IRIS2, 1 << CPU_IC_SOFTINT_H2A_SHFT_IRIS2);
  323. if (rc)
  324. return rc;
  325. return 0;
  326. }
  327. static int __watchdog_iris2(struct msm_vidc_core *vidc_core, u32 intr_status)
  328. {
  329. int rc = 0;
  330. struct msm_vidc_core *core = vidc_core;
  331. if (!core) {
  332. d_vpr_e("%s: invalid params\n", __func__);
  333. return -EINVAL;
  334. }
  335. if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2) {
  336. d_vpr_e("%s: received watchdog interrupt\n", __func__);
  337. rc = 1;
  338. }
  339. return rc;
  340. }
  341. static int __noc_error_info_iris2(struct msm_vidc_core *vidc_core)
  342. {
  343. u32 val = 0;
  344. struct msm_vidc_core *core = vidc_core;
  345. if (!core) {
  346. d_vpr_e("%s: invalid params\n", __func__);
  347. return -EINVAL;
  348. }
  349. val = __read_register(core, VCODEC_NOC_ERL_MAIN_SWID_LOW);
  350. d_vpr_e("VCODEC_NOC_ERL_MAIN_SWID_LOW: %#x\n", val);
  351. val = __read_register(core, VCODEC_NOC_ERL_MAIN_SWID_HIGH);
  352. d_vpr_e("VCODEC_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val);
  353. val = __read_register(core, VCODEC_NOC_ERL_MAIN_MAINCTL_LOW);
  354. d_vpr_e("VCODEC_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val);
  355. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW);
  356. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val);
  357. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRCLR_LOW);
  358. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val);
  359. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW);
  360. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val);
  361. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH);
  362. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val);
  363. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW);
  364. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val);
  365. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH);
  366. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val);
  367. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW);
  368. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val);
  369. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH);
  370. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val);
  371. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW);
  372. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val);
  373. val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH);
  374. d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val);
  375. return 0;
  376. }
  377. static int __clear_interrupt_iris2(struct msm_vidc_core *vidc_core)
  378. {
  379. struct msm_vidc_core *core = vidc_core;
  380. u32 intr_status = 0, mask = 0;
  381. int rc = 0;
  382. if (!core) {
  383. d_vpr_e("%s: NULL core\n", __func__);
  384. return 0;
  385. }
  386. intr_status = __read_register(core, WRAPPER_INTR_STATUS_IRIS2);
  387. mask = (WRAPPER_INTR_STATUS_A2H_BMSK_IRIS2|
  388. WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2|
  389. CTRL_INIT_IDLE_MSG_BMSK_IRIS2);
  390. if (intr_status & mask) {
  391. core->intr_status |= intr_status;
  392. core->reg_count++;
  393. d_vpr_l("INTERRUPT: times: %d interrupt_status: %d\n",
  394. core->reg_count, intr_status);
  395. } else {
  396. core->spur_count++;
  397. }
  398. rc = __write_register(core, CPU_CS_A2HSOFTINTCLR_IRIS2, 1);
  399. if (rc)
  400. return rc;
  401. return 0;
  402. }
  403. static int __boot_firmware_iris2(struct msm_vidc_core *vidc_core)
  404. {
  405. int rc = 0;
  406. u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000;
  407. struct msm_vidc_core *core = vidc_core;
  408. if (!core) {
  409. d_vpr_e("%s: NULL core\n", __func__);
  410. return 0;
  411. }
  412. ctrl_init_val = BIT(0);
  413. rc = __write_register(core, CTRL_INIT_IRIS2, ctrl_init_val);
  414. if (rc)
  415. return rc;
  416. while (!ctrl_status && count < max_tries) {
  417. ctrl_status = __read_register(core, CTRL_STATUS_IRIS2);
  418. if ((ctrl_status & CTRL_ERROR_STATUS__M_IRIS2) == 0x4) {
  419. d_vpr_e("invalid setting for UC_REGION\n");
  420. break;
  421. }
  422. usleep_range(50, 100);
  423. count++;
  424. }
  425. if (count >= max_tries) {
  426. d_vpr_e("Error booting up vidc firmware\n");
  427. rc = -ETIME;
  428. }
  429. /* Enable interrupt before sending commands to venus */
  430. rc = __write_register(core, CPU_CS_H2XSOFTINTEN_IRIS2, 0x1);
  431. if (rc)
  432. return rc;
  433. rc = __write_register(core, CPU_CS_X2RPMh_IRIS2, 0x0);
  434. if (rc)
  435. return rc;
  436. return rc;
  437. }
  438. int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst* inst)
  439. {
  440. u32 work_mode;
  441. struct v4l2_format *inp_f;
  442. u32 width, height;
  443. bool res_ok = false;
  444. if (!inst || !inst->capabilities) {
  445. d_vpr_e("%s: invalid params\n", __func__);
  446. return -EINVAL;
  447. }
  448. work_mode = MSM_VIDC_STAGE_2;
  449. inp_f = &inst->fmts[INPUT_PORT];
  450. if (is_image_decode_session(inst))
  451. work_mode = MSM_VIDC_STAGE_1;
  452. if (is_image_session(inst))
  453. goto exit;
  454. if (is_decode_session(inst)) {
  455. height = inp_f->fmt.pix_mp.height;
  456. width = inp_f->fmt.pix_mp.width;
  457. res_ok = res_is_less_than(width, height, 1280, 720);
  458. if (inst->capabilities->cap[CODED_FRAMES].value ==
  459. CODED_FRAMES_INTERLACE ||
  460. inst->capabilities->cap[LOWLATENCY_MODE].value ||
  461. res_ok) {
  462. work_mode = MSM_VIDC_STAGE_1;
  463. }
  464. } else if (is_encode_session(inst)) {
  465. height = inst->crop.height;
  466. width = inst->crop.width;
  467. res_ok = !res_is_greater_than(width, height, 4096, 2160);
  468. if (res_ok &&
  469. (inst->capabilities->cap[LOWLATENCY_MODE].value)) {
  470. work_mode = MSM_VIDC_STAGE_1;
  471. }
  472. if (inst->capabilities->cap[LOSSLESS].value)
  473. work_mode = MSM_VIDC_STAGE_2;
  474. if (!inst->capabilities->cap[GOP_SIZE].value)
  475. work_mode = MSM_VIDC_STAGE_2;
  476. } else {
  477. i_vpr_e(inst, "%s: invalid session type\n", __func__);
  478. return -EINVAL;
  479. }
  480. exit:
  481. i_vpr_h(inst, "Configuring work mode = %u low latency = %u, gop size = %u\n",
  482. work_mode, inst->capabilities->cap[LOWLATENCY_MODE].value,
  483. inst->capabilities->cap[GOP_SIZE].value);
  484. msm_vidc_update_cap_value(inst, STAGE, work_mode, __func__);
  485. return 0;
  486. }
  487. int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst* inst)
  488. {
  489. u32 work_route;
  490. struct msm_vidc_core* core;
  491. if (!inst || !inst->core) {
  492. d_vpr_e("%s: invalid params\n", __func__);
  493. return -EINVAL;
  494. }
  495. core = inst->core;
  496. work_route = core->capabilities[NUM_VPP_PIPE].value;
  497. if (is_image_session(inst))
  498. goto exit;
  499. if (is_decode_session(inst)) {
  500. if (inst->capabilities->cap[CODED_FRAMES].value ==
  501. CODED_FRAMES_INTERLACE)
  502. work_route = MSM_VIDC_PIPE_1;
  503. } else if (is_encode_session(inst)) {
  504. u32 slice_mode, width, height;
  505. struct v4l2_format* f;
  506. f = &inst->fmts[INPUT_PORT];
  507. height = f->fmt.pix_mp.height;
  508. width = f->fmt.pix_mp.width;
  509. slice_mode = inst->capabilities->cap[SLICE_MODE].value;
  510. /*TODO Pipe=1 for legacy CBR*/
  511. if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES)
  512. work_route = MSM_VIDC_PIPE_1;
  513. } else {
  514. i_vpr_e(inst, "%s: invalid session type\n", __func__);
  515. return -EINVAL;
  516. }
  517. exit:
  518. i_vpr_h(inst, "Configuring work route = %u", work_route);
  519. msm_vidc_update_cap_value(inst, PIPE, work_route, __func__);
  520. return 0;
  521. }
  522. int msm_vidc_decide_quality_mode_iris2(struct msm_vidc_inst* inst)
  523. {
  524. struct msm_vidc_inst_capability* capability = NULL;
  525. struct msm_vidc_core *core;
  526. u32 mbpf, mbps, max_hq_mbpf, max_hq_mbps;
  527. u32 mode = MSM_VIDC_POWER_SAVE_MODE;
  528. if (!inst || !inst->capabilities) {
  529. d_vpr_e("%s: invalid params\n", __func__);
  530. return -EINVAL;
  531. }
  532. capability = inst->capabilities;
  533. if (!is_encode_session(inst))
  534. return 0;
  535. /* image session always runs at quality mode */
  536. if (is_image_session(inst)) {
  537. mode = MSM_VIDC_MAX_QUALITY_MODE;
  538. goto exit;
  539. }
  540. mbpf = msm_vidc_get_mbs_per_frame(inst);
  541. mbps = mbpf * msm_vidc_get_fps(inst);
  542. core = inst->core;
  543. max_hq_mbpf = core->capabilities[MAX_MBPF_HQ].value;;
  544. max_hq_mbps = core->capabilities[MAX_MBPS_HQ].value;;
  545. /* Power saving always disabled for CQ and LOSSLESS RC modes. */
  546. if (capability->cap[LOSSLESS].value ||
  547. (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps))
  548. mode = MSM_VIDC_MAX_QUALITY_MODE;
  549. exit:
  550. msm_vidc_update_cap_value(inst, QUALITY_MODE, mode, __func__);
  551. return 0;
  552. }
  553. static struct msm_vidc_venus_ops iris2_ops = {
  554. .boot_firmware = __boot_firmware_iris2,
  555. .interrupt_init = __interrupt_init_iris2,
  556. .raise_interrupt = __raise_interrupt_iris2,
  557. .clear_interrupt = __clear_interrupt_iris2,
  558. .setup_ucregion_memmap = __setup_ucregion_memory_map_iris2,
  559. .clock_config_on_enable = NULL,
  560. .reset_ahb2axi_bridge = __reset_ahb2axi_bridge,
  561. .power_off = __power_off_iris2,
  562. .prepare_pc = __prepare_pc_iris2,
  563. .watchdog = __watchdog_iris2,
  564. .noc_error_info = __noc_error_info_iris2,
  565. };
  566. static struct msm_vidc_session_ops msm_session_ops = {
  567. .buffer_size = msm_buffer_size_iris2,
  568. .min_count = msm_buffer_min_count_iris2,
  569. .extra_count = msm_buffer_extra_count_iris2,
  570. .calc_freq = msm_vidc_calc_freq_iris2,
  571. .calc_bw = msm_vidc_calc_bw_iris2,
  572. .decide_work_route = msm_vidc_decide_work_route_iris2,
  573. .decide_work_mode = msm_vidc_decide_work_mode_iris2,
  574. .decide_quality_mode = msm_vidc_decide_quality_mode_iris2,
  575. };
  576. int msm_vidc_init_iris2(struct msm_vidc_core *core)
  577. {
  578. if (!core) {
  579. d_vpr_e("%s: invalid params\n", __func__);
  580. return -EINVAL;
  581. }
  582. d_vpr_h("%s()\n", __func__);
  583. core->venus_ops = &iris2_ops;
  584. core->session_ops = &msm_session_ops;
  585. return 0;
  586. }
  587. int msm_vidc_deinit_iris2(struct msm_vidc_core *core)
  588. {
  589. /* do nothing */
  590. return 0;
  591. }