vce_v3_0.c 21 KB

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