vcn_v1_0.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. /*
  2. * Copyright 2016 Advanced Micro Devices, Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. */
  23. #include <linux/firmware.h>
  24. #include <drm/drmP.h>
  25. #include "amdgpu.h"
  26. #include "amdgpu_vcn.h"
  27. #include "soc15d.h"
  28. #include "soc15_common.h"
  29. #include "vega10/soc15ip.h"
  30. #include "raven1/VCN/vcn_1_0_offset.h"
  31. #include "raven1/VCN/vcn_1_0_sh_mask.h"
  32. #include "vega10/HDP/hdp_4_0_offset.h"
  33. #include "raven1/MMHUB/mmhub_9_1_offset.h"
  34. #include "raven1/MMHUB/mmhub_9_1_sh_mask.h"
  35. static int vcn_v1_0_start(struct amdgpu_device *adev);
  36. static int vcn_v1_0_stop(struct amdgpu_device *adev);
  37. static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
  38. static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev);
  39. /**
  40. * vcn_v1_0_early_init - set function pointers
  41. *
  42. * @handle: amdgpu_device pointer
  43. *
  44. * Set ring and irq function pointers
  45. */
  46. static int vcn_v1_0_early_init(void *handle)
  47. {
  48. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  49. vcn_v1_0_set_dec_ring_funcs(adev);
  50. vcn_v1_0_set_irq_funcs(adev);
  51. return 0;
  52. }
  53. /**
  54. * vcn_v1_0_sw_init - sw init for VCN block
  55. *
  56. * @handle: amdgpu_device pointer
  57. *
  58. * Load firmware and sw initialization
  59. */
  60. static int vcn_v1_0_sw_init(void *handle)
  61. {
  62. struct amdgpu_ring *ring;
  63. int r;
  64. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  65. /* VCN TRAP */
  66. r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_VCN, 124, &adev->vcn.irq);
  67. if (r)
  68. return r;
  69. r = amdgpu_vcn_sw_init(adev);
  70. if (r)
  71. return r;
  72. r = amdgpu_vcn_resume(adev);
  73. if (r)
  74. return r;
  75. ring = &adev->vcn.ring_dec;
  76. sprintf(ring->name, "vcn_dec");
  77. r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.irq, 0);
  78. return r;
  79. }
  80. /**
  81. * vcn_v1_0_sw_fini - sw fini for VCN block
  82. *
  83. * @handle: amdgpu_device pointer
  84. *
  85. * VCN suspend and free up sw allocation
  86. */
  87. static int vcn_v1_0_sw_fini(void *handle)
  88. {
  89. int r;
  90. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  91. r = amdgpu_vcn_suspend(adev);
  92. if (r)
  93. return r;
  94. r = amdgpu_vcn_sw_fini(adev);
  95. return r;
  96. }
  97. /**
  98. * vcn_v1_0_hw_init - start and test VCN block
  99. *
  100. * @handle: amdgpu_device pointer
  101. *
  102. * Initialize the hardware, boot up the VCPU and do some testing
  103. */
  104. static int vcn_v1_0_hw_init(void *handle)
  105. {
  106. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  107. struct amdgpu_ring *ring = &adev->vcn.ring_dec;
  108. int r;
  109. r = vcn_v1_0_start(adev);
  110. if (r)
  111. goto done;
  112. ring->ready = true;
  113. r = amdgpu_ring_test_ring(ring);
  114. if (r) {
  115. ring->ready = false;
  116. goto done;
  117. }
  118. done:
  119. if (!r)
  120. DRM_INFO("VCN decode initialized successfully.\n");
  121. return r;
  122. }
  123. /**
  124. * vcn_v1_0_hw_fini - stop the hardware block
  125. *
  126. * @handle: amdgpu_device pointer
  127. *
  128. * Stop the VCN block, mark ring as not ready any more
  129. */
  130. static int vcn_v1_0_hw_fini(void *handle)
  131. {
  132. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  133. struct amdgpu_ring *ring = &adev->vcn.ring_dec;
  134. int r;
  135. r = vcn_v1_0_stop(adev);
  136. if (r)
  137. return r;
  138. ring->ready = false;
  139. return 0;
  140. }
  141. /**
  142. * vcn_v1_0_suspend - suspend VCN block
  143. *
  144. * @handle: amdgpu_device pointer
  145. *
  146. * HW fini and suspend VCN block
  147. */
  148. static int vcn_v1_0_suspend(void *handle)
  149. {
  150. int r;
  151. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  152. r = vcn_v1_0_hw_fini(adev);
  153. if (r)
  154. return r;
  155. r = amdgpu_vcn_suspend(adev);
  156. return r;
  157. }
  158. /**
  159. * vcn_v1_0_resume - resume VCN block
  160. *
  161. * @handle: amdgpu_device pointer
  162. *
  163. * Resume firmware and hw init VCN block
  164. */
  165. static int vcn_v1_0_resume(void *handle)
  166. {
  167. int r;
  168. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  169. r = amdgpu_vcn_resume(adev);
  170. if (r)
  171. return r;
  172. r = vcn_v1_0_hw_init(adev);
  173. return r;
  174. }
  175. /**
  176. * vcn_v1_0_mc_resume - memory controller programming
  177. *
  178. * @adev: amdgpu_device pointer
  179. *
  180. * Let the VCN memory controller know it's offsets
  181. */
  182. static void vcn_v1_0_mc_resume(struct amdgpu_device *adev)
  183. {
  184. uint64_t offset;
  185. uint32_t size;
  186. /* programm memory controller bits 0-27 */
  187. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
  188. lower_32_bits(adev->vcn.gpu_addr));
  189. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
  190. upper_32_bits(adev->vcn.gpu_addr));
  191. /* Current FW has no signed header, but will be added later on */
  192. /* offset = AMDGPU_VCN_FIRMWARE_OFFSET; */
  193. offset = 0;
  194. size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
  195. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0), offset >> 3);
  196. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE0), size);
  197. offset += size;
  198. size = AMDGPU_VCN_HEAP_SIZE;
  199. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1), offset >> 3);
  200. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE1), size);
  201. offset += size;
  202. size = AMDGPU_VCN_STACK_SIZE + (AMDGPU_VCN_SESSION_SIZE * 40);
  203. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2), offset >> 3);
  204. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE2), size);
  205. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_UDEC_ADDR_CONFIG),
  206. adev->gfx.config.gb_addr_config);
  207. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG),
  208. adev->gfx.config.gb_addr_config);
  209. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG),
  210. adev->gfx.config.gb_addr_config);
  211. }
  212. /**
  213. * vcn_v1_0_start - start VCN block
  214. *
  215. * @adev: amdgpu_device pointer
  216. *
  217. * Setup and start the VCN block
  218. */
  219. static int vcn_v1_0_start(struct amdgpu_device *adev)
  220. {
  221. struct amdgpu_ring *ring = &adev->vcn.ring_dec;
  222. uint32_t rb_bufsz, tmp;
  223. uint32_t lmi_swap_cntl;
  224. int i, j, r;
  225. /* disable byte swapping */
  226. lmi_swap_cntl = 0;
  227. vcn_v1_0_mc_resume(adev);
  228. /* disable clock gating */
  229. WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_CGC_CTRL), 0,
  230. ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK);
  231. /* disable interupt */
  232. WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0,
  233. ~UVD_MASTINT_EN__VCPU_EN_MASK);
  234. /* stall UMC and register bus before resetting VCPU */
  235. WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
  236. UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
  237. ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
  238. mdelay(1);
  239. /* put LMI, VCPU, RBC etc... into reset */
  240. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
  241. UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
  242. UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK |
  243. UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK |
  244. UVD_SOFT_RESET__RBC_SOFT_RESET_MASK |
  245. UVD_SOFT_RESET__CSM_SOFT_RESET_MASK |
  246. UVD_SOFT_RESET__CXW_SOFT_RESET_MASK |
  247. UVD_SOFT_RESET__TAP_SOFT_RESET_MASK |
  248. UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
  249. mdelay(5);
  250. /* initialize VCN memory controller */
  251. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL),
  252. (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
  253. UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
  254. UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
  255. UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
  256. UVD_LMI_CTRL__REQ_MODE_MASK |
  257. 0x00100000L);
  258. #ifdef __BIG_ENDIAN
  259. /* swap (8 in 32) RB and IB */
  260. lmi_swap_cntl = 0xa;
  261. #endif
  262. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_SWAP_CNTL), lmi_swap_cntl);
  263. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXA0), 0x40c2040);
  264. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXA1), 0x0);
  265. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXB0), 0x40c2040);
  266. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXB1), 0x0);
  267. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_ALU), 0);
  268. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUX), 0x88);
  269. /* take all subblocks out of reset, except VCPU */
  270. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
  271. UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
  272. mdelay(5);
  273. /* enable VCPU clock */
  274. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL),
  275. UVD_VCPU_CNTL__CLK_EN_MASK);
  276. /* enable UMC */
  277. WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0,
  278. ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
  279. /* boot up the VCPU */
  280. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0);
  281. mdelay(10);
  282. for (i = 0; i < 10; ++i) {
  283. uint32_t status;
  284. for (j = 0; j < 100; ++j) {
  285. status = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS));
  286. if (status & 2)
  287. break;
  288. mdelay(10);
  289. }
  290. r = 0;
  291. if (status & 2)
  292. break;
  293. DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");
  294. WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
  295. UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,
  296. ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
  297. mdelay(10);
  298. WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0,
  299. ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
  300. mdelay(10);
  301. r = -1;
  302. }
  303. if (r) {
  304. DRM_ERROR("VCN decode not responding, giving up!!!\n");
  305. return r;
  306. }
  307. /* enable master interrupt */
  308. WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN),
  309. (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK),
  310. ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK));
  311. /* clear the bit 4 of VCN_STATUS */
  312. WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0,
  313. ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
  314. /* force RBC into idle state */
  315. rb_bufsz = order_base_2(ring->ring_size);
  316. tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
  317. tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
  318. tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
  319. tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0);
  320. tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
  321. tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
  322. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), tmp);
  323. /* set the write pointer delay */
  324. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL), 0);
  325. /* set the wb address */
  326. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_RPTR_ADDR),
  327. (upper_32_bits(ring->gpu_addr) >> 2));
  328. /* programm the RB_BASE for ring buffer */
  329. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW),
  330. lower_32_bits(ring->gpu_addr));
  331. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH),
  332. upper_32_bits(ring->gpu_addr));
  333. /* Initialize the ring buffer's read and write pointers */
  334. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_RPTR), 0);
  335. ring->wptr = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_RPTR));
  336. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_WPTR),
  337. lower_32_bits(ring->wptr));
  338. WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0,
  339. ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK);
  340. return 0;
  341. }
  342. /**
  343. * vcn_v1_0_stop - stop VCN block
  344. *
  345. * @adev: amdgpu_device pointer
  346. *
  347. * stop the VCN block
  348. */
  349. static int vcn_v1_0_stop(struct amdgpu_device *adev)
  350. {
  351. /* force RBC into idle state */
  352. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0x11010101);
  353. /* Stall UMC and register bus before resetting VCPU */
  354. WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
  355. UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
  356. ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
  357. mdelay(1);
  358. /* put VCPU into reset */
  359. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
  360. UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
  361. mdelay(5);
  362. /* disable VCPU clock */
  363. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL), 0x0);
  364. /* Unstall UMC and register bus */
  365. WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0,
  366. ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
  367. return 0;
  368. }
  369. static int vcn_v1_0_set_clockgating_state(void *handle,
  370. enum amd_clockgating_state state)
  371. {
  372. /* needed for driver unload*/
  373. return 0;
  374. }
  375. /**
  376. * vcn_v1_0_dec_ring_get_rptr - get read pointer
  377. *
  378. * @ring: amdgpu_ring pointer
  379. *
  380. * Returns the current hardware read pointer
  381. */
  382. static uint64_t vcn_v1_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
  383. {
  384. struct amdgpu_device *adev = ring->adev;
  385. return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_RPTR));
  386. }
  387. /**
  388. * vcn_v1_0_dec_ring_get_wptr - get write pointer
  389. *
  390. * @ring: amdgpu_ring pointer
  391. *
  392. * Returns the current hardware write pointer
  393. */
  394. static uint64_t vcn_v1_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
  395. {
  396. struct amdgpu_device *adev = ring->adev;
  397. return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_WPTR));
  398. }
  399. /**
  400. * vcn_v1_0_dec_ring_set_wptr - set write pointer
  401. *
  402. * @ring: amdgpu_ring pointer
  403. *
  404. * Commits the write pointer to the hardware
  405. */
  406. static void vcn_v1_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
  407. {
  408. struct amdgpu_device *adev = ring->adev;
  409. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_WPTR), lower_32_bits(ring->wptr));
  410. }
  411. /**
  412. * vcn_v1_0_dec_ring_emit_fence - emit an fence & trap command
  413. *
  414. * @ring: amdgpu_ring pointer
  415. * @fence: fence to emit
  416. *
  417. * Write a fence and a trap command to the ring.
  418. */
  419. static void vcn_v1_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
  420. unsigned flags)
  421. {
  422. WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
  423. amdgpu_ring_write(ring,
  424. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0));
  425. amdgpu_ring_write(ring, seq);
  426. amdgpu_ring_write(ring,
  427. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));
  428. amdgpu_ring_write(ring, addr & 0xffffffff);
  429. amdgpu_ring_write(ring,
  430. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));
  431. amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff);
  432. amdgpu_ring_write(ring,
  433. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));
  434. amdgpu_ring_write(ring, 0);
  435. amdgpu_ring_write(ring,
  436. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));
  437. amdgpu_ring_write(ring, 0);
  438. amdgpu_ring_write(ring,
  439. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));
  440. amdgpu_ring_write(ring, 0);
  441. amdgpu_ring_write(ring,
  442. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));
  443. amdgpu_ring_write(ring, 2);
  444. }
  445. /**
  446. * vcn_v1_0_dec_ring_hdp_invalidate - emit an hdp invalidate
  447. *
  448. * @ring: amdgpu_ring pointer
  449. *
  450. * Emits an hdp invalidate.
  451. */
  452. static void vcn_v1_0_dec_ring_emit_hdp_invalidate(struct amdgpu_ring *ring)
  453. {
  454. amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(HDP, 0, mmHDP_DEBUG0), 0));
  455. amdgpu_ring_write(ring, 1);
  456. }
  457. /**
  458. * vcn_v1_0_dec_ring_test_ring - register write test
  459. *
  460. * @ring: amdgpu_ring pointer
  461. *
  462. * Test if we can successfully write to the context register
  463. */
  464. static int vcn_v1_0_dec_ring_test_ring(struct amdgpu_ring *ring)
  465. {
  466. struct amdgpu_device *adev = ring->adev;
  467. uint32_t tmp = 0;
  468. unsigned i;
  469. int r;
  470. WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0xCAFEDEAD);
  471. r = amdgpu_ring_alloc(ring, 3);
  472. if (r) {
  473. DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n",
  474. ring->idx, r);
  475. return r;
  476. }
  477. amdgpu_ring_write(ring,
  478. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0));
  479. amdgpu_ring_write(ring, 0xDEADBEEF);
  480. amdgpu_ring_commit(ring);
  481. for (i = 0; i < adev->usec_timeout; i++) {
  482. tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID));
  483. if (tmp == 0xDEADBEEF)
  484. break;
  485. DRM_UDELAY(1);
  486. }
  487. if (i < adev->usec_timeout) {
  488. DRM_INFO("ring test on %d succeeded in %d usecs\n",
  489. ring->idx, i);
  490. } else {
  491. DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
  492. ring->idx, tmp);
  493. r = -EINVAL;
  494. }
  495. return r;
  496. }
  497. /**
  498. * vcn_v1_0_dec_ring_emit_ib - execute indirect buffer
  499. *
  500. * @ring: amdgpu_ring pointer
  501. * @ib: indirect buffer to execute
  502. *
  503. * Write ring commands to execute the indirect buffer
  504. */
  505. static void vcn_v1_0_dec_ring_emit_ib(struct amdgpu_ring *ring,
  506. struct amdgpu_ib *ib,
  507. unsigned vm_id, bool ctx_switch)
  508. {
  509. amdgpu_ring_write(ring,
  510. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_VMID), 0));
  511. amdgpu_ring_write(ring, vm_id);
  512. amdgpu_ring_write(ring,
  513. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0));
  514. amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
  515. amdgpu_ring_write(ring,
  516. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH), 0));
  517. amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
  518. amdgpu_ring_write(ring,
  519. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_IB_SIZE), 0));
  520. amdgpu_ring_write(ring, ib->length_dw);
  521. }
  522. static void vcn_v1_0_dec_vm_reg_write(struct amdgpu_ring *ring,
  523. uint32_t data0, uint32_t data1)
  524. {
  525. amdgpu_ring_write(ring,
  526. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));
  527. amdgpu_ring_write(ring, data0);
  528. amdgpu_ring_write(ring,
  529. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));
  530. amdgpu_ring_write(ring, data1);
  531. amdgpu_ring_write(ring,
  532. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));
  533. amdgpu_ring_write(ring, 8);
  534. }
  535. static void vcn_v1_0_dec_vm_reg_wait(struct amdgpu_ring *ring,
  536. uint32_t data0, uint32_t data1, uint32_t mask)
  537. {
  538. amdgpu_ring_write(ring,
  539. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));
  540. amdgpu_ring_write(ring, data0);
  541. amdgpu_ring_write(ring,
  542. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));
  543. amdgpu_ring_write(ring, data1);
  544. amdgpu_ring_write(ring,
  545. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GP_SCRATCH8), 0));
  546. amdgpu_ring_write(ring, mask);
  547. amdgpu_ring_write(ring,
  548. PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));
  549. amdgpu_ring_write(ring, 12);
  550. }
  551. static void vcn_v1_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring,
  552. unsigned vm_id, uint64_t pd_addr)
  553. {
  554. struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
  555. uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vm_id);
  556. uint32_t data0, data1, mask;
  557. unsigned eng = ring->vm_inv_eng;
  558. pd_addr = pd_addr | 0x1; /* valid bit */
  559. /* now only use physical base address of PDE and valid */
  560. BUG_ON(pd_addr & 0xFFFF00000000003EULL);
  561. data0 = (hub->ctx0_ptb_addr_hi32 + vm_id * 2) << 2;
  562. data1 = upper_32_bits(pd_addr);
  563. vcn_v1_0_dec_vm_reg_write(ring, data0, data1);
  564. data0 = (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2;
  565. data1 = lower_32_bits(pd_addr);
  566. vcn_v1_0_dec_vm_reg_write(ring, data0, data1);
  567. data0 = (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2;
  568. data1 = lower_32_bits(pd_addr);
  569. mask = 0xffffffff;
  570. vcn_v1_0_dec_vm_reg_wait(ring, data0, data1, mask);
  571. /* flush TLB */
  572. data0 = (hub->vm_inv_eng0_req + eng) << 2;
  573. data1 = req;
  574. vcn_v1_0_dec_vm_reg_write(ring, data0, data1);
  575. /* wait for flush */
  576. data0 = (hub->vm_inv_eng0_ack + eng) << 2;
  577. data1 = 1 << vm_id;
  578. mask = 1 << vm_id;
  579. vcn_v1_0_dec_vm_reg_wait(ring, data0, data1, mask);
  580. }
  581. static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev,
  582. struct amdgpu_irq_src *source,
  583. unsigned type,
  584. enum amdgpu_interrupt_state state)
  585. {
  586. return 0;
  587. }
  588. static int vcn_v1_0_process_interrupt(struct amdgpu_device *adev,
  589. struct amdgpu_irq_src *source,
  590. struct amdgpu_iv_entry *entry)
  591. {
  592. DRM_DEBUG("IH: VCN TRAP\n");
  593. amdgpu_fence_process(&adev->vcn.ring_dec);
  594. return 0;
  595. }
  596. static const struct amd_ip_funcs vcn_v1_0_ip_funcs = {
  597. .name = "vcn_v1_0",
  598. .early_init = vcn_v1_0_early_init,
  599. .late_init = NULL,
  600. .sw_init = vcn_v1_0_sw_init,
  601. .sw_fini = vcn_v1_0_sw_fini,
  602. .hw_init = vcn_v1_0_hw_init,
  603. .hw_fini = vcn_v1_0_hw_fini,
  604. .suspend = vcn_v1_0_suspend,
  605. .resume = vcn_v1_0_resume,
  606. .is_idle = NULL /* vcn_v1_0_is_idle */,
  607. .wait_for_idle = NULL /* vcn_v1_0_wait_for_idle */,
  608. .check_soft_reset = NULL /* vcn_v1_0_check_soft_reset */,
  609. .pre_soft_reset = NULL /* vcn_v1_0_pre_soft_reset */,
  610. .soft_reset = NULL /* vcn_v1_0_soft_reset */,
  611. .post_soft_reset = NULL /* vcn_v1_0_post_soft_reset */,
  612. .set_clockgating_state = vcn_v1_0_set_clockgating_state,
  613. .set_powergating_state = NULL /* vcn_v1_0_set_powergating_state */,
  614. };
  615. static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = {
  616. .type = AMDGPU_RING_TYPE_VCN_DEC,
  617. .align_mask = 0xf,
  618. .nop = PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP), 0),
  619. .support_64bit_ptrs = false,
  620. .get_rptr = vcn_v1_0_dec_ring_get_rptr,
  621. .get_wptr = vcn_v1_0_dec_ring_get_wptr,
  622. .set_wptr = vcn_v1_0_dec_ring_set_wptr,
  623. .emit_frame_size =
  624. 2 + /* vcn_v1_0_dec_ring_emit_hdp_invalidate */
  625. 34 * AMDGPU_MAX_VMHUBS + /* vcn_v1_0_dec_ring_emit_vm_flush */
  626. 14 + 14, /* vcn_v1_0_dec_ring_emit_fence x2 vm fence */
  627. .emit_ib_size = 8, /* vcn_v1_0_dec_ring_emit_ib */
  628. .emit_ib = vcn_v1_0_dec_ring_emit_ib,
  629. .emit_fence = vcn_v1_0_dec_ring_emit_fence,
  630. .emit_vm_flush = vcn_v1_0_dec_ring_emit_vm_flush,
  631. .emit_hdp_invalidate = vcn_v1_0_dec_ring_emit_hdp_invalidate,
  632. .test_ring = vcn_v1_0_dec_ring_test_ring,
  633. .test_ib = amdgpu_vcn_dec_ring_test_ib,
  634. .insert_nop = amdgpu_ring_insert_nop,
  635. .pad_ib = amdgpu_ring_generic_pad_ib,
  636. .begin_use = amdgpu_vcn_ring_begin_use,
  637. .end_use = amdgpu_vcn_ring_end_use,
  638. };
  639. static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev)
  640. {
  641. adev->vcn.ring_dec.funcs = &vcn_v1_0_dec_ring_vm_funcs;
  642. DRM_INFO("VCN decode is enabled in VM mode\n");
  643. }
  644. static const struct amdgpu_irq_src_funcs vcn_v1_0_irq_funcs = {
  645. .set = vcn_v1_0_set_interrupt_state,
  646. .process = vcn_v1_0_process_interrupt,
  647. };
  648. static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev)
  649. {
  650. adev->vcn.irq.num_types = 1;
  651. adev->vcn.irq.funcs = &vcn_v1_0_irq_funcs;
  652. }
  653. const struct amdgpu_ip_block_version vcn_v1_0_ip_block =
  654. {
  655. .type = AMD_IP_BLOCK_TYPE_VCN,
  656. .major = 1,
  657. .minor = 0,
  658. .rev = 0,
  659. .funcs = &vcn_v1_0_ip_funcs,
  660. };