kfd_mqd_manager_cik.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. /*
  2. * Copyright 2014 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/printk.h>
  24. #include <linux/slab.h>
  25. #include "kfd_priv.h"
  26. #include "kfd_mqd_manager.h"
  27. #include "cik_regs.h"
  28. #include "cik_structs.h"
  29. static inline struct cik_mqd *get_mqd(void *mqd)
  30. {
  31. return (struct cik_mqd *)mqd;
  32. }
  33. static int init_mqd(struct mqd_manager *mm, void **mqd,
  34. struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
  35. struct queue_properties *q)
  36. {
  37. uint64_t addr;
  38. struct cik_mqd *m;
  39. int retval;
  40. BUG_ON(!mm || !q || !mqd);
  41. pr_debug("kfd: In func %s\n", __func__);
  42. retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct cik_mqd),
  43. mqd_mem_obj);
  44. if (retval != 0)
  45. return -ENOMEM;
  46. m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr;
  47. addr = (*mqd_mem_obj)->gpu_addr;
  48. memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256));
  49. m->header = 0xC0310800;
  50. m->compute_pipelinestat_enable = 1;
  51. m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF;
  52. m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF;
  53. m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF;
  54. m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF;
  55. /*
  56. * Make sure to use the last queue state saved on mqd when the cp
  57. * reassigns the queue, so when queue is switched on/off (e.g over
  58. * subscription or quantum timeout) the context will be consistent
  59. */
  60. m->cp_hqd_persistent_state =
  61. DEFAULT_CP_HQD_PERSISTENT_STATE | PRELOAD_REQ;
  62. m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN;
  63. m->cp_mqd_base_addr_lo = lower_32_bits(addr);
  64. m->cp_mqd_base_addr_hi = upper_32_bits(addr);
  65. m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE | IB_ATC_EN;
  66. /* Although WinKFD writes this, I suspect it should not be necessary */
  67. m->cp_hqd_ib_control = IB_ATC_EN | DEFAULT_MIN_IB_AVAIL_SIZE;
  68. m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS |
  69. QUANTUM_DURATION(10);
  70. /*
  71. * Pipe Priority
  72. * Identifies the pipe relative priority when this queue is connected
  73. * to the pipeline. The pipe priority is against the GFX pipe and HP3D.
  74. * In KFD we are using a fixed pipe priority set to CS_MEDIUM.
  75. * 0 = CS_LOW (typically below GFX)
  76. * 1 = CS_MEDIUM (typically between HP3D and GFX
  77. * 2 = CS_HIGH (typically above HP3D)
  78. */
  79. m->cp_hqd_pipe_priority = 1;
  80. m->cp_hqd_queue_priority = 15;
  81. if (q->format == KFD_QUEUE_FORMAT_AQL)
  82. m->cp_hqd_iq_rptr = AQL_ENABLE;
  83. *mqd = m;
  84. if (gart_addr != NULL)
  85. *gart_addr = addr;
  86. retval = mm->update_mqd(mm, m, q);
  87. return retval;
  88. }
  89. static int init_mqd_sdma(struct mqd_manager *mm, void **mqd,
  90. struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
  91. struct queue_properties *q)
  92. {
  93. int retval;
  94. struct cik_sdma_rlc_registers *m;
  95. BUG_ON(!mm || !mqd || !mqd_mem_obj);
  96. retval = kfd_gtt_sa_allocate(mm->dev,
  97. sizeof(struct cik_sdma_rlc_registers),
  98. mqd_mem_obj);
  99. if (retval != 0)
  100. return -ENOMEM;
  101. m = (struct cik_sdma_rlc_registers *) (*mqd_mem_obj)->cpu_ptr;
  102. memset(m, 0, sizeof(struct cik_sdma_rlc_registers));
  103. *mqd = m;
  104. if (gart_addr != NULL)
  105. *gart_addr = (*mqd_mem_obj)->gpu_addr;
  106. retval = mm->update_mqd(mm, m, q);
  107. return retval;
  108. }
  109. static void uninit_mqd(struct mqd_manager *mm, void *mqd,
  110. struct kfd_mem_obj *mqd_mem_obj)
  111. {
  112. BUG_ON(!mm || !mqd);
  113. kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
  114. }
  115. static void uninit_mqd_sdma(struct mqd_manager *mm, void *mqd,
  116. struct kfd_mem_obj *mqd_mem_obj)
  117. {
  118. BUG_ON(!mm || !mqd);
  119. kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
  120. }
  121. static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id,
  122. uint32_t queue_id, uint32_t __user *wptr)
  123. {
  124. return mm->dev->kfd2kgd->hqd_load
  125. (mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
  126. }
  127. static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
  128. uint32_t pipe_id, uint32_t queue_id,
  129. uint32_t __user *wptr)
  130. {
  131. return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd);
  132. }
  133. static int update_mqd(struct mqd_manager *mm, void *mqd,
  134. struct queue_properties *q)
  135. {
  136. struct cik_mqd *m;
  137. BUG_ON(!mm || !q || !mqd);
  138. pr_debug("kfd: In func %s\n", __func__);
  139. m = get_mqd(mqd);
  140. m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
  141. DEFAULT_MIN_AVAIL_SIZE | PQ_ATC_EN;
  142. /*
  143. * Calculating queue size which is log base 2 of actual queue size -1
  144. * dwords and another -1 for ffs
  145. */
  146. m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int))
  147. - 1 - 1;
  148. m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
  149. m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
  150. m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
  151. m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
  152. m->cp_hqd_pq_doorbell_control = DOORBELL_EN |
  153. DOORBELL_OFFSET(q->doorbell_off);
  154. m->cp_hqd_vmid = q->vmid;
  155. if (q->format == KFD_QUEUE_FORMAT_AQL) {
  156. m->cp_hqd_pq_control |= NO_UPDATE_RPTR;
  157. }
  158. m->cp_hqd_active = 0;
  159. q->is_active = false;
  160. if (q->queue_size > 0 &&
  161. q->queue_address != 0 &&
  162. q->queue_percent > 0) {
  163. m->cp_hqd_active = 1;
  164. q->is_active = true;
  165. }
  166. return 0;
  167. }
  168. static int update_mqd_sdma(struct mqd_manager *mm, void *mqd,
  169. struct queue_properties *q)
  170. {
  171. struct cik_sdma_rlc_registers *m;
  172. BUG_ON(!mm || !mqd || !q);
  173. m = get_sdma_mqd(mqd);
  174. m->sdma_rlc_rb_cntl =
  175. SDMA_RB_SIZE((ffs(q->queue_size / sizeof(unsigned int)))) |
  176. SDMA_RB_VMID(q->vmid) |
  177. SDMA_RPTR_WRITEBACK_ENABLE |
  178. SDMA_RPTR_WRITEBACK_TIMER(6);
  179. m->sdma_rlc_rb_base = lower_32_bits(q->queue_address >> 8);
  180. m->sdma_rlc_rb_base_hi = upper_32_bits(q->queue_address >> 8);
  181. m->sdma_rlc_rb_rptr_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
  182. m->sdma_rlc_rb_rptr_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
  183. m->sdma_rlc_doorbell = SDMA_OFFSET(q->doorbell_off) | SDMA_DB_ENABLE;
  184. m->sdma_rlc_virtual_addr = q->sdma_vm_addr;
  185. m->sdma_engine_id = q->sdma_engine_id;
  186. m->sdma_queue_id = q->sdma_queue_id;
  187. q->is_active = false;
  188. if (q->queue_size > 0 &&
  189. q->queue_address != 0 &&
  190. q->queue_percent > 0) {
  191. m->sdma_rlc_rb_cntl |= SDMA_RB_ENABLE;
  192. q->is_active = true;
  193. }
  194. return 0;
  195. }
  196. static int destroy_mqd(struct mqd_manager *mm, void *mqd,
  197. enum kfd_preempt_type type,
  198. unsigned int timeout, uint32_t pipe_id,
  199. uint32_t queue_id)
  200. {
  201. return mm->dev->kfd2kgd->hqd_destroy(mm->dev->kgd, type, timeout,
  202. pipe_id, queue_id);
  203. }
  204. /*
  205. * preempt type here is ignored because there is only one way
  206. * to preempt sdma queue
  207. */
  208. static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
  209. enum kfd_preempt_type type,
  210. unsigned int timeout, uint32_t pipe_id,
  211. uint32_t queue_id)
  212. {
  213. return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout);
  214. }
  215. static bool is_occupied(struct mqd_manager *mm, void *mqd,
  216. uint64_t queue_address, uint32_t pipe_id,
  217. uint32_t queue_id)
  218. {
  219. return mm->dev->kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address,
  220. pipe_id, queue_id);
  221. }
  222. static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
  223. uint64_t queue_address, uint32_t pipe_id,
  224. uint32_t queue_id)
  225. {
  226. return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd);
  227. }
  228. /*
  229. * HIQ MQD Implementation, concrete implementation for HIQ MQD implementation.
  230. * The HIQ queue in Kaveri is using the same MQD structure as all the user mode
  231. * queues but with different initial values.
  232. */
  233. static int init_mqd_hiq(struct mqd_manager *mm, void **mqd,
  234. struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
  235. struct queue_properties *q)
  236. {
  237. uint64_t addr;
  238. struct cik_mqd *m;
  239. int retval;
  240. BUG_ON(!mm || !q || !mqd || !mqd_mem_obj);
  241. pr_debug("kfd: In func %s\n", __func__);
  242. retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct cik_mqd),
  243. mqd_mem_obj);
  244. if (retval != 0)
  245. return -ENOMEM;
  246. m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr;
  247. addr = (*mqd_mem_obj)->gpu_addr;
  248. memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256));
  249. m->header = 0xC0310800;
  250. m->compute_pipelinestat_enable = 1;
  251. m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF;
  252. m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF;
  253. m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF;
  254. m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF;
  255. m->cp_hqd_persistent_state = DEFAULT_CP_HQD_PERSISTENT_STATE |
  256. PRELOAD_REQ;
  257. m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS |
  258. QUANTUM_DURATION(10);
  259. m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN;
  260. m->cp_mqd_base_addr_lo = lower_32_bits(addr);
  261. m->cp_mqd_base_addr_hi = upper_32_bits(addr);
  262. m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE;
  263. /*
  264. * Pipe Priority
  265. * Identifies the pipe relative priority when this queue is connected
  266. * to the pipeline. The pipe priority is against the GFX pipe and HP3D.
  267. * In KFD we are using a fixed pipe priority set to CS_MEDIUM.
  268. * 0 = CS_LOW (typically below GFX)
  269. * 1 = CS_MEDIUM (typically between HP3D and GFX
  270. * 2 = CS_HIGH (typically above HP3D)
  271. */
  272. m->cp_hqd_pipe_priority = 1;
  273. m->cp_hqd_queue_priority = 15;
  274. *mqd = m;
  275. if (gart_addr)
  276. *gart_addr = addr;
  277. retval = mm->update_mqd(mm, m, q);
  278. return retval;
  279. }
  280. static int update_mqd_hiq(struct mqd_manager *mm, void *mqd,
  281. struct queue_properties *q)
  282. {
  283. struct cik_mqd *m;
  284. BUG_ON(!mm || !q || !mqd);
  285. pr_debug("kfd: In func %s\n", __func__);
  286. m = get_mqd(mqd);
  287. m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
  288. DEFAULT_MIN_AVAIL_SIZE |
  289. PRIV_STATE |
  290. KMD_QUEUE;
  291. /*
  292. * Calculating queue size which is log base 2 of actual queue
  293. * size -1 dwords
  294. */
  295. m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int))
  296. - 1 - 1;
  297. m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
  298. m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
  299. m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
  300. m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
  301. m->cp_hqd_pq_doorbell_control = DOORBELL_EN |
  302. DOORBELL_OFFSET(q->doorbell_off);
  303. m->cp_hqd_vmid = q->vmid;
  304. m->cp_hqd_active = 0;
  305. q->is_active = false;
  306. if (q->queue_size > 0 &&
  307. q->queue_address != 0 &&
  308. q->queue_percent > 0) {
  309. m->cp_hqd_active = 1;
  310. q->is_active = true;
  311. }
  312. return 0;
  313. }
  314. struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
  315. {
  316. struct cik_sdma_rlc_registers *m;
  317. BUG_ON(!mqd);
  318. m = (struct cik_sdma_rlc_registers *)mqd;
  319. return m;
  320. }
  321. struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
  322. struct kfd_dev *dev)
  323. {
  324. struct mqd_manager *mqd;
  325. BUG_ON(!dev);
  326. BUG_ON(type >= KFD_MQD_TYPE_MAX);
  327. pr_debug("kfd: In func %s\n", __func__);
  328. mqd = kzalloc(sizeof(struct mqd_manager), GFP_KERNEL);
  329. if (!mqd)
  330. return NULL;
  331. mqd->dev = dev;
  332. switch (type) {
  333. case KFD_MQD_TYPE_CP:
  334. case KFD_MQD_TYPE_COMPUTE:
  335. mqd->init_mqd = init_mqd;
  336. mqd->uninit_mqd = uninit_mqd;
  337. mqd->load_mqd = load_mqd;
  338. mqd->update_mqd = update_mqd;
  339. mqd->destroy_mqd = destroy_mqd;
  340. mqd->is_occupied = is_occupied;
  341. break;
  342. case KFD_MQD_TYPE_HIQ:
  343. mqd->init_mqd = init_mqd_hiq;
  344. mqd->uninit_mqd = uninit_mqd;
  345. mqd->load_mqd = load_mqd;
  346. mqd->update_mqd = update_mqd_hiq;
  347. mqd->destroy_mqd = destroy_mqd;
  348. mqd->is_occupied = is_occupied;
  349. break;
  350. case KFD_MQD_TYPE_SDMA:
  351. mqd->init_mqd = init_mqd_sdma;
  352. mqd->uninit_mqd = uninit_mqd_sdma;
  353. mqd->load_mqd = load_mqd_sdma;
  354. mqd->update_mqd = update_mqd_sdma;
  355. mqd->destroy_mqd = destroy_mqd_sdma;
  356. mqd->is_occupied = is_occupied_sdma;
  357. break;
  358. default:
  359. kfree(mqd);
  360. return NULL;
  361. }
  362. return mqd;
  363. }