etnaviv_mmu.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. /*
  2. * Copyright (C) 2015 Etnaviv Project
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License version 2 as published by
  6. * the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful, but WITHOUT
  9. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. * more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along with
  14. * this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "common.xml.h"
  17. #include "etnaviv_drv.h"
  18. #include "etnaviv_gem.h"
  19. #include "etnaviv_gpu.h"
  20. #include "etnaviv_iommu.h"
  21. #include "etnaviv_mmu.h"
  22. static int etnaviv_fault_handler(struct iommu_domain *iommu, struct device *dev,
  23. unsigned long iova, int flags, void *arg)
  24. {
  25. DBG("*** fault: iova=%08lx, flags=%d", iova, flags);
  26. return 0;
  27. }
  28. int etnaviv_iommu_map(struct etnaviv_iommu *iommu, u32 iova,
  29. struct sg_table *sgt, unsigned len, int prot)
  30. {
  31. struct iommu_domain *domain = iommu->domain;
  32. struct scatterlist *sg;
  33. unsigned int da = iova;
  34. unsigned int i, j;
  35. int ret;
  36. if (!domain || !sgt)
  37. return -EINVAL;
  38. for_each_sg(sgt->sgl, sg, sgt->nents, i) {
  39. u32 pa = sg_dma_address(sg) - sg->offset;
  40. size_t bytes = sg_dma_len(sg) + sg->offset;
  41. VERB("map[%d]: %08x %08x(%zx)", i, iova, pa, bytes);
  42. ret = iommu_map(domain, da, pa, bytes, prot);
  43. if (ret)
  44. goto fail;
  45. da += bytes;
  46. }
  47. return 0;
  48. fail:
  49. da = iova;
  50. for_each_sg(sgt->sgl, sg, i, j) {
  51. size_t bytes = sg_dma_len(sg) + sg->offset;
  52. iommu_unmap(domain, da, bytes);
  53. da += bytes;
  54. }
  55. return ret;
  56. }
  57. int etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova,
  58. struct sg_table *sgt, unsigned len)
  59. {
  60. struct iommu_domain *domain = iommu->domain;
  61. struct scatterlist *sg;
  62. unsigned int da = iova;
  63. int i;
  64. for_each_sg(sgt->sgl, sg, sgt->nents, i) {
  65. size_t bytes = sg_dma_len(sg) + sg->offset;
  66. size_t unmapped;
  67. unmapped = iommu_unmap(domain, da, bytes);
  68. if (unmapped < bytes)
  69. return unmapped;
  70. VERB("unmap[%d]: %08x(%zx)", i, iova, bytes);
  71. BUG_ON(!PAGE_ALIGNED(bytes));
  72. da += bytes;
  73. }
  74. return 0;
  75. }
  76. static void etnaviv_iommu_remove_mapping(struct etnaviv_iommu *mmu,
  77. struct etnaviv_vram_mapping *mapping)
  78. {
  79. struct etnaviv_gem_object *etnaviv_obj = mapping->object;
  80. etnaviv_iommu_unmap(mmu, mapping->vram_node.start,
  81. etnaviv_obj->sgt, etnaviv_obj->base.size);
  82. drm_mm_remove_node(&mapping->vram_node);
  83. }
  84. static int etnaviv_iommu_find_iova(struct etnaviv_iommu *mmu,
  85. struct drm_mm_node *node, size_t size)
  86. {
  87. struct etnaviv_vram_mapping *free = NULL;
  88. int ret;
  89. lockdep_assert_held(&mmu->lock);
  90. while (1) {
  91. struct etnaviv_vram_mapping *m, *n;
  92. struct drm_mm_scan scan;
  93. struct list_head list;
  94. bool found;
  95. /*
  96. * XXX: The DRM_MM_SEARCH_BELOW is really a hack to trick
  97. * drm_mm into giving out a low IOVA after address space
  98. * rollover. This needs a proper fix.
  99. */
  100. ret = drm_mm_insert_node_in_range(&mmu->mm, node,
  101. size, 0, mmu->last_iova, ~0UL,
  102. mmu->last_iova ? DRM_MM_SEARCH_DEFAULT : DRM_MM_SEARCH_BELOW);
  103. if (ret != -ENOSPC)
  104. break;
  105. /*
  106. * If we did not search from the start of the MMU region,
  107. * try again in case there are free slots.
  108. */
  109. if (mmu->last_iova) {
  110. mmu->last_iova = 0;
  111. mmu->need_flush = true;
  112. continue;
  113. }
  114. /* Try to retire some entries */
  115. drm_mm_scan_init(&scan, &mmu->mm, size, 0, 0, 0);
  116. found = 0;
  117. INIT_LIST_HEAD(&list);
  118. list_for_each_entry(free, &mmu->mappings, mmu_node) {
  119. /* If this vram node has not been used, skip this. */
  120. if (!free->vram_node.mm)
  121. continue;
  122. /*
  123. * If the iova is pinned, then it's in-use,
  124. * so we must keep its mapping.
  125. */
  126. if (free->use)
  127. continue;
  128. list_add(&free->scan_node, &list);
  129. if (drm_mm_scan_add_block(&scan, &free->vram_node)) {
  130. found = true;
  131. break;
  132. }
  133. }
  134. if (!found) {
  135. /* Nothing found, clean up and fail */
  136. list_for_each_entry_safe(m, n, &list, scan_node)
  137. BUG_ON(drm_mm_scan_remove_block(&scan, &m->vram_node));
  138. break;
  139. }
  140. /*
  141. * drm_mm does not allow any other operations while
  142. * scanning, so we have to remove all blocks first.
  143. * If drm_mm_scan_remove_block() returns false, we
  144. * can leave the block pinned.
  145. */
  146. list_for_each_entry_safe(m, n, &list, scan_node)
  147. if (!drm_mm_scan_remove_block(&scan, &m->vram_node))
  148. list_del_init(&m->scan_node);
  149. /*
  150. * Unmap the blocks which need to be reaped from the MMU.
  151. * Clear the mmu pointer to prevent the mapping_get finding
  152. * this mapping.
  153. */
  154. list_for_each_entry_safe(m, n, &list, scan_node) {
  155. etnaviv_iommu_remove_mapping(mmu, m);
  156. m->mmu = NULL;
  157. list_del_init(&m->mmu_node);
  158. list_del_init(&m->scan_node);
  159. }
  160. /*
  161. * We removed enough mappings so that the new allocation will
  162. * succeed. Ensure that the MMU will be flushed before the
  163. * associated commit requesting this mapping, and retry the
  164. * allocation one more time.
  165. */
  166. mmu->need_flush = true;
  167. }
  168. return ret;
  169. }
  170. int etnaviv_iommu_map_gem(struct etnaviv_iommu *mmu,
  171. struct etnaviv_gem_object *etnaviv_obj, u32 memory_base,
  172. struct etnaviv_vram_mapping *mapping)
  173. {
  174. struct sg_table *sgt = etnaviv_obj->sgt;
  175. struct drm_mm_node *node;
  176. int ret;
  177. lockdep_assert_held(&etnaviv_obj->lock);
  178. mutex_lock(&mmu->lock);
  179. /* v1 MMU can optimize single entry (contiguous) scatterlists */
  180. if (mmu->version == ETNAVIV_IOMMU_V1 &&
  181. sgt->nents == 1 && !(etnaviv_obj->flags & ETNA_BO_FORCE_MMU)) {
  182. u32 iova;
  183. iova = sg_dma_address(sgt->sgl) - memory_base;
  184. if (iova < 0x80000000 - sg_dma_len(sgt->sgl)) {
  185. mapping->iova = iova;
  186. list_add_tail(&mapping->mmu_node, &mmu->mappings);
  187. mutex_unlock(&mmu->lock);
  188. return 0;
  189. }
  190. }
  191. node = &mapping->vram_node;
  192. ret = etnaviv_iommu_find_iova(mmu, node, etnaviv_obj->base.size);
  193. if (ret < 0) {
  194. mutex_unlock(&mmu->lock);
  195. return ret;
  196. }
  197. mmu->last_iova = node->start + etnaviv_obj->base.size;
  198. mapping->iova = node->start;
  199. ret = etnaviv_iommu_map(mmu, node->start, sgt, etnaviv_obj->base.size,
  200. IOMMU_READ | IOMMU_WRITE);
  201. if (ret < 0) {
  202. drm_mm_remove_node(node);
  203. mutex_unlock(&mmu->lock);
  204. return ret;
  205. }
  206. list_add_tail(&mapping->mmu_node, &mmu->mappings);
  207. mutex_unlock(&mmu->lock);
  208. return ret;
  209. }
  210. void etnaviv_iommu_unmap_gem(struct etnaviv_iommu *mmu,
  211. struct etnaviv_vram_mapping *mapping)
  212. {
  213. WARN_ON(mapping->use);
  214. mutex_lock(&mmu->lock);
  215. /* If the vram node is on the mm, unmap and remove the node */
  216. if (mapping->vram_node.mm == &mmu->mm)
  217. etnaviv_iommu_remove_mapping(mmu, mapping);
  218. list_del(&mapping->mmu_node);
  219. mutex_unlock(&mmu->lock);
  220. }
  221. void etnaviv_iommu_destroy(struct etnaviv_iommu *mmu)
  222. {
  223. drm_mm_takedown(&mmu->mm);
  224. iommu_domain_free(mmu->domain);
  225. kfree(mmu);
  226. }
  227. struct etnaviv_iommu *etnaviv_iommu_new(struct etnaviv_gpu *gpu)
  228. {
  229. enum etnaviv_iommu_version version;
  230. struct etnaviv_iommu *mmu;
  231. mmu = kzalloc(sizeof(*mmu), GFP_KERNEL);
  232. if (!mmu)
  233. return ERR_PTR(-ENOMEM);
  234. if (!(gpu->identity.minor_features1 & chipMinorFeatures1_MMU_VERSION)) {
  235. mmu->domain = etnaviv_iommuv1_domain_alloc(gpu);
  236. version = ETNAVIV_IOMMU_V1;
  237. } else {
  238. mmu->domain = etnaviv_iommuv2_domain_alloc(gpu);
  239. version = ETNAVIV_IOMMU_V2;
  240. }
  241. if (!mmu->domain) {
  242. dev_err(gpu->dev, "Failed to allocate GPU IOMMU domain\n");
  243. kfree(mmu);
  244. return ERR_PTR(-ENOMEM);
  245. }
  246. mmu->gpu = gpu;
  247. mmu->version = version;
  248. mutex_init(&mmu->lock);
  249. INIT_LIST_HEAD(&mmu->mappings);
  250. drm_mm_init(&mmu->mm, mmu->domain->geometry.aperture_start,
  251. mmu->domain->geometry.aperture_end -
  252. mmu->domain->geometry.aperture_start + 1);
  253. iommu_set_fault_handler(mmu->domain, etnaviv_fault_handler, gpu->dev);
  254. return mmu;
  255. }
  256. void etnaviv_iommu_restore(struct etnaviv_gpu *gpu)
  257. {
  258. if (gpu->mmu->version == ETNAVIV_IOMMU_V1)
  259. etnaviv_iommuv1_restore(gpu);
  260. else
  261. etnaviv_iommuv2_restore(gpu);
  262. }
  263. u32 etnaviv_iommu_get_cmdbuf_va(struct etnaviv_gpu *gpu,
  264. struct etnaviv_cmdbuf *buf)
  265. {
  266. struct etnaviv_iommu *mmu = gpu->mmu;
  267. if (mmu->version == ETNAVIV_IOMMU_V1) {
  268. return buf->paddr - gpu->memory_base;
  269. } else {
  270. int ret;
  271. if (buf->vram_node.allocated)
  272. return (u32)buf->vram_node.start;
  273. mutex_lock(&mmu->lock);
  274. ret = etnaviv_iommu_find_iova(mmu, &buf->vram_node,
  275. buf->size + SZ_64K);
  276. if (ret < 0) {
  277. mutex_unlock(&mmu->lock);
  278. return 0;
  279. }
  280. ret = iommu_map(mmu->domain, buf->vram_node.start, buf->paddr,
  281. buf->size, IOMMU_READ);
  282. if (ret < 0) {
  283. drm_mm_remove_node(&buf->vram_node);
  284. mutex_unlock(&mmu->lock);
  285. return 0;
  286. }
  287. /*
  288. * At least on GC3000 the FE MMU doesn't properly flush old TLB
  289. * entries. Make sure to space the command buffers out in a way
  290. * that the FE MMU prefetch won't load invalid entries.
  291. */
  292. mmu->last_iova = buf->vram_node.start + buf->size + SZ_64K;
  293. gpu->mmu->need_flush = true;
  294. mutex_unlock(&mmu->lock);
  295. return (u32)buf->vram_node.start;
  296. }
  297. }
  298. void etnaviv_iommu_put_cmdbuf_va(struct etnaviv_gpu *gpu,
  299. struct etnaviv_cmdbuf *buf)
  300. {
  301. struct etnaviv_iommu *mmu = gpu->mmu;
  302. if (mmu->version == ETNAVIV_IOMMU_V2 && buf->vram_node.allocated) {
  303. mutex_lock(&mmu->lock);
  304. iommu_unmap(mmu->domain, buf->vram_node.start, buf->size);
  305. drm_mm_remove_node(&buf->vram_node);
  306. mutex_unlock(&mmu->lock);
  307. }
  308. }
  309. size_t etnaviv_iommu_dump_size(struct etnaviv_iommu *iommu)
  310. {
  311. struct etnaviv_iommu_ops *ops;
  312. ops = container_of(iommu->domain->ops, struct etnaviv_iommu_ops, ops);
  313. return ops->dump_size(iommu->domain);
  314. }
  315. void etnaviv_iommu_dump(struct etnaviv_iommu *iommu, void *buf)
  316. {
  317. struct etnaviv_iommu_ops *ops;
  318. ops = container_of(iommu->domain->ops, struct etnaviv_iommu_ops, ops);
  319. ops->dump(iommu->domain, buf);
  320. }