uvd_v7_0.c 51 KB

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