uvd_v7_0.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889
  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_uvd.h"
  27. #include "soc15.h"
  28. #include "soc15d.h"
  29. #include "soc15_common.h"
  30. #include "mmsch_v1_0.h"
  31. #include "uvd/uvd_7_0_offset.h"
  32. #include "uvd/uvd_7_0_sh_mask.h"
  33. #include "vce/vce_4_0_offset.h"
  34. #include "vce/vce_4_0_default.h"
  35. #include "vce/vce_4_0_sh_mask.h"
  36. #include "nbif/nbif_6_1_offset.h"
  37. #include "hdp/hdp_4_0_offset.h"
  38. #include "mmhub/mmhub_1_0_offset.h"
  39. #include "mmhub/mmhub_1_0_sh_mask.h"
  40. #include "ivsrcid/uvd/irqsrcs_uvd_7_0.h"
  41. #define mmUVD_PG0_CC_UVD_HARVESTING 0x00c7
  42. #define mmUVD_PG0_CC_UVD_HARVESTING_BASE_IDX 1
  43. //UVD_PG0_CC_UVD_HARVESTING
  44. #define UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE__SHIFT 0x1
  45. #define UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE_MASK 0x00000002L
  46. #define UVD7_MAX_HW_INSTANCES_VEGA20 2
  47. static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev);
  48. static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev);
  49. static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev);
  50. static int uvd_v7_0_start(struct amdgpu_device *adev);
  51. static void uvd_v7_0_stop(struct amdgpu_device *adev);
  52. static int uvd_v7_0_sriov_start(struct amdgpu_device *adev);
  53. static int amdgpu_ih_clientid_uvds[] = {
  54. SOC15_IH_CLIENTID_UVD,
  55. SOC15_IH_CLIENTID_UVD1
  56. };
  57. /**
  58. * uvd_v7_0_ring_get_rptr - get read pointer
  59. *
  60. * @ring: amdgpu_ring pointer
  61. *
  62. * Returns the current hardware read pointer
  63. */
  64. static uint64_t uvd_v7_0_ring_get_rptr(struct amdgpu_ring *ring)
  65. {
  66. struct amdgpu_device *adev = ring->adev;
  67. return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_RPTR);
  68. }
  69. /**
  70. * uvd_v7_0_enc_ring_get_rptr - get enc read pointer
  71. *
  72. * @ring: amdgpu_ring pointer
  73. *
  74. * Returns the current hardware enc read pointer
  75. */
  76. static uint64_t uvd_v7_0_enc_ring_get_rptr(struct amdgpu_ring *ring)
  77. {
  78. struct amdgpu_device *adev = ring->adev;
  79. if (ring == &adev->uvd.inst[ring->me].ring_enc[0])
  80. return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR);
  81. else
  82. return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR2);
  83. }
  84. /**
  85. * uvd_v7_0_ring_get_wptr - get write pointer
  86. *
  87. * @ring: amdgpu_ring pointer
  88. *
  89. * Returns the current hardware write pointer
  90. */
  91. static uint64_t uvd_v7_0_ring_get_wptr(struct amdgpu_ring *ring)
  92. {
  93. struct amdgpu_device *adev = ring->adev;
  94. return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR);
  95. }
  96. /**
  97. * uvd_v7_0_enc_ring_get_wptr - get enc write pointer
  98. *
  99. * @ring: amdgpu_ring pointer
  100. *
  101. * Returns the current hardware enc write pointer
  102. */
  103. static uint64_t uvd_v7_0_enc_ring_get_wptr(struct amdgpu_ring *ring)
  104. {
  105. struct amdgpu_device *adev = ring->adev;
  106. if (ring->use_doorbell)
  107. return adev->wb.wb[ring->wptr_offs];
  108. if (ring == &adev->uvd.inst[ring->me].ring_enc[0])
  109. return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR);
  110. else
  111. return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2);
  112. }
  113. /**
  114. * uvd_v7_0_ring_set_wptr - set write pointer
  115. *
  116. * @ring: amdgpu_ring pointer
  117. *
  118. * Commits the write pointer to the hardware
  119. */
  120. static void uvd_v7_0_ring_set_wptr(struct amdgpu_ring *ring)
  121. {
  122. struct amdgpu_device *adev = ring->adev;
  123. WREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
  124. }
  125. /**
  126. * uvd_v7_0_enc_ring_set_wptr - set enc write pointer
  127. *
  128. * @ring: amdgpu_ring pointer
  129. *
  130. * Commits the enc write pointer to the hardware
  131. */
  132. static void uvd_v7_0_enc_ring_set_wptr(struct amdgpu_ring *ring)
  133. {
  134. struct amdgpu_device *adev = ring->adev;
  135. if (ring->use_doorbell) {
  136. /* XXX check if swapping is necessary on BE */
  137. adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
  138. WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
  139. return;
  140. }
  141. if (ring == &adev->uvd.inst[ring->me].ring_enc[0])
  142. WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR,
  143. lower_32_bits(ring->wptr));
  144. else
  145. WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2,
  146. lower_32_bits(ring->wptr));
  147. }
  148. /**
  149. * uvd_v7_0_enc_ring_test_ring - test if UVD ENC ring is working
  150. *
  151. * @ring: the engine to test on
  152. *
  153. */
  154. static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring)
  155. {
  156. struct amdgpu_device *adev = ring->adev;
  157. uint32_t rptr;
  158. unsigned i;
  159. int r;
  160. if (amdgpu_sriov_vf(adev))
  161. return 0;
  162. r = amdgpu_ring_alloc(ring, 16);
  163. if (r) {
  164. DRM_ERROR("amdgpu: uvd enc failed to lock (%d)ring %d (%d).\n",
  165. ring->me, ring->idx, r);
  166. return r;
  167. }
  168. rptr = amdgpu_ring_get_rptr(ring);
  169. amdgpu_ring_write(ring, HEVC_ENC_CMD_END);
  170. amdgpu_ring_commit(ring);
  171. for (i = 0; i < adev->usec_timeout; i++) {
  172. if (amdgpu_ring_get_rptr(ring) != rptr)
  173. break;
  174. DRM_UDELAY(1);
  175. }
  176. if (i < adev->usec_timeout) {
  177. DRM_DEBUG("(%d)ring test on %d succeeded in %d usecs\n",
  178. ring->me, ring->idx, i);
  179. } else {
  180. DRM_ERROR("amdgpu: (%d)ring %d test failed\n",
  181. ring->me, ring->idx);
  182. r = -ETIMEDOUT;
  183. }
  184. return r;
  185. }
  186. /**
  187. * uvd_v7_0_enc_get_create_msg - generate a UVD ENC create msg
  188. *
  189. * @adev: amdgpu_device pointer
  190. * @ring: ring we should submit the msg to
  191. * @handle: session handle to use
  192. * @fence: optional fence to return
  193. *
  194. * Open up a stream for HW test
  195. */
  196. static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
  197. struct dma_fence **fence)
  198. {
  199. const unsigned ib_size_dw = 16;
  200. struct amdgpu_job *job;
  201. struct amdgpu_ib *ib;
  202. struct dma_fence *f = NULL;
  203. uint64_t dummy;
  204. int i, r;
  205. r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
  206. if (r)
  207. return r;
  208. ib = &job->ibs[0];
  209. dummy = ib->gpu_addr + 1024;
  210. ib->length_dw = 0;
  211. ib->ptr[ib->length_dw++] = 0x00000018;
  212. ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
  213. ib->ptr[ib->length_dw++] = handle;
  214. ib->ptr[ib->length_dw++] = 0x00000000;
  215. ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
  216. ib->ptr[ib->length_dw++] = dummy;
  217. ib->ptr[ib->length_dw++] = 0x00000014;
  218. ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
  219. ib->ptr[ib->length_dw++] = 0x0000001c;
  220. ib->ptr[ib->length_dw++] = 0x00000000;
  221. ib->ptr[ib->length_dw++] = 0x00000000;
  222. ib->ptr[ib->length_dw++] = 0x00000008;
  223. ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */
  224. for (i = ib->length_dw; i < ib_size_dw; ++i)
  225. ib->ptr[i] = 0x0;
  226. r = amdgpu_job_submit_direct(job, ring, &f);
  227. if (r)
  228. goto err;
  229. if (fence)
  230. *fence = dma_fence_get(f);
  231. dma_fence_put(f);
  232. return 0;
  233. err:
  234. amdgpu_job_free(job);
  235. return r;
  236. }
  237. /**
  238. * uvd_v7_0_enc_get_destroy_msg - generate a UVD ENC destroy msg
  239. *
  240. * @adev: amdgpu_device pointer
  241. * @ring: ring we should submit the msg to
  242. * @handle: session handle to use
  243. * @fence: optional fence to return
  244. *
  245. * Close up a stream for HW test or if userspace failed to do so
  246. */
  247. int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
  248. bool direct, struct dma_fence **fence)
  249. {
  250. const unsigned ib_size_dw = 16;
  251. struct amdgpu_job *job;
  252. struct amdgpu_ib *ib;
  253. struct dma_fence *f = NULL;
  254. uint64_t dummy;
  255. int i, r;
  256. r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
  257. if (r)
  258. return r;
  259. ib = &job->ibs[0];
  260. dummy = ib->gpu_addr + 1024;
  261. ib->length_dw = 0;
  262. ib->ptr[ib->length_dw++] = 0x00000018;
  263. ib->ptr[ib->length_dw++] = 0x00000001;
  264. ib->ptr[ib->length_dw++] = handle;
  265. ib->ptr[ib->length_dw++] = 0x00000000;
  266. ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
  267. ib->ptr[ib->length_dw++] = dummy;
  268. ib->ptr[ib->length_dw++] = 0x00000014;
  269. ib->ptr[ib->length_dw++] = 0x00000002;
  270. ib->ptr[ib->length_dw++] = 0x0000001c;
  271. ib->ptr[ib->length_dw++] = 0x00000000;
  272. ib->ptr[ib->length_dw++] = 0x00000000;
  273. ib->ptr[ib->length_dw++] = 0x00000008;
  274. ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */
  275. for (i = ib->length_dw; i < ib_size_dw; ++i)
  276. ib->ptr[i] = 0x0;
  277. if (direct)
  278. r = amdgpu_job_submit_direct(job, ring, &f);
  279. else
  280. r = amdgpu_job_submit(job, &ring->adev->vce.entity,
  281. AMDGPU_FENCE_OWNER_UNDEFINED, &f);
  282. if (r)
  283. goto err;
  284. if (fence)
  285. *fence = dma_fence_get(f);
  286. dma_fence_put(f);
  287. return 0;
  288. err:
  289. amdgpu_job_free(job);
  290. return r;
  291. }
  292. /**
  293. * uvd_v7_0_enc_ring_test_ib - test if UVD ENC IBs are working
  294. *
  295. * @ring: the engine to test on
  296. *
  297. */
  298. static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
  299. {
  300. struct dma_fence *fence = NULL;
  301. long r;
  302. r = uvd_v7_0_enc_get_create_msg(ring, 1, NULL);
  303. if (r) {
  304. DRM_ERROR("amdgpu: (%d)failed to get create msg (%ld).\n", ring->me, r);
  305. goto error;
  306. }
  307. r = uvd_v7_0_enc_get_destroy_msg(ring, 1, true, &fence);
  308. if (r) {
  309. DRM_ERROR("amdgpu: (%d)failed to get destroy ib (%ld).\n", ring->me, r);
  310. goto error;
  311. }
  312. r = dma_fence_wait_timeout(fence, false, timeout);
  313. if (r == 0) {
  314. DRM_ERROR("amdgpu: (%d)IB test timed out.\n", ring->me);
  315. r = -ETIMEDOUT;
  316. } else if (r < 0) {
  317. DRM_ERROR("amdgpu: (%d)fence wait failed (%ld).\n", ring->me, r);
  318. } else {
  319. DRM_DEBUG("ib test on (%d)ring %d succeeded\n", ring->me, ring->idx);
  320. r = 0;
  321. }
  322. error:
  323. dma_fence_put(fence);
  324. return r;
  325. }
  326. static int uvd_v7_0_early_init(void *handle)
  327. {
  328. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  329. if (adev->asic_type == CHIP_VEGA20) {
  330. u32 harvest;
  331. int i;
  332. adev->uvd.num_uvd_inst = UVD7_MAX_HW_INSTANCES_VEGA20;
  333. for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
  334. harvest = RREG32_SOC15(UVD, i, mmUVD_PG0_CC_UVD_HARVESTING);
  335. if (harvest & UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE_MASK) {
  336. adev->uvd.harvest_config |= 1 << i;
  337. }
  338. }
  339. if (adev->uvd.harvest_config == (AMDGPU_UVD_HARVEST_UVD0 |
  340. AMDGPU_UVD_HARVEST_UVD1))
  341. /* both instances are harvested, disable the block */
  342. return -ENOENT;
  343. } else {
  344. adev->uvd.num_uvd_inst = 1;
  345. }
  346. if (amdgpu_sriov_vf(adev))
  347. adev->uvd.num_enc_rings = 1;
  348. else
  349. adev->uvd.num_enc_rings = 2;
  350. uvd_v7_0_set_ring_funcs(adev);
  351. uvd_v7_0_set_enc_ring_funcs(adev);
  352. uvd_v7_0_set_irq_funcs(adev);
  353. return 0;
  354. }
  355. static int uvd_v7_0_sw_init(void *handle)
  356. {
  357. struct amdgpu_ring *ring;
  358. int i, j, r;
  359. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  360. for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
  361. if (adev->uvd.harvest_config & (1 << j))
  362. continue;
  363. /* UVD TRAP */
  364. r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], UVD_7_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->uvd.inst[j].irq);
  365. if (r)
  366. return r;
  367. /* UVD ENC TRAP */
  368. for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
  369. r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], i + UVD_7_0__SRCID__UVD_ENC_GEN_PURP, &adev->uvd.inst[j].irq);
  370. if (r)
  371. return r;
  372. }
  373. }
  374. r = amdgpu_uvd_sw_init(adev);
  375. if (r)
  376. return r;
  377. if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
  378. const struct common_firmware_header *hdr;
  379. hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
  380. adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].ucode_id = AMDGPU_UCODE_ID_UVD;
  381. adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].fw = adev->uvd.fw;
  382. adev->firmware.fw_size +=
  383. ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
  384. DRM_INFO("PSP loading UVD firmware\n");
  385. }
  386. for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
  387. if (adev->uvd.harvest_config & (1 << j))
  388. continue;
  389. if (!amdgpu_sriov_vf(adev)) {
  390. ring = &adev->uvd.inst[j].ring;
  391. sprintf(ring->name, "uvd<%d>", j);
  392. r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0);
  393. if (r)
  394. return r;
  395. }
  396. for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
  397. ring = &adev->uvd.inst[j].ring_enc[i];
  398. sprintf(ring->name, "uvd_enc%d<%d>", i, j);
  399. if (amdgpu_sriov_vf(adev)) {
  400. ring->use_doorbell = true;
  401. /* currently only use the first enconding ring for
  402. * sriov, so set unused location for other unused rings.
  403. */
  404. if (i == 0)
  405. ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING0_1 * 2;
  406. else
  407. ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING2_3 * 2 + 1;
  408. }
  409. r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0);
  410. if (r)
  411. return r;
  412. }
  413. }
  414. r = amdgpu_uvd_resume(adev);
  415. if (r)
  416. return r;
  417. r = amdgpu_uvd_entity_init(adev);
  418. if (r)
  419. return r;
  420. r = amdgpu_virt_alloc_mm_table(adev);
  421. if (r)
  422. return r;
  423. return r;
  424. }
  425. static int uvd_v7_0_sw_fini(void *handle)
  426. {
  427. int i, j, r;
  428. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  429. amdgpu_virt_free_mm_table(adev);
  430. r = amdgpu_uvd_suspend(adev);
  431. if (r)
  432. return r;
  433. for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
  434. if (adev->uvd.harvest_config & (1 << j))
  435. continue;
  436. for (i = 0; i < adev->uvd.num_enc_rings; ++i)
  437. amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]);
  438. }
  439. return amdgpu_uvd_sw_fini(adev);
  440. }
  441. /**
  442. * uvd_v7_0_hw_init - start and test UVD block
  443. *
  444. * @adev: amdgpu_device pointer
  445. *
  446. * Initialize the hardware, boot up the VCPU and do some testing
  447. */
  448. static int uvd_v7_0_hw_init(void *handle)
  449. {
  450. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  451. struct amdgpu_ring *ring;
  452. uint32_t tmp;
  453. int i, j, r;
  454. if (amdgpu_sriov_vf(adev))
  455. r = uvd_v7_0_sriov_start(adev);
  456. else
  457. r = uvd_v7_0_start(adev);
  458. if (r)
  459. goto done;
  460. for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
  461. if (adev->uvd.harvest_config & (1 << j))
  462. continue;
  463. ring = &adev->uvd.inst[j].ring;
  464. if (!amdgpu_sriov_vf(adev)) {
  465. ring->ready = true;
  466. r = amdgpu_ring_test_ring(ring);
  467. if (r) {
  468. ring->ready = false;
  469. goto done;
  470. }
  471. r = amdgpu_ring_alloc(ring, 10);
  472. if (r) {
  473. DRM_ERROR("amdgpu: (%d)ring failed to lock UVD ring (%d).\n", j, r);
  474. goto done;
  475. }
  476. tmp = PACKET0(SOC15_REG_OFFSET(UVD, j,
  477. mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL), 0);
  478. amdgpu_ring_write(ring, tmp);
  479. amdgpu_ring_write(ring, 0xFFFFF);
  480. tmp = PACKET0(SOC15_REG_OFFSET(UVD, j,
  481. mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL), 0);
  482. amdgpu_ring_write(ring, tmp);
  483. amdgpu_ring_write(ring, 0xFFFFF);
  484. tmp = PACKET0(SOC15_REG_OFFSET(UVD, j,
  485. mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL), 0);
  486. amdgpu_ring_write(ring, tmp);
  487. amdgpu_ring_write(ring, 0xFFFFF);
  488. /* Clear timeout status bits */
  489. amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, j,
  490. mmUVD_SEMA_TIMEOUT_STATUS), 0));
  491. amdgpu_ring_write(ring, 0x8);
  492. amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, j,
  493. mmUVD_SEMA_CNTL), 0));
  494. amdgpu_ring_write(ring, 3);
  495. amdgpu_ring_commit(ring);
  496. }
  497. for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
  498. ring = &adev->uvd.inst[j].ring_enc[i];
  499. ring->ready = true;
  500. r = amdgpu_ring_test_ring(ring);
  501. if (r) {
  502. ring->ready = false;
  503. goto done;
  504. }
  505. }
  506. }
  507. done:
  508. if (!r)
  509. DRM_INFO("UVD and UVD ENC initialized successfully.\n");
  510. return r;
  511. }
  512. /**
  513. * uvd_v7_0_hw_fini - stop the hardware block
  514. *
  515. * @adev: amdgpu_device pointer
  516. *
  517. * Stop the UVD block, mark ring as not ready any more
  518. */
  519. static int uvd_v7_0_hw_fini(void *handle)
  520. {
  521. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  522. int i;
  523. if (!amdgpu_sriov_vf(adev))
  524. uvd_v7_0_stop(adev);
  525. else {
  526. /* full access mode, so don't touch any UVD register */
  527. DRM_DEBUG("For SRIOV client, shouldn't do anything.\n");
  528. }
  529. for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
  530. if (adev->uvd.harvest_config & (1 << i))
  531. continue;
  532. adev->uvd.inst[i].ring.ready = false;
  533. }
  534. return 0;
  535. }
  536. static int uvd_v7_0_suspend(void *handle)
  537. {
  538. int r;
  539. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  540. r = uvd_v7_0_hw_fini(adev);
  541. if (r)
  542. return r;
  543. return amdgpu_uvd_suspend(adev);
  544. }
  545. static int uvd_v7_0_resume(void *handle)
  546. {
  547. int r;
  548. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  549. r = amdgpu_uvd_resume(adev);
  550. if (r)
  551. return r;
  552. return uvd_v7_0_hw_init(adev);
  553. }
  554. /**
  555. * uvd_v7_0_mc_resume - memory controller programming
  556. *
  557. * @adev: amdgpu_device pointer
  558. *
  559. * Let the UVD memory controller know it's offsets
  560. */
  561. static void uvd_v7_0_mc_resume(struct amdgpu_device *adev)
  562. {
  563. uint32_t size = AMDGPU_UVD_FIRMWARE_SIZE(adev);
  564. uint32_t offset;
  565. int i;
  566. for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
  567. if (adev->uvd.harvest_config & (1 << i))
  568. continue;
  569. if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
  570. WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
  571. lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr));
  572. WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
  573. upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr));
  574. offset = 0;
  575. } else {
  576. WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
  577. lower_32_bits(adev->uvd.inst[i].gpu_addr));
  578. WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
  579. upper_32_bits(adev->uvd.inst[i].gpu_addr));
  580. offset = size;
  581. }
  582. WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET0,
  583. AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
  584. WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE0, size);
  585. WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
  586. lower_32_bits(adev->uvd.inst[i].gpu_addr + offset));
  587. WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
  588. upper_32_bits(adev->uvd.inst[i].gpu_addr + offset));
  589. WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET1, (1 << 21));
  590. WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_UVD_HEAP_SIZE);
  591. WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
  592. lower_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE));
  593. WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
  594. upper_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE));
  595. WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET2, (2 << 21));
  596. WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE2,
  597. AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40));
  598. WREG32_SOC15(UVD, i, mmUVD_UDEC_ADDR_CONFIG,
  599. adev->gfx.config.gb_addr_config);
  600. WREG32_SOC15(UVD, i, mmUVD_UDEC_DB_ADDR_CONFIG,
  601. adev->gfx.config.gb_addr_config);
  602. WREG32_SOC15(UVD, i, mmUVD_UDEC_DBW_ADDR_CONFIG,
  603. adev->gfx.config.gb_addr_config);
  604. WREG32_SOC15(UVD, i, mmUVD_GP_SCRATCH4, adev->uvd.max_handles);
  605. }
  606. }
  607. static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev,
  608. struct amdgpu_mm_table *table)
  609. {
  610. uint32_t data = 0, loop;
  611. uint64_t addr = table->gpu_addr;
  612. struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)table->cpu_addr;
  613. uint32_t size;
  614. int i;
  615. size = header->header_size + header->vce_table_size + header->uvd_table_size;
  616. /* 1, write to vce_mmsch_vf_ctx_addr_lo/hi register with GPU mc addr of memory descriptor location */
  617. WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_CTX_ADDR_LO, lower_32_bits(addr));
  618. WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_CTX_ADDR_HI, upper_32_bits(addr));
  619. /* 2, update vmid of descriptor */
  620. data = RREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_VMID);
  621. data &= ~VCE_MMSCH_VF_VMID__VF_CTX_VMID_MASK;
  622. data |= (0 << VCE_MMSCH_VF_VMID__VF_CTX_VMID__SHIFT); /* use domain0 for MM scheduler */
  623. WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_VMID, data);
  624. /* 3, notify mmsch about the size of this descriptor */
  625. WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_CTX_SIZE, size);
  626. /* 4, set resp to zero */
  627. WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0);
  628. for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
  629. if (adev->uvd.harvest_config & (1 << i))
  630. continue;
  631. WDOORBELL32(adev->uvd.inst[i].ring_enc[0].doorbell_index, 0);
  632. adev->wb.wb[adev->uvd.inst[i].ring_enc[0].wptr_offs] = 0;
  633. adev->uvd.inst[i].ring_enc[0].wptr = 0;
  634. adev->uvd.inst[i].ring_enc[0].wptr_old = 0;
  635. }
  636. /* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */
  637. WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_HOST, 0x10000001);
  638. data = RREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP);
  639. loop = 1000;
  640. while ((data & 0x10000002) != 0x10000002) {
  641. udelay(10);
  642. data = RREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP);
  643. loop--;
  644. if (!loop)
  645. break;
  646. }
  647. if (!loop) {
  648. dev_err(adev->dev, "failed to init MMSCH, mmVCE_MMSCH_VF_MAILBOX_RESP = %x\n", data);
  649. return -EBUSY;
  650. }
  651. return 0;
  652. }
  653. static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
  654. {
  655. struct amdgpu_ring *ring;
  656. uint32_t offset, size, tmp;
  657. uint32_t table_size = 0;
  658. struct mmsch_v1_0_cmd_direct_write direct_wt = { {0} };
  659. struct mmsch_v1_0_cmd_direct_read_modify_write direct_rd_mod_wt = { {0} };
  660. struct mmsch_v1_0_cmd_direct_polling direct_poll = { {0} };
  661. struct mmsch_v1_0_cmd_end end = { {0} };
  662. uint32_t *init_table = adev->virt.mm_table.cpu_addr;
  663. struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)init_table;
  664. uint8_t i = 0;
  665. direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE;
  666. direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
  667. direct_poll.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_POLLING;
  668. end.cmd_header.command_type = MMSCH_COMMAND__END;
  669. if (header->uvd_table_offset == 0 && header->uvd_table_size == 0) {
  670. header->version = MMSCH_VERSION;
  671. header->header_size = sizeof(struct mmsch_v1_0_init_header) >> 2;
  672. if (header->vce_table_offset == 0 && header->vce_table_size == 0)
  673. header->uvd_table_offset = header->header_size;
  674. else
  675. header->uvd_table_offset = header->vce_table_size + header->vce_table_offset;
  676. init_table += header->uvd_table_offset;
  677. for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
  678. if (adev->uvd.harvest_config & (1 << i))
  679. continue;
  680. ring = &adev->uvd.inst[i].ring;
  681. ring->wptr = 0;
  682. size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4);
  683. MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS),
  684. 0xFFFFFFFF, 0x00000004);
  685. /* mc resume*/
  686. if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
  687. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
  688. lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr));
  689. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
  690. upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr));
  691. offset = 0;
  692. } else {
  693. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
  694. lower_32_bits(adev->uvd.inst[i].gpu_addr));
  695. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
  696. upper_32_bits(adev->uvd.inst[i].gpu_addr));
  697. offset = size;
  698. }
  699. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET0),
  700. AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
  701. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE0), size);
  702. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
  703. lower_32_bits(adev->uvd.inst[i].gpu_addr + offset));
  704. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
  705. upper_32_bits(adev->uvd.inst[i].gpu_addr + offset));
  706. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET1), (1 << 21));
  707. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_UVD_HEAP_SIZE);
  708. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
  709. lower_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE));
  710. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
  711. upper_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE));
  712. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET2), (2 << 21));
  713. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE2),
  714. AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40));
  715. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_GP_SCRATCH4), adev->uvd.max_handles);
  716. /* mc resume end*/
  717. /* disable clock gating */
  718. MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_CGC_CTRL),
  719. ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK, 0);
  720. /* disable interupt */
  721. MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN),
  722. ~UVD_MASTINT_EN__VCPU_EN_MASK, 0);
  723. /* stall UMC and register bus before resetting VCPU */
  724. MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2),
  725. ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
  726. UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
  727. /* put LMI, VCPU, RBC etc... into reset */
  728. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET),
  729. (uint32_t)(UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
  730. UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK |
  731. UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK |
  732. UVD_SOFT_RESET__RBC_SOFT_RESET_MASK |
  733. UVD_SOFT_RESET__CSM_SOFT_RESET_MASK |
  734. UVD_SOFT_RESET__CXW_SOFT_RESET_MASK |
  735. UVD_SOFT_RESET__TAP_SOFT_RESET_MASK |
  736. UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK));
  737. /* initialize UVD memory controller */
  738. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL),
  739. (uint32_t)((0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
  740. UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
  741. UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
  742. UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
  743. UVD_LMI_CTRL__REQ_MODE_MASK |
  744. 0x00100000L));
  745. /* take all subblocks out of reset, except VCPU */
  746. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET),
  747. UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
  748. /* enable VCPU clock */
  749. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL),
  750. UVD_VCPU_CNTL__CLK_EN_MASK);
  751. /* enable master interrupt */
  752. MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN),
  753. ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK),
  754. (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK));
  755. /* clear the bit 4 of UVD_STATUS */
  756. MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS),
  757. ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT), 0);
  758. /* force RBC into idle state */
  759. size = order_base_2(ring->ring_size);
  760. tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, size);
  761. tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
  762. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RBC_RB_CNTL), tmp);
  763. ring = &adev->uvd.inst[i].ring_enc[0];
  764. ring->wptr = 0;
  765. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_BASE_LO), ring->gpu_addr);
  766. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_BASE_HI), upper_32_bits(ring->gpu_addr));
  767. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_SIZE), ring->ring_size / 4);
  768. /* boot up the VCPU */
  769. MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET), 0);
  770. /* enable UMC */
  771. MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2),
  772. ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0);
  773. MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS), 0x02, 0x02);
  774. }
  775. /* add end packet */
  776. memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end));
  777. table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4;
  778. header->uvd_table_size = table_size;
  779. }
  780. return uvd_v7_0_mmsch_start(adev, &adev->virt.mm_table);
  781. }
  782. /**
  783. * uvd_v7_0_start - start UVD block
  784. *
  785. * @adev: amdgpu_device pointer
  786. *
  787. * Setup and start the UVD block
  788. */
  789. static int uvd_v7_0_start(struct amdgpu_device *adev)
  790. {
  791. struct amdgpu_ring *ring;
  792. uint32_t rb_bufsz, tmp;
  793. uint32_t lmi_swap_cntl;
  794. uint32_t mp_swap_cntl;
  795. int i, j, k, r;
  796. for (k = 0; k < adev->uvd.num_uvd_inst; ++k) {
  797. if (adev->uvd.harvest_config & (1 << k))
  798. continue;
  799. /* disable DPG */
  800. WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_POWER_STATUS), 0,
  801. ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
  802. }
  803. /* disable byte swapping */
  804. lmi_swap_cntl = 0;
  805. mp_swap_cntl = 0;
  806. uvd_v7_0_mc_resume(adev);
  807. for (k = 0; k < adev->uvd.num_uvd_inst; ++k) {
  808. if (adev->uvd.harvest_config & (1 << k))
  809. continue;
  810. ring = &adev->uvd.inst[k].ring;
  811. /* disable clock gating */
  812. WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_CGC_CTRL), 0,
  813. ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK);
  814. /* disable interupt */
  815. WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_MASTINT_EN), 0,
  816. ~UVD_MASTINT_EN__VCPU_EN_MASK);
  817. /* stall UMC and register bus before resetting VCPU */
  818. WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_LMI_CTRL2),
  819. UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
  820. ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
  821. mdelay(1);
  822. /* put LMI, VCPU, RBC etc... into reset */
  823. WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET,
  824. UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
  825. UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK |
  826. UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK |
  827. UVD_SOFT_RESET__RBC_SOFT_RESET_MASK |
  828. UVD_SOFT_RESET__CSM_SOFT_RESET_MASK |
  829. UVD_SOFT_RESET__CXW_SOFT_RESET_MASK |
  830. UVD_SOFT_RESET__TAP_SOFT_RESET_MASK |
  831. UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
  832. mdelay(5);
  833. /* initialize UVD memory controller */
  834. WREG32_SOC15(UVD, k, mmUVD_LMI_CTRL,
  835. (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
  836. UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
  837. UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
  838. UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
  839. UVD_LMI_CTRL__REQ_MODE_MASK |
  840. 0x00100000L);
  841. #ifdef __BIG_ENDIAN
  842. /* swap (8 in 32) RB and IB */
  843. lmi_swap_cntl = 0xa;
  844. mp_swap_cntl = 0;
  845. #endif
  846. WREG32_SOC15(UVD, k, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl);
  847. WREG32_SOC15(UVD, k, mmUVD_MP_SWAP_CNTL, mp_swap_cntl);
  848. WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXA0, 0x40c2040);
  849. WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXA1, 0x0);
  850. WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXB0, 0x40c2040);
  851. WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXB1, 0x0);
  852. WREG32_SOC15(UVD, k, mmUVD_MPC_SET_ALU, 0);
  853. WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUX, 0x88);
  854. /* take all subblocks out of reset, except VCPU */
  855. WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET,
  856. UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
  857. mdelay(5);
  858. /* enable VCPU clock */
  859. WREG32_SOC15(UVD, k, mmUVD_VCPU_CNTL,
  860. UVD_VCPU_CNTL__CLK_EN_MASK);
  861. /* enable UMC */
  862. WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_LMI_CTRL2), 0,
  863. ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
  864. /* boot up the VCPU */
  865. WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET, 0);
  866. mdelay(10);
  867. for (i = 0; i < 10; ++i) {
  868. uint32_t status;
  869. for (j = 0; j < 100; ++j) {
  870. status = RREG32_SOC15(UVD, k, mmUVD_STATUS);
  871. if (status & 2)
  872. break;
  873. mdelay(10);
  874. }
  875. r = 0;
  876. if (status & 2)
  877. break;
  878. DRM_ERROR("UVD(%d) not responding, trying to reset the VCPU!!!\n", k);
  879. WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_SOFT_RESET),
  880. UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,
  881. ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
  882. mdelay(10);
  883. WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_SOFT_RESET), 0,
  884. ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
  885. mdelay(10);
  886. r = -1;
  887. }
  888. if (r) {
  889. DRM_ERROR("UVD(%d) not responding, giving up!!!\n", k);
  890. return r;
  891. }
  892. /* enable master interrupt */
  893. WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_MASTINT_EN),
  894. (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK),
  895. ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK));
  896. /* clear the bit 4 of UVD_STATUS */
  897. WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_STATUS), 0,
  898. ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
  899. /* force RBC into idle state */
  900. rb_bufsz = order_base_2(ring->ring_size);
  901. tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
  902. tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
  903. tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
  904. tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0);
  905. tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
  906. tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
  907. WREG32_SOC15(UVD, k, mmUVD_RBC_RB_CNTL, tmp);
  908. /* set the write pointer delay */
  909. WREG32_SOC15(UVD, k, mmUVD_RBC_RB_WPTR_CNTL, 0);
  910. /* set the wb address */
  911. WREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR_ADDR,
  912. (upper_32_bits(ring->gpu_addr) >> 2));
  913. /* programm the RB_BASE for ring buffer */
  914. WREG32_SOC15(UVD, k, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
  915. lower_32_bits(ring->gpu_addr));
  916. WREG32_SOC15(UVD, k, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
  917. upper_32_bits(ring->gpu_addr));
  918. /* Initialize the ring buffer's read and write pointers */
  919. WREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR, 0);
  920. ring->wptr = RREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR);
  921. WREG32_SOC15(UVD, k, mmUVD_RBC_RB_WPTR,
  922. lower_32_bits(ring->wptr));
  923. WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_RBC_RB_CNTL), 0,
  924. ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK);
  925. ring = &adev->uvd.inst[k].ring_enc[0];
  926. WREG32_SOC15(UVD, k, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
  927. WREG32_SOC15(UVD, k, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
  928. WREG32_SOC15(UVD, k, mmUVD_RB_BASE_LO, ring->gpu_addr);
  929. WREG32_SOC15(UVD, k, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
  930. WREG32_SOC15(UVD, k, mmUVD_RB_SIZE, ring->ring_size / 4);
  931. ring = &adev->uvd.inst[k].ring_enc[1];
  932. WREG32_SOC15(UVD, k, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
  933. WREG32_SOC15(UVD, k, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
  934. WREG32_SOC15(UVD, k, mmUVD_RB_BASE_LO2, ring->gpu_addr);
  935. WREG32_SOC15(UVD, k, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
  936. WREG32_SOC15(UVD, k, mmUVD_RB_SIZE2, ring->ring_size / 4);
  937. }
  938. return 0;
  939. }
  940. /**
  941. * uvd_v7_0_stop - stop UVD block
  942. *
  943. * @adev: amdgpu_device pointer
  944. *
  945. * stop the UVD block
  946. */
  947. static void uvd_v7_0_stop(struct amdgpu_device *adev)
  948. {
  949. uint8_t i = 0;
  950. for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
  951. if (adev->uvd.harvest_config & (1 << i))
  952. continue;
  953. /* force RBC into idle state */
  954. WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, 0x11010101);
  955. /* Stall UMC and register bus before resetting VCPU */
  956. WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2),
  957. UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
  958. ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
  959. mdelay(1);
  960. /* put VCPU into reset */
  961. WREG32_SOC15(UVD, i, mmUVD_SOFT_RESET,
  962. UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
  963. mdelay(5);
  964. /* disable VCPU clock */
  965. WREG32_SOC15(UVD, i, mmUVD_VCPU_CNTL, 0x0);
  966. /* Unstall UMC and register bus */
  967. WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), 0,
  968. ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
  969. }
  970. }
  971. /**
  972. * uvd_v7_0_ring_emit_fence - emit an fence & trap command
  973. *
  974. * @ring: amdgpu_ring pointer
  975. * @fence: fence to emit
  976. *
  977. * Write a fence and a trap command to the ring.
  978. */
  979. static void uvd_v7_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
  980. unsigned flags)
  981. {
  982. struct amdgpu_device *adev = ring->adev;
  983. WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
  984. amdgpu_ring_write(ring,
  985. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_CONTEXT_ID), 0));
  986. amdgpu_ring_write(ring, seq);
  987. amdgpu_ring_write(ring,
  988. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0));
  989. amdgpu_ring_write(ring, addr & 0xffffffff);
  990. amdgpu_ring_write(ring,
  991. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0));
  992. amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff);
  993. amdgpu_ring_write(ring,
  994. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0));
  995. amdgpu_ring_write(ring, 0);
  996. amdgpu_ring_write(ring,
  997. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0));
  998. amdgpu_ring_write(ring, 0);
  999. amdgpu_ring_write(ring,
  1000. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0));
  1001. amdgpu_ring_write(ring, 0);
  1002. amdgpu_ring_write(ring,
  1003. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0));
  1004. amdgpu_ring_write(ring, 2);
  1005. }
  1006. /**
  1007. * uvd_v7_0_enc_ring_emit_fence - emit an enc fence & trap command
  1008. *
  1009. * @ring: amdgpu_ring pointer
  1010. * @fence: fence to emit
  1011. *
  1012. * Write enc a fence and a trap command to the ring.
  1013. */
  1014. static void uvd_v7_0_enc_ring_emit_fence(struct amdgpu_ring *ring, u64 addr,
  1015. u64 seq, unsigned flags)
  1016. {
  1017. WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
  1018. amdgpu_ring_write(ring, HEVC_ENC_CMD_FENCE);
  1019. amdgpu_ring_write(ring, addr);
  1020. amdgpu_ring_write(ring, upper_32_bits(addr));
  1021. amdgpu_ring_write(ring, seq);
  1022. amdgpu_ring_write(ring, HEVC_ENC_CMD_TRAP);
  1023. }
  1024. /**
  1025. * uvd_v7_0_ring_emit_hdp_flush - skip HDP flushing
  1026. *
  1027. * @ring: amdgpu_ring pointer
  1028. */
  1029. static void uvd_v7_0_ring_emit_hdp_flush(struct amdgpu_ring *ring)
  1030. {
  1031. /* The firmware doesn't seem to like touching registers at this point. */
  1032. }
  1033. /**
  1034. * uvd_v7_0_ring_test_ring - register write test
  1035. *
  1036. * @ring: amdgpu_ring pointer
  1037. *
  1038. * Test if we can successfully write to the context register
  1039. */
  1040. static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring)
  1041. {
  1042. struct amdgpu_device *adev = ring->adev;
  1043. uint32_t tmp = 0;
  1044. unsigned i;
  1045. int r;
  1046. WREG32_SOC15(UVD, ring->me, mmUVD_CONTEXT_ID, 0xCAFEDEAD);
  1047. r = amdgpu_ring_alloc(ring, 3);
  1048. if (r) {
  1049. DRM_ERROR("amdgpu: (%d)cp failed to lock ring %d (%d).\n",
  1050. ring->me, ring->idx, r);
  1051. return r;
  1052. }
  1053. amdgpu_ring_write(ring,
  1054. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_CONTEXT_ID), 0));
  1055. amdgpu_ring_write(ring, 0xDEADBEEF);
  1056. amdgpu_ring_commit(ring);
  1057. for (i = 0; i < adev->usec_timeout; i++) {
  1058. tmp = RREG32_SOC15(UVD, ring->me, mmUVD_CONTEXT_ID);
  1059. if (tmp == 0xDEADBEEF)
  1060. break;
  1061. DRM_UDELAY(1);
  1062. }
  1063. if (i < adev->usec_timeout) {
  1064. DRM_DEBUG("(%d)ring test on %d succeeded in %d usecs\n",
  1065. ring->me, ring->idx, i);
  1066. } else {
  1067. DRM_ERROR("(%d)amdgpu: ring %d test failed (0x%08X)\n",
  1068. ring->me, ring->idx, tmp);
  1069. r = -EINVAL;
  1070. }
  1071. return r;
  1072. }
  1073. /**
  1074. * uvd_v7_0_ring_patch_cs_in_place - Patch the IB for command submission.
  1075. *
  1076. * @p: the CS parser with the IBs
  1077. * @ib_idx: which IB to patch
  1078. *
  1079. */
  1080. static int uvd_v7_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
  1081. uint32_t ib_idx)
  1082. {
  1083. struct amdgpu_ib *ib = &p->job->ibs[ib_idx];
  1084. unsigned i;
  1085. /* No patching necessary for the first instance */
  1086. if (!p->ring->me)
  1087. return 0;
  1088. for (i = 0; i < ib->length_dw; i += 2) {
  1089. uint32_t reg = amdgpu_get_ib_value(p, ib_idx, i);
  1090. reg -= p->adev->reg_offset[UVD_HWIP][0][1];
  1091. reg += p->adev->reg_offset[UVD_HWIP][1][1];
  1092. amdgpu_set_ib_value(p, ib_idx, i, reg);
  1093. }
  1094. return 0;
  1095. }
  1096. /**
  1097. * uvd_v7_0_ring_emit_ib - execute indirect buffer
  1098. *
  1099. * @ring: amdgpu_ring pointer
  1100. * @ib: indirect buffer to execute
  1101. *
  1102. * Write ring commands to execute the indirect buffer
  1103. */
  1104. static void uvd_v7_0_ring_emit_ib(struct amdgpu_ring *ring,
  1105. struct amdgpu_ib *ib,
  1106. unsigned vmid, bool ctx_switch)
  1107. {
  1108. struct amdgpu_device *adev = ring->adev;
  1109. amdgpu_ring_write(ring,
  1110. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_VMID), 0));
  1111. amdgpu_ring_write(ring, vmid);
  1112. amdgpu_ring_write(ring,
  1113. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0));
  1114. amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
  1115. amdgpu_ring_write(ring,
  1116. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH), 0));
  1117. amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
  1118. amdgpu_ring_write(ring,
  1119. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_RBC_IB_SIZE), 0));
  1120. amdgpu_ring_write(ring, ib->length_dw);
  1121. }
  1122. /**
  1123. * uvd_v7_0_enc_ring_emit_ib - enc execute indirect buffer
  1124. *
  1125. * @ring: amdgpu_ring pointer
  1126. * @ib: indirect buffer to execute
  1127. *
  1128. * Write enc ring commands to execute the indirect buffer
  1129. */
  1130. static void uvd_v7_0_enc_ring_emit_ib(struct amdgpu_ring *ring,
  1131. struct amdgpu_ib *ib, unsigned int vmid, bool ctx_switch)
  1132. {
  1133. amdgpu_ring_write(ring, HEVC_ENC_CMD_IB_VM);
  1134. amdgpu_ring_write(ring, vmid);
  1135. amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
  1136. amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
  1137. amdgpu_ring_write(ring, ib->length_dw);
  1138. }
  1139. static void uvd_v7_0_ring_emit_wreg(struct amdgpu_ring *ring,
  1140. uint32_t reg, uint32_t val)
  1141. {
  1142. struct amdgpu_device *adev = ring->adev;
  1143. amdgpu_ring_write(ring,
  1144. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0));
  1145. amdgpu_ring_write(ring, reg << 2);
  1146. amdgpu_ring_write(ring,
  1147. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0));
  1148. amdgpu_ring_write(ring, val);
  1149. amdgpu_ring_write(ring,
  1150. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0));
  1151. amdgpu_ring_write(ring, 8);
  1152. }
  1153. static void uvd_v7_0_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg,
  1154. uint32_t val, uint32_t mask)
  1155. {
  1156. struct amdgpu_device *adev = ring->adev;
  1157. amdgpu_ring_write(ring,
  1158. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0));
  1159. amdgpu_ring_write(ring, reg << 2);
  1160. amdgpu_ring_write(ring,
  1161. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0));
  1162. amdgpu_ring_write(ring, val);
  1163. amdgpu_ring_write(ring,
  1164. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GP_SCRATCH8), 0));
  1165. amdgpu_ring_write(ring, mask);
  1166. amdgpu_ring_write(ring,
  1167. PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0));
  1168. amdgpu_ring_write(ring, 12);
  1169. }
  1170. static void uvd_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
  1171. unsigned vmid, uint64_t pd_addr)
  1172. {
  1173. struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
  1174. uint32_t data0, data1, mask;
  1175. pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
  1176. /* wait for reg writes */
  1177. data0 = hub->ctx0_ptb_addr_lo32 + vmid * 2;
  1178. data1 = lower_32_bits(pd_addr);
  1179. mask = 0xffffffff;
  1180. uvd_v7_0_ring_emit_reg_wait(ring, data0, data1, mask);
  1181. }
  1182. static void uvd_v7_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
  1183. {
  1184. struct amdgpu_device *adev = ring->adev;
  1185. int i;
  1186. WARN_ON(ring->wptr % 2 || count % 2);
  1187. for (i = 0; i < count / 2; i++) {
  1188. amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_NO_OP), 0));
  1189. amdgpu_ring_write(ring, 0);
  1190. }
  1191. }
  1192. static void uvd_v7_0_enc_ring_insert_end(struct amdgpu_ring *ring)
  1193. {
  1194. amdgpu_ring_write(ring, HEVC_ENC_CMD_END);
  1195. }
  1196. static void uvd_v7_0_enc_ring_emit_reg_wait(struct amdgpu_ring *ring,
  1197. uint32_t reg, uint32_t val,
  1198. uint32_t mask)
  1199. {
  1200. amdgpu_ring_write(ring, HEVC_ENC_CMD_REG_WAIT);
  1201. amdgpu_ring_write(ring, reg << 2);
  1202. amdgpu_ring_write(ring, mask);
  1203. amdgpu_ring_write(ring, val);
  1204. }
  1205. static void uvd_v7_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring,
  1206. unsigned int vmid, uint64_t pd_addr)
  1207. {
  1208. struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
  1209. pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
  1210. /* wait for reg writes */
  1211. uvd_v7_0_enc_ring_emit_reg_wait(ring, hub->ctx0_ptb_addr_lo32 + vmid * 2,
  1212. lower_32_bits(pd_addr), 0xffffffff);
  1213. }
  1214. static void uvd_v7_0_enc_ring_emit_wreg(struct amdgpu_ring *ring,
  1215. uint32_t reg, uint32_t val)
  1216. {
  1217. amdgpu_ring_write(ring, HEVC_ENC_CMD_REG_WRITE);
  1218. amdgpu_ring_write(ring, reg << 2);
  1219. amdgpu_ring_write(ring, val);
  1220. }
  1221. #if 0
  1222. static bool uvd_v7_0_is_idle(void *handle)
  1223. {
  1224. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  1225. return !(RREG32(mmSRBM_STATUS) & SRBM_STATUS__UVD_BUSY_MASK);
  1226. }
  1227. static int uvd_v7_0_wait_for_idle(void *handle)
  1228. {
  1229. unsigned i;
  1230. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  1231. for (i = 0; i < adev->usec_timeout; i++) {
  1232. if (uvd_v7_0_is_idle(handle))
  1233. return 0;
  1234. }
  1235. return -ETIMEDOUT;
  1236. }
  1237. #define AMDGPU_UVD_STATUS_BUSY_MASK 0xfd
  1238. static bool uvd_v7_0_check_soft_reset(void *handle)
  1239. {
  1240. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  1241. u32 srbm_soft_reset = 0;
  1242. u32 tmp = RREG32(mmSRBM_STATUS);
  1243. if (REG_GET_FIELD(tmp, SRBM_STATUS, UVD_RQ_PENDING) ||
  1244. REG_GET_FIELD(tmp, SRBM_STATUS, UVD_BUSY) ||
  1245. (RREG32_SOC15(UVD, ring->me, mmUVD_STATUS) &
  1246. AMDGPU_UVD_STATUS_BUSY_MASK))
  1247. srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset,
  1248. SRBM_SOFT_RESET, SOFT_RESET_UVD, 1);
  1249. if (srbm_soft_reset) {
  1250. adev->uvd.inst[ring->me].srbm_soft_reset = srbm_soft_reset;
  1251. return true;
  1252. } else {
  1253. adev->uvd.inst[ring->me].srbm_soft_reset = 0;
  1254. return false;
  1255. }
  1256. }
  1257. static int uvd_v7_0_pre_soft_reset(void *handle)
  1258. {
  1259. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  1260. if (!adev->uvd.inst[ring->me].srbm_soft_reset)
  1261. return 0;
  1262. uvd_v7_0_stop(adev);
  1263. return 0;
  1264. }
  1265. static int uvd_v7_0_soft_reset(void *handle)
  1266. {
  1267. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  1268. u32 srbm_soft_reset;
  1269. if (!adev->uvd.inst[ring->me].srbm_soft_reset)
  1270. return 0;
  1271. srbm_soft_reset = adev->uvd.inst[ring->me].srbm_soft_reset;
  1272. if (srbm_soft_reset) {
  1273. u32 tmp;
  1274. tmp = RREG32(mmSRBM_SOFT_RESET);
  1275. tmp |= srbm_soft_reset;
  1276. dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
  1277. WREG32(mmSRBM_SOFT_RESET, tmp);
  1278. tmp = RREG32(mmSRBM_SOFT_RESET);
  1279. udelay(50);
  1280. tmp &= ~srbm_soft_reset;
  1281. WREG32(mmSRBM_SOFT_RESET, tmp);
  1282. tmp = RREG32(mmSRBM_SOFT_RESET);
  1283. /* Wait a little for things to settle down */
  1284. udelay(50);
  1285. }
  1286. return 0;
  1287. }
  1288. static int uvd_v7_0_post_soft_reset(void *handle)
  1289. {
  1290. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  1291. if (!adev->uvd.inst[ring->me].srbm_soft_reset)
  1292. return 0;
  1293. mdelay(5);
  1294. return uvd_v7_0_start(adev);
  1295. }
  1296. #endif
  1297. static int uvd_v7_0_set_interrupt_state(struct amdgpu_device *adev,
  1298. struct amdgpu_irq_src *source,
  1299. unsigned type,
  1300. enum amdgpu_interrupt_state state)
  1301. {
  1302. // TODO
  1303. return 0;
  1304. }
  1305. static int uvd_v7_0_process_interrupt(struct amdgpu_device *adev,
  1306. struct amdgpu_irq_src *source,
  1307. struct amdgpu_iv_entry *entry)
  1308. {
  1309. uint32_t ip_instance;
  1310. switch (entry->client_id) {
  1311. case SOC15_IH_CLIENTID_UVD:
  1312. ip_instance = 0;
  1313. break;
  1314. case SOC15_IH_CLIENTID_UVD1:
  1315. ip_instance = 1;
  1316. break;
  1317. default:
  1318. DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
  1319. return 0;
  1320. }
  1321. DRM_DEBUG("IH: UVD TRAP\n");
  1322. switch (entry->src_id) {
  1323. case 124:
  1324. amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring);
  1325. break;
  1326. case 119:
  1327. amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring_enc[0]);
  1328. break;
  1329. case 120:
  1330. if (!amdgpu_sriov_vf(adev))
  1331. amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring_enc[1]);
  1332. break;
  1333. default:
  1334. DRM_ERROR("Unhandled interrupt: %d %d\n",
  1335. entry->src_id, entry->src_data[0]);
  1336. break;
  1337. }
  1338. return 0;
  1339. }
  1340. #if 0
  1341. static void uvd_v7_0_set_sw_clock_gating(struct amdgpu_device *adev)
  1342. {
  1343. uint32_t data, data1, data2, suvd_flags;
  1344. data = RREG32_SOC15(UVD, ring->me, mmUVD_CGC_CTRL);
  1345. data1 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE);
  1346. data2 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_CTRL);
  1347. data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK |
  1348. UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK);
  1349. suvd_flags = UVD_SUVD_CGC_GATE__SRE_MASK |
  1350. UVD_SUVD_CGC_GATE__SIT_MASK |
  1351. UVD_SUVD_CGC_GATE__SMP_MASK |
  1352. UVD_SUVD_CGC_GATE__SCM_MASK |
  1353. UVD_SUVD_CGC_GATE__SDB_MASK;
  1354. data |= UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK |
  1355. (1 << REG_FIELD_SHIFT(UVD_CGC_CTRL, CLK_GATE_DLY_TIMER)) |
  1356. (4 << REG_FIELD_SHIFT(UVD_CGC_CTRL, CLK_OFF_DELAY));
  1357. data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
  1358. UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
  1359. UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
  1360. UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
  1361. UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
  1362. UVD_CGC_CTRL__SYS_MODE_MASK |
  1363. UVD_CGC_CTRL__UDEC_MODE_MASK |
  1364. UVD_CGC_CTRL__MPEG2_MODE_MASK |
  1365. UVD_CGC_CTRL__REGS_MODE_MASK |
  1366. UVD_CGC_CTRL__RBC_MODE_MASK |
  1367. UVD_CGC_CTRL__LMI_MC_MODE_MASK |
  1368. UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
  1369. UVD_CGC_CTRL__IDCT_MODE_MASK |
  1370. UVD_CGC_CTRL__MPRD_MODE_MASK |
  1371. UVD_CGC_CTRL__MPC_MODE_MASK |
  1372. UVD_CGC_CTRL__LBSI_MODE_MASK |
  1373. UVD_CGC_CTRL__LRBBM_MODE_MASK |
  1374. UVD_CGC_CTRL__WCB_MODE_MASK |
  1375. UVD_CGC_CTRL__VCPU_MODE_MASK |
  1376. UVD_CGC_CTRL__JPEG_MODE_MASK |
  1377. UVD_CGC_CTRL__JPEG2_MODE_MASK |
  1378. UVD_CGC_CTRL__SCPU_MODE_MASK);
  1379. data2 &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK |
  1380. UVD_SUVD_CGC_CTRL__SIT_MODE_MASK |
  1381. UVD_SUVD_CGC_CTRL__SMP_MODE_MASK |
  1382. UVD_SUVD_CGC_CTRL__SCM_MODE_MASK |
  1383. UVD_SUVD_CGC_CTRL__SDB_MODE_MASK);
  1384. data1 |= suvd_flags;
  1385. WREG32_SOC15(UVD, ring->me, mmUVD_CGC_CTRL, data);
  1386. WREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE, 0);
  1387. WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE, data1);
  1388. WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_CTRL, data2);
  1389. }
  1390. static void uvd_v7_0_set_hw_clock_gating(struct amdgpu_device *adev)
  1391. {
  1392. uint32_t data, data1, cgc_flags, suvd_flags;
  1393. data = RREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE);
  1394. data1 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE);
  1395. cgc_flags = UVD_CGC_GATE__SYS_MASK |
  1396. UVD_CGC_GATE__UDEC_MASK |
  1397. UVD_CGC_GATE__MPEG2_MASK |
  1398. UVD_CGC_GATE__RBC_MASK |
  1399. UVD_CGC_GATE__LMI_MC_MASK |
  1400. UVD_CGC_GATE__IDCT_MASK |
  1401. UVD_CGC_GATE__MPRD_MASK |
  1402. UVD_CGC_GATE__MPC_MASK |
  1403. UVD_CGC_GATE__LBSI_MASK |
  1404. UVD_CGC_GATE__LRBBM_MASK |
  1405. UVD_CGC_GATE__UDEC_RE_MASK |
  1406. UVD_CGC_GATE__UDEC_CM_MASK |
  1407. UVD_CGC_GATE__UDEC_IT_MASK |
  1408. UVD_CGC_GATE__UDEC_DB_MASK |
  1409. UVD_CGC_GATE__UDEC_MP_MASK |
  1410. UVD_CGC_GATE__WCB_MASK |
  1411. UVD_CGC_GATE__VCPU_MASK |
  1412. UVD_CGC_GATE__SCPU_MASK |
  1413. UVD_CGC_GATE__JPEG_MASK |
  1414. UVD_CGC_GATE__JPEG2_MASK;
  1415. suvd_flags = UVD_SUVD_CGC_GATE__SRE_MASK |
  1416. UVD_SUVD_CGC_GATE__SIT_MASK |
  1417. UVD_SUVD_CGC_GATE__SMP_MASK |
  1418. UVD_SUVD_CGC_GATE__SCM_MASK |
  1419. UVD_SUVD_CGC_GATE__SDB_MASK;
  1420. data |= cgc_flags;
  1421. data1 |= suvd_flags;
  1422. WREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE, data);
  1423. WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE, data1);
  1424. }
  1425. static void uvd_v7_0_set_bypass_mode(struct amdgpu_device *adev, bool enable)
  1426. {
  1427. u32 tmp = RREG32_SMC(ixGCK_DFS_BYPASS_CNTL);
  1428. if (enable)
  1429. tmp |= (GCK_DFS_BYPASS_CNTL__BYPASSDCLK_MASK |
  1430. GCK_DFS_BYPASS_CNTL__BYPASSVCLK_MASK);
  1431. else
  1432. tmp &= ~(GCK_DFS_BYPASS_CNTL__BYPASSDCLK_MASK |
  1433. GCK_DFS_BYPASS_CNTL__BYPASSVCLK_MASK);
  1434. WREG32_SMC(ixGCK_DFS_BYPASS_CNTL, tmp);
  1435. }
  1436. static int uvd_v7_0_set_clockgating_state(void *handle,
  1437. enum amd_clockgating_state state)
  1438. {
  1439. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  1440. bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
  1441. uvd_v7_0_set_bypass_mode(adev, enable);
  1442. if (!(adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG))
  1443. return 0;
  1444. if (enable) {
  1445. /* disable HW gating and enable Sw gating */
  1446. uvd_v7_0_set_sw_clock_gating(adev);
  1447. } else {
  1448. /* wait for STATUS to clear */
  1449. if (uvd_v7_0_wait_for_idle(handle))
  1450. return -EBUSY;
  1451. /* enable HW gates because UVD is idle */
  1452. /* uvd_v7_0_set_hw_clock_gating(adev); */
  1453. }
  1454. return 0;
  1455. }
  1456. static int uvd_v7_0_set_powergating_state(void *handle,
  1457. enum amd_powergating_state state)
  1458. {
  1459. /* This doesn't actually powergate the UVD block.
  1460. * That's done in the dpm code via the SMC. This
  1461. * just re-inits the block as necessary. The actual
  1462. * gating still happens in the dpm code. We should
  1463. * revisit this when there is a cleaner line between
  1464. * the smc and the hw blocks
  1465. */
  1466. struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  1467. if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD))
  1468. return 0;
  1469. WREG32_SOC15(UVD, ring->me, mmUVD_POWER_STATUS, UVD_POWER_STATUS__UVD_PG_EN_MASK);
  1470. if (state == AMD_PG_STATE_GATE) {
  1471. uvd_v7_0_stop(adev);
  1472. return 0;
  1473. } else {
  1474. return uvd_v7_0_start(adev);
  1475. }
  1476. }
  1477. #endif
  1478. static int uvd_v7_0_set_clockgating_state(void *handle,
  1479. enum amd_clockgating_state state)
  1480. {
  1481. /* needed for driver unload*/
  1482. return 0;
  1483. }
  1484. const struct amd_ip_funcs uvd_v7_0_ip_funcs = {
  1485. .name = "uvd_v7_0",
  1486. .early_init = uvd_v7_0_early_init,
  1487. .late_init = NULL,
  1488. .sw_init = uvd_v7_0_sw_init,
  1489. .sw_fini = uvd_v7_0_sw_fini,
  1490. .hw_init = uvd_v7_0_hw_init,
  1491. .hw_fini = uvd_v7_0_hw_fini,
  1492. .suspend = uvd_v7_0_suspend,
  1493. .resume = uvd_v7_0_resume,
  1494. .is_idle = NULL /* uvd_v7_0_is_idle */,
  1495. .wait_for_idle = NULL /* uvd_v7_0_wait_for_idle */,
  1496. .check_soft_reset = NULL /* uvd_v7_0_check_soft_reset */,
  1497. .pre_soft_reset = NULL /* uvd_v7_0_pre_soft_reset */,
  1498. .soft_reset = NULL /* uvd_v7_0_soft_reset */,
  1499. .post_soft_reset = NULL /* uvd_v7_0_post_soft_reset */,
  1500. .set_clockgating_state = uvd_v7_0_set_clockgating_state,
  1501. .set_powergating_state = NULL /* uvd_v7_0_set_powergating_state */,
  1502. };
  1503. static const struct amdgpu_ring_funcs uvd_v7_0_ring_vm_funcs = {
  1504. .type = AMDGPU_RING_TYPE_UVD,
  1505. .align_mask = 0xf,
  1506. .support_64bit_ptrs = false,
  1507. .vmhub = AMDGPU_MMHUB,
  1508. .get_rptr = uvd_v7_0_ring_get_rptr,
  1509. .get_wptr = uvd_v7_0_ring_get_wptr,
  1510. .set_wptr = uvd_v7_0_ring_set_wptr,
  1511. .patch_cs_in_place = uvd_v7_0_ring_patch_cs_in_place,
  1512. .emit_frame_size =
  1513. 6 + /* hdp invalidate */
  1514. SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
  1515. SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
  1516. 8 + /* uvd_v7_0_ring_emit_vm_flush */
  1517. 14 + 14, /* uvd_v7_0_ring_emit_fence x2 vm fence */
  1518. .emit_ib_size = 8, /* uvd_v7_0_ring_emit_ib */
  1519. .emit_ib = uvd_v7_0_ring_emit_ib,
  1520. .emit_fence = uvd_v7_0_ring_emit_fence,
  1521. .emit_vm_flush = uvd_v7_0_ring_emit_vm_flush,
  1522. .emit_hdp_flush = uvd_v7_0_ring_emit_hdp_flush,
  1523. .test_ring = uvd_v7_0_ring_test_ring,
  1524. .test_ib = amdgpu_uvd_ring_test_ib,
  1525. .insert_nop = uvd_v7_0_ring_insert_nop,
  1526. .pad_ib = amdgpu_ring_generic_pad_ib,
  1527. .begin_use = amdgpu_uvd_ring_begin_use,
  1528. .end_use = amdgpu_uvd_ring_end_use,
  1529. .emit_wreg = uvd_v7_0_ring_emit_wreg,
  1530. .emit_reg_wait = uvd_v7_0_ring_emit_reg_wait,
  1531. .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
  1532. };
  1533. static const struct amdgpu_ring_funcs uvd_v7_0_enc_ring_vm_funcs = {
  1534. .type = AMDGPU_RING_TYPE_UVD_ENC,
  1535. .align_mask = 0x3f,
  1536. .nop = HEVC_ENC_CMD_NO_OP,
  1537. .support_64bit_ptrs = false,
  1538. .vmhub = AMDGPU_MMHUB,
  1539. .get_rptr = uvd_v7_0_enc_ring_get_rptr,
  1540. .get_wptr = uvd_v7_0_enc_ring_get_wptr,
  1541. .set_wptr = uvd_v7_0_enc_ring_set_wptr,
  1542. .emit_frame_size =
  1543. 3 + 3 + /* hdp flush / invalidate */
  1544. SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
  1545. SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
  1546. 4 + /* uvd_v7_0_enc_ring_emit_vm_flush */
  1547. 5 + 5 + /* uvd_v7_0_enc_ring_emit_fence x2 vm fence */
  1548. 1, /* uvd_v7_0_enc_ring_insert_end */
  1549. .emit_ib_size = 5, /* uvd_v7_0_enc_ring_emit_ib */
  1550. .emit_ib = uvd_v7_0_enc_ring_emit_ib,
  1551. .emit_fence = uvd_v7_0_enc_ring_emit_fence,
  1552. .emit_vm_flush = uvd_v7_0_enc_ring_emit_vm_flush,
  1553. .test_ring = uvd_v7_0_enc_ring_test_ring,
  1554. .test_ib = uvd_v7_0_enc_ring_test_ib,
  1555. .insert_nop = amdgpu_ring_insert_nop,
  1556. .insert_end = uvd_v7_0_enc_ring_insert_end,
  1557. .pad_ib = amdgpu_ring_generic_pad_ib,
  1558. .begin_use = amdgpu_uvd_ring_begin_use,
  1559. .end_use = amdgpu_uvd_ring_end_use,
  1560. .emit_wreg = uvd_v7_0_enc_ring_emit_wreg,
  1561. .emit_reg_wait = uvd_v7_0_enc_ring_emit_reg_wait,
  1562. .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
  1563. };
  1564. static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev)
  1565. {
  1566. int i;
  1567. for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
  1568. if (adev->uvd.harvest_config & (1 << i))
  1569. continue;
  1570. adev->uvd.inst[i].ring.funcs = &uvd_v7_0_ring_vm_funcs;
  1571. adev->uvd.inst[i].ring.me = i;
  1572. DRM_INFO("UVD(%d) is enabled in VM mode\n", i);
  1573. }
  1574. }
  1575. static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev)
  1576. {
  1577. int i, j;
  1578. for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
  1579. if (adev->uvd.harvest_config & (1 << j))
  1580. continue;
  1581. for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
  1582. adev->uvd.inst[j].ring_enc[i].funcs = &uvd_v7_0_enc_ring_vm_funcs;
  1583. adev->uvd.inst[j].ring_enc[i].me = j;
  1584. }
  1585. DRM_INFO("UVD(%d) ENC is enabled in VM mode\n", j);
  1586. }
  1587. }
  1588. static const struct amdgpu_irq_src_funcs uvd_v7_0_irq_funcs = {
  1589. .set = uvd_v7_0_set_interrupt_state,
  1590. .process = uvd_v7_0_process_interrupt,
  1591. };
  1592. static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev)
  1593. {
  1594. int i;
  1595. for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
  1596. if (adev->uvd.harvest_config & (1 << i))
  1597. continue;
  1598. adev->uvd.inst[i].irq.num_types = adev->uvd.num_enc_rings + 1;
  1599. adev->uvd.inst[i].irq.funcs = &uvd_v7_0_irq_funcs;
  1600. }
  1601. }
  1602. const struct amdgpu_ip_block_version uvd_v7_0_ip_block =
  1603. {
  1604. .type = AMD_IP_BLOCK_TYPE_UVD,
  1605. .major = 7,
  1606. .minor = 0,
  1607. .rev = 0,
  1608. .funcs = &uvd_v7_0_ip_funcs,
  1609. };