ivpu_hw_ip.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2020-2024 Intel Corporation
  4. */
  5. #include "ivpu_drv.h"
  6. #include "ivpu_fw.h"
  7. #include "ivpu_gem.h"
  8. #include "ivpu_hw.h"
  9. #include "ivpu_hw_37xx_reg.h"
  10. #include "ivpu_hw_40xx_reg.h"
  11. #include "ivpu_hw_btrs.h"
  12. #include "ivpu_hw_ip.h"
  13. #include "ivpu_hw_reg_io.h"
  14. #include "ivpu_mmu.h"
  15. #include "ivpu_pm.h"
  16. #define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC)
  17. #define TIM_SAFE_ENABLE 0xf1d0dead
  18. #define TIM_WATCHDOG_RESET_VALUE 0xffffffff
  19. #define ICB_0_IRQ_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \
  20. (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \
  21. (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT)) | \
  22. (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT)) | \
  23. (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT)) | \
  24. (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT)) | \
  25. (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT)))
  26. #define ICB_1_IRQ_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_2_INT)) | \
  27. (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_3_INT)) | \
  28. (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_4_INT)))
  29. #define ICB_0_1_IRQ_MASK_37XX ((((u64)ICB_1_IRQ_MASK_37XX) << 32) | ICB_0_IRQ_MASK_37XX)
  30. #define ICB_0_IRQ_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \
  31. (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \
  32. (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT)) | \
  33. (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT)) | \
  34. (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT)) | \
  35. (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT)) | \
  36. (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT)))
  37. #define ICB_1_IRQ_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_2_INT)) | \
  38. (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_3_INT)) | \
  39. (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_4_INT)))
  40. #define ICB_0_1_IRQ_MASK_40XX ((((u64)ICB_1_IRQ_MASK_40XX) << 32) | ICB_0_IRQ_MASK_40XX)
  41. #define ITF_FIREWALL_VIOLATION_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_ROM_CMX)) | \
  42. (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_DBG)) | \
  43. (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_CTRL)) | \
  44. (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, DEC400)) | \
  45. (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_NCE)) | \
  46. (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \
  47. (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX)))
  48. #define ITF_FIREWALL_VIOLATION_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_ROM_CMX)) | \
  49. (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_DBG)) | \
  50. (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_CTRL)) | \
  51. (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, DEC400)) | \
  52. (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_NCE)) | \
  53. (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \
  54. (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX)))
  55. static int wait_for_ip_bar(struct ivpu_device *vdev)
  56. {
  57. return REGV_POLL_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, AON, 0, 100);
  58. }
  59. static void host_ss_rst_clr(struct ivpu_device *vdev)
  60. {
  61. u32 val = 0;
  62. val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, TOP_NOC, val);
  63. val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, DSS_MAS, val);
  64. val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, MSS_MAS, val);
  65. REGV_WR32(VPU_37XX_HOST_SS_CPR_RST_CLR, val);
  66. }
  67. static int host_ss_noc_qreqn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
  68. {
  69. u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QREQN);
  70. if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, exp_val, val))
  71. return -EIO;
  72. return 0;
  73. }
  74. static int host_ss_noc_qreqn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
  75. {
  76. u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QREQN);
  77. if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, exp_val, val))
  78. return -EIO;
  79. return 0;
  80. }
  81. static int host_ss_noc_qreqn_check(struct ivpu_device *vdev, u32 exp_val)
  82. {
  83. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  84. return host_ss_noc_qreqn_check_37xx(vdev, exp_val);
  85. else
  86. return host_ss_noc_qreqn_check_40xx(vdev, exp_val);
  87. }
  88. static int host_ss_noc_qacceptn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
  89. {
  90. u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QACCEPTN);
  91. if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QACCEPTN, TOP_SOCMMIO, exp_val, val))
  92. return -EIO;
  93. return 0;
  94. }
  95. static int host_ss_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
  96. {
  97. u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QACCEPTN);
  98. if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QACCEPTN, TOP_SOCMMIO, exp_val, val))
  99. return -EIO;
  100. return 0;
  101. }
  102. static int host_ss_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
  103. {
  104. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  105. return host_ss_noc_qacceptn_check_37xx(vdev, exp_val);
  106. else
  107. return host_ss_noc_qacceptn_check_40xx(vdev, exp_val);
  108. }
  109. static int host_ss_noc_qdeny_check_37xx(struct ivpu_device *vdev, u32 exp_val)
  110. {
  111. u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QDENY);
  112. if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QDENY, TOP_SOCMMIO, exp_val, val))
  113. return -EIO;
  114. return 0;
  115. }
  116. static int host_ss_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)
  117. {
  118. u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QDENY);
  119. if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QDENY, TOP_SOCMMIO, exp_val, val))
  120. return -EIO;
  121. return 0;
  122. }
  123. static int host_ss_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
  124. {
  125. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  126. return host_ss_noc_qdeny_check_37xx(vdev, exp_val);
  127. else
  128. return host_ss_noc_qdeny_check_40xx(vdev, exp_val);
  129. }
  130. static int top_noc_qrenqn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
  131. {
  132. u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QREQN);
  133. if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, exp_val, val) ||
  134. !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, exp_val, val))
  135. return -EIO;
  136. return 0;
  137. }
  138. static int top_noc_qrenqn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
  139. {
  140. u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QREQN);
  141. if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, exp_val, val) ||
  142. !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, exp_val, val))
  143. return -EIO;
  144. return 0;
  145. }
  146. static int top_noc_qreqn_check(struct ivpu_device *vdev, u32 exp_val)
  147. {
  148. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  149. return top_noc_qrenqn_check_37xx(vdev, exp_val);
  150. else
  151. return top_noc_qrenqn_check_40xx(vdev, exp_val);
  152. }
  153. int ivpu_hw_ip_host_ss_configure(struct ivpu_device *vdev)
  154. {
  155. int ret;
  156. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
  157. ret = wait_for_ip_bar(vdev);
  158. if (ret) {
  159. ivpu_err(vdev, "Timed out waiting for NPU IP bar\n");
  160. return ret;
  161. }
  162. host_ss_rst_clr(vdev);
  163. }
  164. ret = host_ss_noc_qreqn_check(vdev, 0x0);
  165. if (ret) {
  166. ivpu_err(vdev, "Failed qreqn check: %d\n", ret);
  167. return ret;
  168. }
  169. ret = host_ss_noc_qacceptn_check(vdev, 0x0);
  170. if (ret) {
  171. ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
  172. return ret;
  173. }
  174. ret = host_ss_noc_qdeny_check(vdev, 0x0);
  175. if (ret)
  176. ivpu_err(vdev, "Failed qdeny check %d\n", ret);
  177. return ret;
  178. }
  179. static void idle_gen_drive_37xx(struct ivpu_device *vdev, bool enable)
  180. {
  181. u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN);
  182. if (enable)
  183. val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, EN, val);
  184. else
  185. val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, EN, val);
  186. REGV_WR32(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, val);
  187. }
  188. static void idle_gen_drive_40xx(struct ivpu_device *vdev, bool enable)
  189. {
  190. u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_IDLE_GEN);
  191. if (enable)
  192. val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_IDLE_GEN, EN, val);
  193. else
  194. val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_IDLE_GEN, EN, val);
  195. REGV_WR32(VPU_40XX_HOST_SS_AON_IDLE_GEN, val);
  196. }
  197. void ivpu_hw_ip_idle_gen_enable(struct ivpu_device *vdev)
  198. {
  199. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  200. idle_gen_drive_37xx(vdev, true);
  201. else
  202. idle_gen_drive_40xx(vdev, true);
  203. }
  204. void ivpu_hw_ip_idle_gen_disable(struct ivpu_device *vdev)
  205. {
  206. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  207. idle_gen_drive_37xx(vdev, false);
  208. else
  209. idle_gen_drive_40xx(vdev, false);
  210. }
  211. static void
  212. pwr_island_delay_set_50xx(struct ivpu_device *vdev, u32 post, u32 post1, u32 post2, u32 status)
  213. {
  214. u32 val;
  215. val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY);
  216. val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST_DLY, post, val);
  217. val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST1_DLY, post1, val);
  218. val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST2_DLY, post2, val);
  219. REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, val);
  220. val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY);
  221. val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY, STATUS_DLY, status, val);
  222. REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY, val);
  223. }
  224. static void pwr_island_trickle_drive_37xx(struct ivpu_device *vdev, bool enable)
  225. {
  226. u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
  227. if (enable)
  228. val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);
  229. else
  230. val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);
  231. REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val);
  232. }
  233. static void pwr_island_trickle_drive_40xx(struct ivpu_device *vdev, bool enable)
  234. {
  235. u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
  236. if (enable)
  237. val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val);
  238. else
  239. val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val);
  240. REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val);
  241. }
  242. static void pwr_island_drive_37xx(struct ivpu_device *vdev, bool enable)
  243. {
  244. u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0);
  245. if (enable)
  246. val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val);
  247. else
  248. val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val);
  249. REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, val);
  250. }
  251. static void pwr_island_drive_40xx(struct ivpu_device *vdev, bool enable)
  252. {
  253. u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0);
  254. if (enable)
  255. val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);
  256. else
  257. val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);
  258. REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, val);
  259. }
  260. static void pwr_island_enable(struct ivpu_device *vdev)
  261. {
  262. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
  263. pwr_island_trickle_drive_37xx(vdev, true);
  264. ndelay(500);
  265. pwr_island_drive_37xx(vdev, true);
  266. } else {
  267. pwr_island_trickle_drive_40xx(vdev, true);
  268. ndelay(500);
  269. pwr_island_drive_40xx(vdev, true);
  270. }
  271. }
  272. static int wait_for_pwr_island_status(struct ivpu_device *vdev, u32 exp_val)
  273. {
  274. if (IVPU_WA(punit_disabled))
  275. return 0;
  276. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  277. return REGV_POLL_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_STATUS0, MSS_CPU, exp_val,
  278. PWR_ISLAND_STATUS_TIMEOUT_US);
  279. else
  280. return REGV_POLL_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_STATUS0, CSS_CPU, exp_val,
  281. PWR_ISLAND_STATUS_TIMEOUT_US);
  282. }
  283. static void pwr_island_isolation_drive_37xx(struct ivpu_device *vdev, bool enable)
  284. {
  285. u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0);
  286. if (enable)
  287. val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);
  288. else
  289. val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);
  290. REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, val);
  291. }
  292. static void pwr_island_isolation_drive_40xx(struct ivpu_device *vdev, bool enable)
  293. {
  294. u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0);
  295. if (enable)
  296. val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, CSS_CPU, val);
  297. else
  298. val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, CSS_CPU, val);
  299. REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, val);
  300. }
  301. static void pwr_island_isolation_drive(struct ivpu_device *vdev, bool enable)
  302. {
  303. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  304. pwr_island_isolation_drive_37xx(vdev, enable);
  305. else
  306. pwr_island_isolation_drive_40xx(vdev, enable);
  307. }
  308. static void pwr_island_isolation_disable(struct ivpu_device *vdev)
  309. {
  310. pwr_island_isolation_drive(vdev, false);
  311. }
  312. static void host_ss_clk_drive_37xx(struct ivpu_device *vdev, bool enable)
  313. {
  314. u32 val = REGV_RD32(VPU_37XX_HOST_SS_CPR_CLK_SET);
  315. if (enable) {
  316. val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, TOP_NOC, val);
  317. val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, DSS_MAS, val);
  318. val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, MSS_MAS, val);
  319. } else {
  320. val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, TOP_NOC, val);
  321. val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, DSS_MAS, val);
  322. val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, MSS_MAS, val);
  323. }
  324. REGV_WR32(VPU_37XX_HOST_SS_CPR_CLK_SET, val);
  325. }
  326. static void host_ss_clk_drive_40xx(struct ivpu_device *vdev, bool enable)
  327. {
  328. u32 val = REGV_RD32(VPU_40XX_HOST_SS_CPR_CLK_EN);
  329. if (enable) {
  330. val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, TOP_NOC, val);
  331. val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, DSS_MAS, val);
  332. val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, CSS_MAS, val);
  333. } else {
  334. val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, TOP_NOC, val);
  335. val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, DSS_MAS, val);
  336. val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, CSS_MAS, val);
  337. }
  338. REGV_WR32(VPU_40XX_HOST_SS_CPR_CLK_EN, val);
  339. }
  340. static void host_ss_clk_drive(struct ivpu_device *vdev, bool enable)
  341. {
  342. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  343. host_ss_clk_drive_37xx(vdev, enable);
  344. else
  345. host_ss_clk_drive_40xx(vdev, enable);
  346. }
  347. static void host_ss_clk_enable(struct ivpu_device *vdev)
  348. {
  349. host_ss_clk_drive(vdev, true);
  350. }
  351. static void host_ss_rst_drive_37xx(struct ivpu_device *vdev, bool enable)
  352. {
  353. u32 val = REGV_RD32(VPU_37XX_HOST_SS_CPR_RST_SET);
  354. if (enable) {
  355. val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, TOP_NOC, val);
  356. val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, DSS_MAS, val);
  357. val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, MSS_MAS, val);
  358. } else {
  359. val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, TOP_NOC, val);
  360. val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, DSS_MAS, val);
  361. val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, MSS_MAS, val);
  362. }
  363. REGV_WR32(VPU_37XX_HOST_SS_CPR_RST_SET, val);
  364. }
  365. static void host_ss_rst_drive_40xx(struct ivpu_device *vdev, bool enable)
  366. {
  367. u32 val = REGV_RD32(VPU_40XX_HOST_SS_CPR_RST_EN);
  368. if (enable) {
  369. val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, TOP_NOC, val);
  370. val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, DSS_MAS, val);
  371. val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, CSS_MAS, val);
  372. } else {
  373. val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, TOP_NOC, val);
  374. val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, DSS_MAS, val);
  375. val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, CSS_MAS, val);
  376. }
  377. REGV_WR32(VPU_40XX_HOST_SS_CPR_RST_EN, val);
  378. }
  379. static void host_ss_rst_drive(struct ivpu_device *vdev, bool enable)
  380. {
  381. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  382. host_ss_rst_drive_37xx(vdev, enable);
  383. else
  384. host_ss_rst_drive_40xx(vdev, enable);
  385. }
  386. static void host_ss_rst_enable(struct ivpu_device *vdev)
  387. {
  388. host_ss_rst_drive(vdev, true);
  389. }
  390. static void host_ss_noc_qreqn_top_socmmio_drive_37xx(struct ivpu_device *vdev, bool enable)
  391. {
  392. u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QREQN);
  393. if (enable)
  394. val = REG_SET_FLD(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
  395. else
  396. val = REG_CLR_FLD(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
  397. REGV_WR32(VPU_37XX_HOST_SS_NOC_QREQN, val);
  398. }
  399. static void host_ss_noc_qreqn_top_socmmio_drive_40xx(struct ivpu_device *vdev, bool enable)
  400. {
  401. u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QREQN);
  402. if (enable)
  403. val = REG_SET_FLD(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
  404. else
  405. val = REG_CLR_FLD(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
  406. REGV_WR32(VPU_40XX_HOST_SS_NOC_QREQN, val);
  407. }
  408. static void host_ss_noc_qreqn_top_socmmio_drive(struct ivpu_device *vdev, bool enable)
  409. {
  410. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  411. host_ss_noc_qreqn_top_socmmio_drive_37xx(vdev, enable);
  412. else
  413. host_ss_noc_qreqn_top_socmmio_drive_40xx(vdev, enable);
  414. }
  415. static int host_ss_axi_drive(struct ivpu_device *vdev, bool enable)
  416. {
  417. int ret;
  418. host_ss_noc_qreqn_top_socmmio_drive(vdev, enable);
  419. ret = host_ss_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
  420. if (ret) {
  421. ivpu_err(vdev, "Failed HOST SS NOC QACCEPTN check: %d\n", ret);
  422. return ret;
  423. }
  424. ret = host_ss_noc_qdeny_check(vdev, 0x0);
  425. if (ret)
  426. ivpu_err(vdev, "Failed HOST SS NOC QDENY check: %d\n", ret);
  427. return ret;
  428. }
  429. static void top_noc_qreqn_drive_40xx(struct ivpu_device *vdev, bool enable)
  430. {
  431. u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QREQN);
  432. if (enable) {
  433. val = REG_SET_FLD(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, val);
  434. val = REG_SET_FLD(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
  435. } else {
  436. val = REG_CLR_FLD(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, val);
  437. val = REG_CLR_FLD(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
  438. }
  439. REGV_WR32(VPU_40XX_TOP_NOC_QREQN, val);
  440. }
  441. static void top_noc_qreqn_drive_37xx(struct ivpu_device *vdev, bool enable)
  442. {
  443. u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QREQN);
  444. if (enable) {
  445. val = REG_SET_FLD(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, val);
  446. val = REG_SET_FLD(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
  447. } else {
  448. val = REG_CLR_FLD(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, val);
  449. val = REG_CLR_FLD(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
  450. }
  451. REGV_WR32(VPU_37XX_TOP_NOC_QREQN, val);
  452. }
  453. static void top_noc_qreqn_drive(struct ivpu_device *vdev, bool enable)
  454. {
  455. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  456. top_noc_qreqn_drive_37xx(vdev, enable);
  457. else
  458. top_noc_qreqn_drive_40xx(vdev, enable);
  459. }
  460. int ivpu_hw_ip_host_ss_axi_enable(struct ivpu_device *vdev)
  461. {
  462. return host_ss_axi_drive(vdev, true);
  463. }
  464. static int top_noc_qacceptn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
  465. {
  466. u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QACCEPTN);
  467. if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QACCEPTN, CPU_CTRL, exp_val, val) ||
  468. !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QACCEPTN, HOSTIF_L2CACHE, exp_val, val))
  469. return -EIO;
  470. return 0;
  471. }
  472. static int top_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
  473. {
  474. u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QACCEPTN);
  475. if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QACCEPTN, CPU_CTRL, exp_val, val) ||
  476. !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QACCEPTN, HOSTIF_L2CACHE, exp_val, val))
  477. return -EIO;
  478. return 0;
  479. }
  480. static int top_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
  481. {
  482. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  483. return top_noc_qacceptn_check_37xx(vdev, exp_val);
  484. else
  485. return top_noc_qacceptn_check_40xx(vdev, exp_val);
  486. }
  487. static int top_noc_qdeny_check_37xx(struct ivpu_device *vdev, u32 exp_val)
  488. {
  489. u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QDENY);
  490. if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QDENY, CPU_CTRL, exp_val, val) ||
  491. !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QDENY, HOSTIF_L2CACHE, exp_val, val))
  492. return -EIO;
  493. return 0;
  494. }
  495. static int top_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)
  496. {
  497. u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QDENY);
  498. if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QDENY, CPU_CTRL, exp_val, val) ||
  499. !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QDENY, HOSTIF_L2CACHE, exp_val, val))
  500. return -EIO;
  501. return 0;
  502. }
  503. static int top_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
  504. {
  505. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  506. return top_noc_qdeny_check_37xx(vdev, exp_val);
  507. else
  508. return top_noc_qdeny_check_40xx(vdev, exp_val);
  509. }
  510. static int top_noc_drive(struct ivpu_device *vdev, bool enable)
  511. {
  512. int ret;
  513. top_noc_qreqn_drive(vdev, enable);
  514. ret = top_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
  515. if (ret) {
  516. ivpu_err(vdev, "Failed TOP NOC QACCEPTN check: %d\n", ret);
  517. return ret;
  518. }
  519. ret = top_noc_qdeny_check(vdev, 0x0);
  520. if (ret)
  521. ivpu_err(vdev, "Failed TOP NOC QDENY check: %d\n", ret);
  522. return ret;
  523. }
  524. int ivpu_hw_ip_top_noc_enable(struct ivpu_device *vdev)
  525. {
  526. return top_noc_drive(vdev, true);
  527. }
  528. static void dpu_active_drive_37xx(struct ivpu_device *vdev, bool enable)
  529. {
  530. u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE);
  531. if (enable)
  532. val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);
  533. else
  534. val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);
  535. REGV_WR32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, val);
  536. }
  537. static void pwr_island_delay_set(struct ivpu_device *vdev)
  538. {
  539. bool high = vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_HIGH;
  540. u32 post, post1, post2, status;
  541. if (ivpu_hw_ip_gen(vdev) < IVPU_HW_IP_50XX)
  542. return;
  543. switch (ivpu_device_id(vdev)) {
  544. case PCI_DEVICE_ID_WCL:
  545. case PCI_DEVICE_ID_PTL_P:
  546. post = high ? 18 : 0;
  547. post1 = 0;
  548. post2 = 0;
  549. status = high ? 46 : 3;
  550. break;
  551. case PCI_DEVICE_ID_NVL:
  552. post = high ? 198 : 17;
  553. post1 = 0;
  554. post2 = high ? 198 : 17;
  555. status = 0;
  556. break;
  557. default:
  558. dump_stack();
  559. ivpu_err(vdev, "Unknown device ID\n");
  560. return;
  561. }
  562. pwr_island_delay_set_50xx(vdev, post, post1, post2, status);
  563. }
  564. int ivpu_hw_ip_pwr_domain_enable(struct ivpu_device *vdev)
  565. {
  566. int ret;
  567. pwr_island_delay_set(vdev);
  568. pwr_island_enable(vdev);
  569. ret = wait_for_pwr_island_status(vdev, 0x1);
  570. if (ret) {
  571. ivpu_err(vdev, "Timed out waiting for power island status\n");
  572. return ret;
  573. }
  574. ret = top_noc_qreqn_check(vdev, 0x0);
  575. if (ret) {
  576. ivpu_err(vdev, "Failed TOP NOC QREQN check %d\n", ret);
  577. return ret;
  578. }
  579. host_ss_clk_enable(vdev);
  580. pwr_island_isolation_disable(vdev);
  581. host_ss_rst_enable(vdev);
  582. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  583. dpu_active_drive_37xx(vdev, true);
  584. return ret;
  585. }
  586. u64 ivpu_hw_ip_read_perf_timer_counter(struct ivpu_device *vdev)
  587. {
  588. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  589. return REGV_RD64(VPU_37XX_CPU_SS_TIM_PERF_FREE_CNT);
  590. else
  591. return REGV_RD64(VPU_40XX_CPU_SS_TIM_PERF_EXT_FREE_CNT);
  592. }
  593. static void ivpu_hw_ip_snoop_disable_37xx(struct ivpu_device *vdev)
  594. {
  595. u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES);
  596. val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, NOSNOOP_OVERRIDE_EN, val);
  597. val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AW_NOSNOOP_OVERRIDE, val);
  598. if (ivpu_is_force_snoop_enabled(vdev))
  599. val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);
  600. else
  601. val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);
  602. REGV_WR32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, val);
  603. }
  604. static void ivpu_hw_ip_snoop_disable_40xx(struct ivpu_device *vdev)
  605. {
  606. u32 val = REGV_RD32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES);
  607. val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, SNOOP_OVERRIDE_EN, val);
  608. val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AW_SNOOP_OVERRIDE, val);
  609. if (ivpu_is_force_snoop_enabled(vdev))
  610. val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);
  611. else
  612. val = REG_CLR_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);
  613. REGV_WR32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, val);
  614. }
  615. void ivpu_hw_ip_snoop_disable(struct ivpu_device *vdev)
  616. {
  617. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  618. return ivpu_hw_ip_snoop_disable_37xx(vdev);
  619. else
  620. return ivpu_hw_ip_snoop_disable_40xx(vdev);
  621. }
  622. static void ivpu_hw_ip_tbu_mmu_enable_37xx(struct ivpu_device *vdev)
  623. {
  624. u32 val = REGV_RD32(VPU_37XX_HOST_IF_TBU_MMUSSIDV);
  625. val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);
  626. val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);
  627. val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);
  628. val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);
  629. REGV_WR32(VPU_37XX_HOST_IF_TBU_MMUSSIDV, val);
  630. }
  631. static void ivpu_hw_ip_tbu_mmu_enable_40xx(struct ivpu_device *vdev)
  632. {
  633. u32 val = REGV_RD32(VPU_40XX_HOST_IF_TBU_MMUSSIDV);
  634. val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);
  635. val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);
  636. val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU1_AWMMUSSIDV, val);
  637. val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU1_ARMMUSSIDV, val);
  638. val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);
  639. val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);
  640. REGV_WR32(VPU_40XX_HOST_IF_TBU_MMUSSIDV, val);
  641. }
  642. void ivpu_hw_ip_tbu_mmu_enable(struct ivpu_device *vdev)
  643. {
  644. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  645. return ivpu_hw_ip_tbu_mmu_enable_37xx(vdev);
  646. else
  647. return ivpu_hw_ip_tbu_mmu_enable_40xx(vdev);
  648. }
  649. static inline u64 get_entry_point_addr(struct ivpu_device *vdev)
  650. {
  651. if (ivpu_fw_is_warm_boot(vdev))
  652. return vdev->fw->warm_boot_entry_point;
  653. else
  654. return vdev->fw->cold_boot_entry_point;
  655. }
  656. static int soc_cpu_boot_37xx(struct ivpu_device *vdev)
  657. {
  658. u32 val;
  659. val = REGV_RD32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC);
  660. val = REG_SET_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTRUN0, val);
  661. val = REG_CLR_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTVEC, val);
  662. REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
  663. val = REG_SET_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);
  664. REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
  665. val = REG_CLR_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);
  666. REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
  667. val = get_entry_point_addr(vdev) >> 9;
  668. REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val);
  669. val = REG_SET_FLD(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, DONE, val);
  670. REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val);
  671. return 0;
  672. }
  673. static int cpu_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
  674. {
  675. u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QACCEPTN);
  676. if (!REG_TEST_FLD_NUM(VPU_40XX_CPU_SS_CPR_NOC_QACCEPTN, TOP_MMIO, exp_val, val))
  677. return -EIO;
  678. return 0;
  679. }
  680. static int cpu_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)
  681. {
  682. u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QDENY);
  683. if (!REG_TEST_FLD_NUM(VPU_40XX_CPU_SS_CPR_NOC_QDENY, TOP_MMIO, exp_val, val))
  684. return -EIO;
  685. return 0;
  686. }
  687. static void cpu_noc_top_mmio_drive_40xx(struct ivpu_device *vdev, bool enable)
  688. {
  689. u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QREQN);
  690. if (enable)
  691. val = REG_SET_FLD(VPU_40XX_CPU_SS_CPR_NOC_QREQN, TOP_MMIO, val);
  692. else
  693. val = REG_CLR_FLD(VPU_40XX_CPU_SS_CPR_NOC_QREQN, TOP_MMIO, val);
  694. REGV_WR32(VPU_40XX_CPU_SS_CPR_NOC_QREQN, val);
  695. }
  696. static int soc_cpu_drive_40xx(struct ivpu_device *vdev, bool enable)
  697. {
  698. int ret;
  699. cpu_noc_top_mmio_drive_40xx(vdev, enable);
  700. ret = cpu_noc_qacceptn_check_40xx(vdev, enable ? 0x1 : 0x0);
  701. if (ret) {
  702. ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
  703. return ret;
  704. }
  705. ret = cpu_noc_qdeny_check_40xx(vdev, 0x0);
  706. if (ret)
  707. ivpu_err(vdev, "Failed qdeny check: %d\n", ret);
  708. return ret;
  709. }
  710. static void soc_cpu_set_entry_point_40xx(struct ivpu_device *vdev, u64 entry_point)
  711. {
  712. u64 val64;
  713. u32 val;
  714. val64 = entry_point;
  715. val64 <<= ffs(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO_IMAGE_LOCATION_MASK) - 1;
  716. REGV_WR64(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val64);
  717. val = REGV_RD32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO);
  718. val = REG_SET_FLD(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, DONE, val);
  719. REGV_WR32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val);
  720. }
  721. static int soc_cpu_boot_40xx(struct ivpu_device *vdev)
  722. {
  723. int ret;
  724. ret = soc_cpu_drive_40xx(vdev, true);
  725. if (ret) {
  726. ivpu_err(vdev, "Failed to enable SOC CPU: %d\n", ret);
  727. return ret;
  728. }
  729. soc_cpu_set_entry_point_40xx(vdev, get_entry_point_addr(vdev));
  730. return 0;
  731. }
  732. static int soc_cpu_boot_60xx(struct ivpu_device *vdev)
  733. {
  734. soc_cpu_set_entry_point_40xx(vdev, vdev->fw->cold_boot_entry_point);
  735. return 0;
  736. }
  737. int ivpu_hw_ip_soc_cpu_boot(struct ivpu_device *vdev)
  738. {
  739. int ret;
  740. switch (ivpu_hw_ip_gen(vdev)) {
  741. case IVPU_HW_IP_37XX:
  742. ret = soc_cpu_boot_37xx(vdev);
  743. break;
  744. case IVPU_HW_IP_40XX:
  745. case IVPU_HW_IP_50XX:
  746. ret = soc_cpu_boot_40xx(vdev);
  747. break;
  748. default:
  749. ret = soc_cpu_boot_60xx(vdev);
  750. }
  751. if (ret)
  752. return ret;
  753. ivpu_dbg(vdev, PM, "Booting firmware, mode: %s\n",
  754. ivpu_fw_is_warm_boot(vdev) ? "warm boot" : "cold boot");
  755. return 0;
  756. }
  757. static void wdt_disable_37xx(struct ivpu_device *vdev)
  758. {
  759. u32 val;
  760. /* Enable writing and set non-zero WDT value */
  761. REGV_WR32(VPU_37XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
  762. REGV_WR32(VPU_37XX_CPU_SS_TIM_WATCHDOG, TIM_WATCHDOG_RESET_VALUE);
  763. /* Enable writing and disable watchdog timer */
  764. REGV_WR32(VPU_37XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
  765. REGV_WR32(VPU_37XX_CPU_SS_TIM_WDOG_EN, 0);
  766. /* Now clear the timeout interrupt */
  767. val = REGV_RD32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG);
  768. val = REG_CLR_FLD(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, WDOG_TO_INT_CLR, val);
  769. REGV_WR32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, val);
  770. }
  771. static void wdt_disable_40xx(struct ivpu_device *vdev)
  772. {
  773. u32 val;
  774. REGV_WR32(VPU_40XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
  775. REGV_WR32(VPU_40XX_CPU_SS_TIM_WATCHDOG, TIM_WATCHDOG_RESET_VALUE);
  776. REGV_WR32(VPU_40XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
  777. REGV_WR32(VPU_40XX_CPU_SS_TIM_WDOG_EN, 0);
  778. val = REGV_RD32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG);
  779. val = REG_CLR_FLD(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, WDOG_TO_INT_CLR, val);
  780. REGV_WR32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, val);
  781. }
  782. void ivpu_hw_ip_wdt_disable(struct ivpu_device *vdev)
  783. {
  784. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  785. return wdt_disable_37xx(vdev);
  786. else
  787. return wdt_disable_40xx(vdev);
  788. }
  789. static u32 ipc_rx_count_get_37xx(struct ivpu_device *vdev)
  790. {
  791. u32 count = readl(vdev->regv + VPU_37XX_HOST_SS_TIM_IPC_FIFO_STAT);
  792. return REG_GET_FLD(VPU_37XX_HOST_SS_TIM_IPC_FIFO_STAT, FILL_LEVEL, count);
  793. }
  794. static u32 ipc_rx_count_get_40xx(struct ivpu_device *vdev)
  795. {
  796. u32 count = readl(vdev->regv + VPU_40XX_HOST_SS_TIM_IPC_FIFO_STAT);
  797. return REG_GET_FLD(VPU_40XX_HOST_SS_TIM_IPC_FIFO_STAT, FILL_LEVEL, count);
  798. }
  799. u32 ivpu_hw_ip_ipc_rx_count_get(struct ivpu_device *vdev)
  800. {
  801. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  802. return ipc_rx_count_get_37xx(vdev);
  803. else
  804. return ipc_rx_count_get_40xx(vdev);
  805. }
  806. void ivpu_hw_ip_irq_enable(struct ivpu_device *vdev)
  807. {
  808. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
  809. REGV_WR32(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, ITF_FIREWALL_VIOLATION_MASK_37XX);
  810. REGV_WR64(VPU_37XX_HOST_SS_ICB_ENABLE_0, ICB_0_1_IRQ_MASK_37XX);
  811. } else {
  812. REGV_WR32(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, ITF_FIREWALL_VIOLATION_MASK_40XX);
  813. REGV_WR64(VPU_40XX_HOST_SS_ICB_ENABLE_0, ICB_0_1_IRQ_MASK_40XX);
  814. }
  815. }
  816. void ivpu_hw_ip_irq_disable(struct ivpu_device *vdev)
  817. {
  818. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
  819. REGV_WR64(VPU_37XX_HOST_SS_ICB_ENABLE_0, 0x0ull);
  820. REGV_WR32(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, 0x0);
  821. } else {
  822. REGV_WR64(VPU_40XX_HOST_SS_ICB_ENABLE_0, 0x0ull);
  823. REGV_WR32(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, 0x0ul);
  824. }
  825. }
  826. static void diagnose_failure_37xx(struct ivpu_device *vdev)
  827. {
  828. u32 reg = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_37XX;
  829. if (ipc_rx_count_get_37xx(vdev))
  830. ivpu_err(vdev, "IPC FIFO queue not empty, missed IPC IRQ");
  831. if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, reg))
  832. ivpu_err(vdev, "WDT MSS timeout detected\n");
  833. if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, reg))
  834. ivpu_err(vdev, "WDT NCE timeout detected\n");
  835. if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, reg))
  836. ivpu_err(vdev, "NOC Firewall irq detected\n");
  837. }
  838. static void diagnose_failure_40xx(struct ivpu_device *vdev)
  839. {
  840. u32 reg = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_40XX;
  841. if (ipc_rx_count_get_40xx(vdev))
  842. ivpu_err(vdev, "IPC FIFO queue not empty, missed IPC IRQ");
  843. if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, reg))
  844. ivpu_err(vdev, "WDT MSS timeout detected\n");
  845. if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, reg))
  846. ivpu_err(vdev, "WDT NCE timeout detected\n");
  847. if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, reg))
  848. ivpu_err(vdev, "NOC Firewall irq detected\n");
  849. }
  850. void ivpu_hw_ip_diagnose_failure(struct ivpu_device *vdev)
  851. {
  852. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  853. diagnose_failure_37xx(vdev);
  854. else
  855. diagnose_failure_40xx(vdev);
  856. }
  857. void ivpu_hw_ip_irq_clear(struct ivpu_device *vdev)
  858. {
  859. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  860. REGV_WR64(VPU_37XX_HOST_SS_ICB_CLEAR_0, ICB_0_1_IRQ_MASK_37XX);
  861. else
  862. REGV_WR64(VPU_40XX_HOST_SS_ICB_CLEAR_0, ICB_0_1_IRQ_MASK_40XX);
  863. }
  864. static void irq_wdt_nce_handler(struct ivpu_device *vdev)
  865. {
  866. ivpu_pm_trigger_recovery(vdev, "WDT NCE IRQ");
  867. }
  868. static void irq_wdt_mss_handler(struct ivpu_device *vdev)
  869. {
  870. ivpu_hw_ip_wdt_disable(vdev);
  871. ivpu_pm_trigger_recovery(vdev, "WDT MSS IRQ");
  872. }
  873. static void irq_noc_firewall_handler(struct ivpu_device *vdev)
  874. {
  875. atomic_inc(&vdev->hw->firewall_irq_counter);
  876. ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n",
  877. atomic_read(&vdev->hw->firewall_irq_counter));
  878. }
  879. /* Handler for IRQs from NPU core */
  880. bool ivpu_hw_ip_irq_handler_37xx(struct ivpu_device *vdev, int irq)
  881. {
  882. u32 status = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_37XX;
  883. if (!status)
  884. return false;
  885. REGV_WR32(VPU_37XX_HOST_SS_ICB_CLEAR_0, status);
  886. if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))
  887. ivpu_mmu_irq_evtq_handler(vdev);
  888. if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
  889. ivpu_ipc_irq_handler(vdev);
  890. if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
  891. ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
  892. if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT, status))
  893. ivpu_mmu_irq_gerr_handler(vdev);
  894. if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, status))
  895. irq_wdt_mss_handler(vdev);
  896. if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, status))
  897. irq_wdt_nce_handler(vdev);
  898. if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
  899. irq_noc_firewall_handler(vdev);
  900. return true;
  901. }
  902. /* Handler for IRQs from NPU core */
  903. bool ivpu_hw_ip_irq_handler_40xx(struct ivpu_device *vdev, int irq)
  904. {
  905. u32 status = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_40XX;
  906. if (!status)
  907. return false;
  908. REGV_WR32(VPU_40XX_HOST_SS_ICB_CLEAR_0, status);
  909. if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))
  910. ivpu_mmu_irq_evtq_handler(vdev);
  911. if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
  912. ivpu_ipc_irq_handler(vdev);
  913. if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
  914. ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
  915. if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT, status))
  916. ivpu_mmu_irq_gerr_handler(vdev);
  917. if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, status))
  918. irq_wdt_mss_handler(vdev);
  919. if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, status))
  920. irq_wdt_nce_handler(vdev);
  921. if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
  922. irq_noc_firewall_handler(vdev);
  923. return true;
  924. }
  925. static void db_set_37xx(struct ivpu_device *vdev, u32 db_id)
  926. {
  927. u32 reg_stride = VPU_37XX_CPU_SS_DOORBELL_1 - VPU_37XX_CPU_SS_DOORBELL_0;
  928. u32 val = REG_FLD(VPU_37XX_CPU_SS_DOORBELL_0, SET);
  929. REGV_WR32I(VPU_37XX_CPU_SS_DOORBELL_0, reg_stride, db_id, val);
  930. }
  931. static void db_set_40xx(struct ivpu_device *vdev, u32 db_id)
  932. {
  933. u32 reg_stride = VPU_40XX_CPU_SS_DOORBELL_1 - VPU_40XX_CPU_SS_DOORBELL_0;
  934. u32 val = REG_FLD(VPU_40XX_CPU_SS_DOORBELL_0, SET);
  935. REGV_WR32I(VPU_40XX_CPU_SS_DOORBELL_0, reg_stride, db_id, val);
  936. }
  937. void ivpu_hw_ip_db_set(struct ivpu_device *vdev, u32 db_id)
  938. {
  939. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  940. db_set_37xx(vdev, db_id);
  941. else
  942. db_set_40xx(vdev, db_id);
  943. }
  944. u32 ivpu_hw_ip_ipc_rx_addr_get(struct ivpu_device *vdev)
  945. {
  946. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  947. return REGV_RD32(VPU_37XX_HOST_SS_TIM_IPC_FIFO_ATM);
  948. else
  949. return REGV_RD32(VPU_40XX_HOST_SS_TIM_IPC_FIFO_ATM);
  950. }
  951. void ivpu_hw_ip_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
  952. {
  953. if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
  954. REGV_WR32(VPU_37XX_CPU_SS_TIM_IPC_FIFO, vpu_addr);
  955. else
  956. REGV_WR32(VPU_40XX_CPU_SS_TIM_IPC_FIFO, vpu_addr);
  957. }