vce_v3_0.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. /*
  2. * Copyright 2014 Advanced Micro Devices, Inc.
  3. * All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sub license, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  16. * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  17. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  18. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  19. * USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. *
  21. * The above copyright notice and this permission notice (including the
  22. * next paragraph) shall be included in all copies or substantial portions
  23. * of the Software.
  24. *
  25. * Authors: Christian König <christian.koenig@amd.com>
  26. */
  27. #include <linux/firmware.h>
  28. #include <drm/drmP.h>
  29. #include "amdgpu.h"
  30. #include "amdgpu_vce.h"
  31. #include "vid.h"
  32. #include "vce/vce_3_0_d.h"
  33. #include "vce/vce_3_0_sh_mask.h"
  34. #include "oss/oss_3_0_d.h"
  35. #include "oss/oss_3_0_sh_mask.h"
  36. #include "gca/gfx_8_0_d.h"
  37. #include "smu/smu_7_1_2_d.h"
  38. #include "smu/smu_7_1_2_sh_mask.h"
  39. #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04
  40. #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10
  41. #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR0 0x8616
  42. #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR1 0x8617
  43. #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR2 0x8618
  44. #define VCE_V3_0_FW_SIZE (384 * 1024)
  45. #define VCE_V3_0_STACK_SIZE (64 * 1024)
  46. #define VCE_V3_0_DATA_SIZE ((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024))
  47. static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx);
  48. static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev);
  49. static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev);
  50. /**
  51. * vce_v3_0_ring_get_rptr - get read pointer
  52. *
  53. * @ring: amdgpu_ring pointer
  54. *
  55. * Returns the current hardware read pointer
  56. */
  57. static uint32_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring)
  58. {
  59. struct amdgpu_device *adev = ring->adev;
  60. if (ring == &adev->vce.ring[0])
  61. return RREG32(mmVCE_RB_RPTR);
  62. else
  63. return RREG32(mmVCE_RB_RPTR2);
  64. }
  65. /**
  66. * vce_v3_0_ring_get_wptr - get write pointer
  67. *
  68. * @ring: amdgpu_ring pointer
  69. *
  70. * Returns the current hardware write pointer
  71. */
  72. static uint32_t vce_v3_0_ring_get_wptr(struct amdgpu_ring *ring)
  73. {
  74. struct amdgpu_device *adev = ring->adev;
  75. if (ring == &adev->vce.ring[0])
  76. return RREG32(mmVCE_RB_WPTR);
  77. else
  78. return RREG32(mmVCE_RB_WPTR2);
  79. }
  80. /**
  81. * vce_v3_0_ring_set_wptr - set write pointer
  82. *
  83. * @ring: amdgpu_ring pointer
  84. *
  85. * Commits the write pointer to the hardware
  86. */
  87. static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring)
  88. {
  89. struct amdgpu_device *adev = ring->adev;
  90. if (ring == &adev->vce.ring[0])
  91. WREG32(mmVCE_RB_WPTR, ring->wptr);
  92. else
  93. WREG32(mmVCE_RB_WPTR2, ring->wptr);
  94. }
  95. static void vce_v3_0_override_vce_clock_gating(struct amdgpu_device *adev, bool override)
  96. {
  97. u32 tmp, data;
  98. tmp = data = RREG32(mmVCE_RB_ARB_CTRL);
  99. if (override)
  100. data |= VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK;
  101. else
  102. data &= ~VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK;
  103. if (tmp != data)
  104. WREG32(mmVCE_RB_ARB_CTRL, data);
  105. }
  106. static void vce_v3_0_set_vce_sw_clock_gating(struct amdgpu_device *adev,
  107. bool gated)
  108. {
  109. u32 tmp, data;
  110. /* Set Override to disable Clock Gating */
  111. vce_v3_0_override_vce_clock_gating(adev, true);
  112. if (!gated) {
  113. /* Force CLOCK ON for VCE_CLOCK_GATING_B,
  114. * {*_FORCE_ON, *_FORCE_OFF} = {1, 0}
  115. * VREG can be FORCE ON or set to Dynamic, but can't be OFF
  116. */
  117. tmp = data = RREG32(mmVCE_CLOCK_GATING_B);
  118. data |= 0x1ff;
  119. data &= ~0xef0000;
  120. if (tmp != data)
  121. WREG32(mmVCE_CLOCK_GATING_B, data);
  122. /* Force CLOCK ON for VCE_UENC_CLOCK_GATING,
  123. * {*_FORCE_ON, *_FORCE_OFF} = {1, 0}
  124. */
  125. tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING);
  126. data |= 0x3ff000;
  127. data &= ~0xffc00000;
  128. if (tmp != data)
  129. WREG32(mmVCE_UENC_CLOCK_GATING, data);
  130. /* set VCE_UENC_CLOCK_GATING_2 */
  131. tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2);
  132. data |= 0x2;
  133. data &= ~0x2;
  134. if (tmp != data)
  135. WREG32(mmVCE_UENC_CLOCK_GATING_2, data);
  136. /* Force CLOCK ON for VCE_UENC_REG_CLOCK_GATING */
  137. tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
  138. data |= 0x37f;
  139. if (tmp != data)
  140. WREG32(mmVCE_UENC_REG_CLOCK_GATING, data);
  141. /* Force VCE_UENC_DMA_DCLK_CTRL Clock ON */
  142. tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL);
  143. data |= VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK |
  144. VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK |
  145. VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK |
  146. 0x8;
  147. if (tmp != data)
  148. WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data);
  149. } else {
  150. /* Force CLOCK OFF for VCE_CLOCK_GATING_B,
  151. * {*, *_FORCE_OFF} = {*, 1}
  152. * set VREG to Dynamic, as it can't be OFF
  153. */
  154. tmp = data = RREG32(mmVCE_CLOCK_GATING_B);
  155. data &= ~0x80010;
  156. data |= 0xe70008;
  157. if (tmp != data)
  158. WREG32(mmVCE_CLOCK_GATING_B, data);
  159. /* Force CLOCK OFF for VCE_UENC_CLOCK_GATING,
  160. * Force ClOCK OFF takes precedent over Force CLOCK ON setting.
  161. * {*_FORCE_ON, *_FORCE_OFF} = {*, 1}
  162. */
  163. tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING);
  164. data |= 0xffc00000;
  165. if (tmp != data)
  166. WREG32(mmVCE_UENC_CLOCK_GATING, data);
  167. /* Set VCE_UENC_CLOCK_GATING_2 */
  168. tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2);
  169. data |= 0x10000;
  170. if (tmp != data)
  171. WREG32(mmVCE_UENC_CLOCK_GATING_2, data);
  172. /* Set VCE_UENC_REG_CLOCK_GATING to dynamic */
  173. tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
  174. data &= ~0xffc00000;
  175. if (tmp != data)
  176. WREG32(mmVCE_UENC_REG_CLOCK_GATING, data);
  177. /* Set VCE_UENC_DMA_DCLK_CTRL CG always in dynamic mode */
  178. tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL);
  179. data &= ~(VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK |
  180. VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK |
  181. VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK |
  182. 0x8);
  183. if (tmp != data)
  184. WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data);
  185. }
  186. vce_v3_0_override_vce_clock_gating(adev, false);
  187. }
  188. /**
  189. * vce_v3_0_start - start VCE block
  190. *
  191. * @adev: amdgpu_device pointer
  192. *
  193. * Setup and start the VCE block
  194. */
  195. static int vce_v3_0_start(struct amdgpu_device *adev)
  196. {
  197. struct amdgpu_ring *ring;
  198. int idx, i, j, r;
  199. mutex_lock(&adev->grbm_idx_mutex);
  200. for (idx = 0; idx < 2; ++idx) {
  201. if (adev->vce.harvest_config & (1 << idx))
  202. continue;
  203. if (idx == 0)
  204. WREG32_P(mmGRBM_GFX_INDEX, 0,
  205. ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
  206. else
  207. WREG32_P(mmGRBM_GFX_INDEX,
  208. GRBM_GFX_INDEX__VCE_INSTANCE_MASK,
  209. ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
  210. vce_v3_0_mc_resume(adev, idx);
  211. /* set BUSY flag */
  212. WREG32_P(mmVCE_STATUS, 1, ~1);
  213. if (adev->asic_type >= CHIP_STONEY)
  214. WREG32_P(mmVCE_VCPU_CNTL, 1, ~0x200001);
  215. else
  216. WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK,
  217. ~VCE_VCPU_CNTL__CLK_EN_MASK);
  218. WREG32_P(mmVCE_SOFT_RESET,
  219. VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
  220. ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
  221. mdelay(100);
  222. WREG32_P(mmVCE_SOFT_RESET, 0,
  223. ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
  224. for (i = 0; i < 10; ++i) {
  225. uint32_t status;
  226. for (j = 0; j < 100; ++j) {
  227. status = RREG32(mmVCE_STATUS);
  228. if (status & 2)
  229. break;
  230. mdelay(10);
  231. }
  232. r = 0;
  233. if (status & 2)
  234. break;
  235. DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
  236. WREG32_P(mmVCE_SOFT_RESET,
  237. VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
  238. ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
  239. mdelay(10);
  240. WREG32_P(mmVCE_SOFT_RESET, 0,
  241. ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
  242. mdelay(10);
  243. r = -1;
  244. }
  245. /* clear BUSY flag */
  246. WREG32_P(mmVCE_STATUS, 0, ~1);
  247. /* Set Clock-Gating off */
  248. if (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)
  249. vce_v3_0_set_vce_sw_clock_gating(adev, false);
  250. if (r) {
  251. DRM_ERROR("VCE not responding, giving up!!!\n");
  252. mutex_unlock(&adev->grbm_idx_mutex);
  253. return r;
  254. }
  255. }
  256. WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
  257. mutex_unlock(&adev->grbm_idx_mutex);
  258. ring = &adev->vce.ring[0];
  259. WREG32(mmVCE_RB_RPTR, ring->wptr);
  260. WREG32(mmVCE_RB_WPTR, ring->wptr);
  261. WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
  262. WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
  263. WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
  264. ring = &adev->vce.ring[1];
  265. WREG32(mmVCE_RB_RPTR2, ring->wptr);
  266. WREG32(mmVCE_RB_WPTR2, ring->wptr);
  267. WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
  268. WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
  269. WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
  270. return 0;
  271. }
  272. #define ixVCE_HARVEST_FUSE_MACRO__ADDRESS 0xC0014074
  273. #define VCE_HARVEST_FUSE_MACRO__SHIFT 27
  274. #define VCE_HARVEST_FUSE_MACRO__MASK 0x18000000
  275. static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev)
  276. {
  277. u32 tmp;
  278. /* Fiji, Stoney are single pipe */
  279. if ((adev->asic_type == CHIP_FIJI) ||
  280. (adev->asic_type == CHIP_STONEY))
  281. return AMDGPU_VCE_HARVEST_VCE1;
  282. /* Tonga and CZ are dual or single pipe */
  283. if (adev->flags & AMD_IS_APU)
  284. tmp = (RREG32_SMC(ixVCE_HARVEST_FUSE_MACRO__ADDRESS) &
  285. VCE_HARVEST_FUSE_MACRO__MASK) >>
  286. VCE_HARVEST_FUSE_MACRO__SHIFT;
  287. else
  288. tmp = (RREG32_SMC(ixCC_HARVEST_FUSES) &
  289. CC_HARVEST_FUSES__VCE_DISABLE_MASK) >>
  290. CC_HARVEST_FUSES__VCE_DISABLE__SHIFT;
  291. switch (tmp) {
  292. case 1:
  293. return AMDGPU_VCE_HARVEST_VCE0;
  294. case 2:
  295. return AMDGPU_VCE_HARVEST_VCE1;
  296. case 3:
  297. return AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1;
  298. default:
  299. return 0;
  300. }
  301. }
  302. static int vce_v3_0_early_init(void *handle)
  303. {
  304. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  305. adev->vce.harvest_config = vce_v3_0_get_harvest_config(adev);
  306. if ((adev->vce.harvest_config &
  307. (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1)) ==
  308. (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1))
  309. return -ENOENT;
  310. vce_v3_0_set_ring_funcs(adev);
  311. vce_v3_0_set_irq_funcs(adev);
  312. return 0;
  313. }
  314. static int vce_v3_0_sw_init(void *handle)
  315. {
  316. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  317. struct amdgpu_ring *ring;
  318. int r;
  319. /* VCE */
  320. r = amdgpu_irq_add_id(adev, 167, &adev->vce.irq);
  321. if (r)
  322. return r;
  323. r = amdgpu_vce_sw_init(adev, VCE_V3_0_FW_SIZE +
  324. (VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE) * 2);
  325. if (r)
  326. return r;
  327. r = amdgpu_vce_resume(adev);
  328. if (r)
  329. return r;
  330. ring = &adev->vce.ring[0];
  331. sprintf(ring->name, "vce0");
  332. r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf,
  333. &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE);
  334. if (r)
  335. return r;
  336. ring = &adev->vce.ring[1];
  337. sprintf(ring->name, "vce1");
  338. r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf,
  339. &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE);
  340. if (r)
  341. return r;
  342. return r;
  343. }
  344. static int vce_v3_0_sw_fini(void *handle)
  345. {
  346. int r;
  347. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  348. r = amdgpu_vce_suspend(adev);
  349. if (r)
  350. return r;
  351. r = amdgpu_vce_sw_fini(adev);
  352. if (r)
  353. return r;
  354. return r;
  355. }
  356. static int vce_v3_0_hw_init(void *handle)
  357. {
  358. int r, i;
  359. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  360. r = vce_v3_0_start(adev);
  361. if (r)
  362. return r;
  363. adev->vce.ring[0].ready = false;
  364. adev->vce.ring[1].ready = false;
  365. for (i = 0; i < 2; i++) {
  366. r = amdgpu_ring_test_ring(&adev->vce.ring[i]);
  367. if (r)
  368. return r;
  369. else
  370. adev->vce.ring[i].ready = true;
  371. }
  372. DRM_INFO("VCE initialized successfully.\n");
  373. return 0;
  374. }
  375. static int vce_v3_0_hw_fini(void *handle)
  376. {
  377. return 0;
  378. }
  379. static int vce_v3_0_suspend(void *handle)
  380. {
  381. int r;
  382. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  383. r = vce_v3_0_hw_fini(adev);
  384. if (r)
  385. return r;
  386. r = amdgpu_vce_suspend(adev);
  387. if (r)
  388. return r;
  389. return r;
  390. }
  391. static int vce_v3_0_resume(void *handle)
  392. {
  393. int r;
  394. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  395. r = amdgpu_vce_resume(adev);
  396. if (r)
  397. return r;
  398. r = vce_v3_0_hw_init(adev);
  399. if (r)
  400. return r;
  401. return r;
  402. }
  403. static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx)
  404. {
  405. uint32_t offset, size;
  406. WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16));
  407. WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
  408. WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
  409. WREG32(mmVCE_CLOCK_GATING_B, 0xf7);
  410. WREG32(mmVCE_LMI_CTRL, 0x00398000);
  411. WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1);
  412. WREG32(mmVCE_LMI_SWAP_CNTL, 0);
  413. WREG32(mmVCE_LMI_SWAP_CNTL1, 0);
  414. WREG32(mmVCE_LMI_VM_CTRL, 0);
  415. if (adev->asic_type >= CHIP_STONEY) {
  416. WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR0, (adev->vce.gpu_addr >> 8));
  417. WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR1, (adev->vce.gpu_addr >> 8));
  418. WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR2, (adev->vce.gpu_addr >> 8));
  419. } else
  420. WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8));
  421. offset = AMDGPU_VCE_FIRMWARE_OFFSET;
  422. size = VCE_V3_0_FW_SIZE;
  423. WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff);
  424. WREG32(mmVCE_VCPU_CACHE_SIZE0, size);
  425. if (idx == 0) {
  426. offset += size;
  427. size = VCE_V3_0_STACK_SIZE;
  428. WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff);
  429. WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
  430. offset += size;
  431. size = VCE_V3_0_DATA_SIZE;
  432. WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff);
  433. WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
  434. } else {
  435. offset += size + VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE;
  436. size = VCE_V3_0_STACK_SIZE;
  437. WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0xfffffff);
  438. WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
  439. offset += size;
  440. size = VCE_V3_0_DATA_SIZE;
  441. WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0xfffffff);
  442. WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
  443. }
  444. WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
  445. WREG32_P(mmVCE_SYS_INT_EN, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK,
  446. ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
  447. }
  448. static bool vce_v3_0_is_idle(void *handle)
  449. {
  450. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  451. u32 mask = 0;
  452. mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE0) ? 0 : SRBM_STATUS2__VCE0_BUSY_MASK;
  453. mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE1) ? 0 : SRBM_STATUS2__VCE1_BUSY_MASK;
  454. return !(RREG32(mmSRBM_STATUS2) & mask);
  455. }
  456. static int vce_v3_0_wait_for_idle(void *handle)
  457. {
  458. unsigned i;
  459. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  460. for (i = 0; i < adev->usec_timeout; i++)
  461. if (vce_v3_0_is_idle(handle))
  462. return 0;
  463. return -ETIMEDOUT;
  464. }
  465. static int vce_v3_0_soft_reset(void *handle)
  466. {
  467. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  468. u32 mask = 0;
  469. mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE0) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK;
  470. mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE1) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK;
  471. WREG32_P(mmSRBM_SOFT_RESET, mask,
  472. ~(SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK |
  473. SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK));
  474. mdelay(5);
  475. return vce_v3_0_start(adev);
  476. }
  477. static void vce_v3_0_print_status(void *handle)
  478. {
  479. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  480. dev_info(adev->dev, "VCE 3.0 registers\n");
  481. dev_info(adev->dev, " VCE_STATUS=0x%08X\n",
  482. RREG32(mmVCE_STATUS));
  483. dev_info(adev->dev, " VCE_VCPU_CNTL=0x%08X\n",
  484. RREG32(mmVCE_VCPU_CNTL));
  485. dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET0=0x%08X\n",
  486. RREG32(mmVCE_VCPU_CACHE_OFFSET0));
  487. dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE0=0x%08X\n",
  488. RREG32(mmVCE_VCPU_CACHE_SIZE0));
  489. dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET1=0x%08X\n",
  490. RREG32(mmVCE_VCPU_CACHE_OFFSET1));
  491. dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE1=0x%08X\n",
  492. RREG32(mmVCE_VCPU_CACHE_SIZE1));
  493. dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET2=0x%08X\n",
  494. RREG32(mmVCE_VCPU_CACHE_OFFSET2));
  495. dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE2=0x%08X\n",
  496. RREG32(mmVCE_VCPU_CACHE_SIZE2));
  497. dev_info(adev->dev, " VCE_SOFT_RESET=0x%08X\n",
  498. RREG32(mmVCE_SOFT_RESET));
  499. dev_info(adev->dev, " VCE_RB_BASE_LO2=0x%08X\n",
  500. RREG32(mmVCE_RB_BASE_LO2));
  501. dev_info(adev->dev, " VCE_RB_BASE_HI2=0x%08X\n",
  502. RREG32(mmVCE_RB_BASE_HI2));
  503. dev_info(adev->dev, " VCE_RB_SIZE2=0x%08X\n",
  504. RREG32(mmVCE_RB_SIZE2));
  505. dev_info(adev->dev, " VCE_RB_RPTR2=0x%08X\n",
  506. RREG32(mmVCE_RB_RPTR2));
  507. dev_info(adev->dev, " VCE_RB_WPTR2=0x%08X\n",
  508. RREG32(mmVCE_RB_WPTR2));
  509. dev_info(adev->dev, " VCE_RB_BASE_LO=0x%08X\n",
  510. RREG32(mmVCE_RB_BASE_LO));
  511. dev_info(adev->dev, " VCE_RB_BASE_HI=0x%08X\n",
  512. RREG32(mmVCE_RB_BASE_HI));
  513. dev_info(adev->dev, " VCE_RB_SIZE=0x%08X\n",
  514. RREG32(mmVCE_RB_SIZE));
  515. dev_info(adev->dev, " VCE_RB_RPTR=0x%08X\n",
  516. RREG32(mmVCE_RB_RPTR));
  517. dev_info(adev->dev, " VCE_RB_WPTR=0x%08X\n",
  518. RREG32(mmVCE_RB_WPTR));
  519. dev_info(adev->dev, " VCE_CLOCK_GATING_A=0x%08X\n",
  520. RREG32(mmVCE_CLOCK_GATING_A));
  521. dev_info(adev->dev, " VCE_CLOCK_GATING_B=0x%08X\n",
  522. RREG32(mmVCE_CLOCK_GATING_B));
  523. dev_info(adev->dev, " VCE_UENC_CLOCK_GATING=0x%08X\n",
  524. RREG32(mmVCE_UENC_CLOCK_GATING));
  525. dev_info(adev->dev, " VCE_UENC_REG_CLOCK_GATING=0x%08X\n",
  526. RREG32(mmVCE_UENC_REG_CLOCK_GATING));
  527. dev_info(adev->dev, " VCE_SYS_INT_EN=0x%08X\n",
  528. RREG32(mmVCE_SYS_INT_EN));
  529. dev_info(adev->dev, " VCE_LMI_CTRL2=0x%08X\n",
  530. RREG32(mmVCE_LMI_CTRL2));
  531. dev_info(adev->dev, " VCE_LMI_CTRL=0x%08X\n",
  532. RREG32(mmVCE_LMI_CTRL));
  533. dev_info(adev->dev, " VCE_LMI_VM_CTRL=0x%08X\n",
  534. RREG32(mmVCE_LMI_VM_CTRL));
  535. dev_info(adev->dev, " VCE_LMI_SWAP_CNTL=0x%08X\n",
  536. RREG32(mmVCE_LMI_SWAP_CNTL));
  537. dev_info(adev->dev, " VCE_LMI_SWAP_CNTL1=0x%08X\n",
  538. RREG32(mmVCE_LMI_SWAP_CNTL1));
  539. dev_info(adev->dev, " VCE_LMI_CACHE_CTRL=0x%08X\n",
  540. RREG32(mmVCE_LMI_CACHE_CTRL));
  541. }
  542. static int vce_v3_0_set_interrupt_state(struct amdgpu_device *adev,
  543. struct amdgpu_irq_src *source,
  544. unsigned type,
  545. enum amdgpu_interrupt_state state)
  546. {
  547. uint32_t val = 0;
  548. if (state == AMDGPU_IRQ_STATE_ENABLE)
  549. val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK;
  550. WREG32_P(mmVCE_SYS_INT_EN, val, ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
  551. return 0;
  552. }
  553. static int vce_v3_0_process_interrupt(struct amdgpu_device *adev,
  554. struct amdgpu_irq_src *source,
  555. struct amdgpu_iv_entry *entry)
  556. {
  557. DRM_DEBUG("IH: VCE\n");
  558. WREG32_P(mmVCE_SYS_INT_STATUS,
  559. VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK,
  560. ~VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK);
  561. switch (entry->src_data) {
  562. case 0:
  563. case 1:
  564. amdgpu_fence_process(&adev->vce.ring[entry->src_data]);
  565. break;
  566. default:
  567. DRM_ERROR("Unhandled interrupt: %d %d\n",
  568. entry->src_id, entry->src_data);
  569. break;
  570. }
  571. return 0;
  572. }
  573. static int vce_v3_0_set_clockgating_state(void *handle,
  574. enum amd_clockgating_state state)
  575. {
  576. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  577. bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
  578. int i;
  579. if (!(adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG))
  580. return 0;
  581. mutex_lock(&adev->grbm_idx_mutex);
  582. for (i = 0; i < 2; i++) {
  583. /* Program VCE Instance 0 or 1 if not harvested */
  584. if (adev->vce.harvest_config & (1 << i))
  585. continue;
  586. if (i == 0)
  587. WREG32_P(mmGRBM_GFX_INDEX, 0,
  588. ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
  589. else
  590. WREG32_P(mmGRBM_GFX_INDEX,
  591. GRBM_GFX_INDEX__VCE_INSTANCE_MASK,
  592. ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
  593. if (enable) {
  594. /* initialize VCE_CLOCK_GATING_A: Clock ON/OFF delay */
  595. uint32_t data = RREG32(mmVCE_CLOCK_GATING_A);
  596. data &= ~(0xf | 0xff0);
  597. data |= ((0x0 << 0) | (0x04 << 4));
  598. WREG32(mmVCE_CLOCK_GATING_A, data);
  599. /* initialize VCE_UENC_CLOCK_GATING: Clock ON/OFF delay */
  600. data = RREG32(mmVCE_UENC_CLOCK_GATING);
  601. data &= ~(0xf | 0xff0);
  602. data |= ((0x0 << 0) | (0x04 << 4));
  603. WREG32(mmVCE_UENC_CLOCK_GATING, data);
  604. }
  605. vce_v3_0_set_vce_sw_clock_gating(adev, enable);
  606. }
  607. WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
  608. mutex_unlock(&adev->grbm_idx_mutex);
  609. return 0;
  610. }
  611. static int vce_v3_0_set_powergating_state(void *handle,
  612. enum amd_powergating_state state)
  613. {
  614. /* This doesn't actually powergate the VCE block.
  615. * That's done in the dpm code via the SMC. This
  616. * just re-inits the block as necessary. The actual
  617. * gating still happens in the dpm code. We should
  618. * revisit this when there is a cleaner line between
  619. * the smc and the hw blocks
  620. */
  621. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  622. if (!(adev->pg_flags & AMD_PG_SUPPORT_VCE))
  623. return 0;
  624. if (state == AMD_PG_STATE_GATE)
  625. /* XXX do we need a vce_v3_0_stop()? */
  626. return 0;
  627. else
  628. return vce_v3_0_start(adev);
  629. }
  630. const struct amd_ip_funcs vce_v3_0_ip_funcs = {
  631. .early_init = vce_v3_0_early_init,
  632. .late_init = NULL,
  633. .sw_init = vce_v3_0_sw_init,
  634. .sw_fini = vce_v3_0_sw_fini,
  635. .hw_init = vce_v3_0_hw_init,
  636. .hw_fini = vce_v3_0_hw_fini,
  637. .suspend = vce_v3_0_suspend,
  638. .resume = vce_v3_0_resume,
  639. .is_idle = vce_v3_0_is_idle,
  640. .wait_for_idle = vce_v3_0_wait_for_idle,
  641. .soft_reset = vce_v3_0_soft_reset,
  642. .print_status = vce_v3_0_print_status,
  643. .set_clockgating_state = vce_v3_0_set_clockgating_state,
  644. .set_powergating_state = vce_v3_0_set_powergating_state,
  645. };
  646. static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = {
  647. .get_rptr = vce_v3_0_ring_get_rptr,
  648. .get_wptr = vce_v3_0_ring_get_wptr,
  649. .set_wptr = vce_v3_0_ring_set_wptr,
  650. .parse_cs = amdgpu_vce_ring_parse_cs,
  651. .emit_ib = amdgpu_vce_ring_emit_ib,
  652. .emit_fence = amdgpu_vce_ring_emit_fence,
  653. .test_ring = amdgpu_vce_ring_test_ring,
  654. .test_ib = amdgpu_vce_ring_test_ib,
  655. .insert_nop = amdgpu_ring_insert_nop,
  656. .pad_ib = amdgpu_ring_generic_pad_ib,
  657. };
  658. static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev)
  659. {
  660. adev->vce.ring[0].funcs = &vce_v3_0_ring_funcs;
  661. adev->vce.ring[1].funcs = &vce_v3_0_ring_funcs;
  662. }
  663. static const struct amdgpu_irq_src_funcs vce_v3_0_irq_funcs = {
  664. .set = vce_v3_0_set_interrupt_state,
  665. .process = vce_v3_0_process_interrupt,
  666. };
  667. static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev)
  668. {
  669. adev->vce.irq.num_types = 1;
  670. adev->vce.irq.funcs = &vce_v3_0_irq_funcs;
  671. };