gtt.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2007, Intel Corporation.
  4. * All Rights Reserved.
  5. *
  6. * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
  7. * Alan Cox <alan@linux.intel.com>
  8. */
  9. #include "gem.h" /* TODO: for struct psb_gem_object, see psb_gtt_restore() */
  10. #include "psb_drv.h"
  11. /*
  12. * GTT resource allocator - manage page mappings in GTT space
  13. */
  14. int psb_gtt_allocate_resource(struct drm_psb_private *pdev, struct resource *res,
  15. const char *name, resource_size_t size, resource_size_t align,
  16. bool stolen, u32 *offset)
  17. {
  18. struct resource *root = pdev->gtt_mem;
  19. resource_size_t start, end;
  20. int ret;
  21. if (stolen) {
  22. /* The start of the GTT is backed by stolen pages. */
  23. start = root->start;
  24. end = root->start + pdev->gtt.stolen_size - 1;
  25. } else {
  26. /* The rest is backed by system pages. */
  27. start = root->start + pdev->gtt.stolen_size;
  28. end = root->end;
  29. }
  30. res->name = name;
  31. ret = allocate_resource(root, res, size, start, end, align, NULL, NULL);
  32. if (ret)
  33. return ret;
  34. *offset = res->start - root->start;
  35. return 0;
  36. }
  37. /**
  38. * psb_gtt_mask_pte - generate GTT pte entry
  39. * @pfn: page number to encode
  40. * @type: type of memory in the GTT
  41. *
  42. * Set the GTT entry for the appropriate memory type.
  43. */
  44. uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
  45. {
  46. uint32_t mask = PSB_PTE_VALID;
  47. /* Ensure we explode rather than put an invalid low mapping of
  48. a high mapping page into the gtt */
  49. BUG_ON(pfn & ~(0xFFFFFFFF >> PAGE_SHIFT));
  50. if (type & PSB_MMU_CACHED_MEMORY)
  51. mask |= PSB_PTE_CACHED;
  52. if (type & PSB_MMU_RO_MEMORY)
  53. mask |= PSB_PTE_RO;
  54. if (type & PSB_MMU_WO_MEMORY)
  55. mask |= PSB_PTE_WO;
  56. return (pfn << PAGE_SHIFT) | mask;
  57. }
  58. static u32 __iomem *psb_gtt_entry(struct drm_psb_private *pdev, const struct resource *res)
  59. {
  60. unsigned long offset = res->start - pdev->gtt_mem->start;
  61. return pdev->gtt_map + (offset >> PAGE_SHIFT);
  62. }
  63. /* Acquires GTT mutex internally. */
  64. void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *res,
  65. struct page **pages)
  66. {
  67. resource_size_t npages, i;
  68. u32 __iomem *gtt_slot;
  69. u32 pte;
  70. mutex_lock(&pdev->gtt_mutex);
  71. /* Write our page entries into the GTT itself */
  72. npages = resource_size(res) >> PAGE_SHIFT;
  73. gtt_slot = psb_gtt_entry(pdev, res);
  74. for (i = 0; i < npages; ++i, ++gtt_slot) {
  75. pte = psb_gtt_mask_pte(page_to_pfn(pages[i]), PSB_MMU_CACHED_MEMORY);
  76. iowrite32(pte, gtt_slot);
  77. }
  78. /* Make sure all the entries are set before we return */
  79. ioread32(gtt_slot - 1);
  80. mutex_unlock(&pdev->gtt_mutex);
  81. }
  82. /* Acquires GTT mutex internally. */
  83. void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *res)
  84. {
  85. resource_size_t npages, i;
  86. u32 __iomem *gtt_slot;
  87. u32 pte;
  88. mutex_lock(&pdev->gtt_mutex);
  89. /* Install scratch page for the resource */
  90. pte = psb_gtt_mask_pte(page_to_pfn(pdev->scratch_page), PSB_MMU_CACHED_MEMORY);
  91. npages = resource_size(res) >> PAGE_SHIFT;
  92. gtt_slot = psb_gtt_entry(pdev, res);
  93. for (i = 0; i < npages; ++i, ++gtt_slot)
  94. iowrite32(pte, gtt_slot);
  95. /* Make sure all the entries are set before we return */
  96. ioread32(gtt_slot - 1);
  97. mutex_unlock(&pdev->gtt_mutex);
  98. }
  99. static int psb_gtt_enable(struct drm_psb_private *dev_priv)
  100. {
  101. struct drm_device *dev = &dev_priv->dev;
  102. struct pci_dev *pdev = to_pci_dev(dev->dev);
  103. int ret;
  104. ret = pci_read_config_word(pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
  105. if (ret)
  106. return pcibios_err_to_errno(ret);
  107. ret = pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
  108. if (ret)
  109. return pcibios_err_to_errno(ret);
  110. dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
  111. PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
  112. (void)PSB_RVDC32(PSB_PGETBL_CTL);
  113. return 0;
  114. }
  115. static void psb_gtt_disable(struct drm_psb_private *dev_priv)
  116. {
  117. struct drm_device *dev = &dev_priv->dev;
  118. struct pci_dev *pdev = to_pci_dev(dev->dev);
  119. pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl);
  120. PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
  121. (void)PSB_RVDC32(PSB_PGETBL_CTL);
  122. }
  123. void psb_gtt_fini(struct drm_device *dev)
  124. {
  125. struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
  126. iounmap(dev_priv->gtt_map);
  127. psb_gtt_disable(dev_priv);
  128. mutex_destroy(&dev_priv->gtt_mutex);
  129. }
  130. /* Clear GTT. Use a scratch page to avoid accidents or scribbles. */
  131. static void psb_gtt_clear(struct drm_psb_private *pdev)
  132. {
  133. resource_size_t pfn_base;
  134. unsigned long i;
  135. uint32_t pte;
  136. pfn_base = page_to_pfn(pdev->scratch_page);
  137. pte = psb_gtt_mask_pte(pfn_base, PSB_MMU_CACHED_MEMORY);
  138. for (i = 0; i < pdev->gtt.gtt_pages; ++i)
  139. iowrite32(pte, pdev->gtt_map + i);
  140. (void)ioread32(pdev->gtt_map + i - 1);
  141. }
  142. static void psb_gtt_init_ranges(struct drm_psb_private *dev_priv)
  143. {
  144. struct drm_device *dev = &dev_priv->dev;
  145. struct pci_dev *pdev = to_pci_dev(dev->dev);
  146. struct psb_gtt *pg = &dev_priv->gtt;
  147. resource_size_t gtt_phys_start, mmu_gatt_start, gtt_start, gtt_pages,
  148. gatt_start, gatt_pages;
  149. struct resource *gtt_mem;
  150. /* The root resource we allocate address space from */
  151. gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
  152. /*
  153. * The video MMU has a HW bug when accessing 0x0d0000000. Make
  154. * GATT start at 0x0e0000000. This doesn't actually matter for
  155. * us now, but maybe will if the video acceleration ever gets
  156. * opened up.
  157. */
  158. mmu_gatt_start = 0xe0000000;
  159. gtt_start = pci_resource_start(pdev, PSB_GTT_RESOURCE);
  160. gtt_pages = pci_resource_len(pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
  161. /* CDV doesn't report this. In which case the system has 64 gtt pages */
  162. if (!gtt_start || !gtt_pages) {
  163. dev_dbg(dev->dev, "GTT PCI BAR not initialized.\n");
  164. gtt_pages = 64;
  165. gtt_start = dev_priv->pge_ctl;
  166. }
  167. gatt_start = pci_resource_start(pdev, PSB_GATT_RESOURCE);
  168. gatt_pages = pci_resource_len(pdev, PSB_GATT_RESOURCE) >> PAGE_SHIFT;
  169. if (!gatt_pages || !gatt_start) {
  170. static struct resource fudge; /* Preferably peppermint */
  171. /*
  172. * This can occur on CDV systems. Fudge it in this case. We
  173. * really don't care what imaginary space is being allocated
  174. * at this point.
  175. */
  176. dev_dbg(dev->dev, "GATT PCI BAR not initialized.\n");
  177. gatt_start = 0x40000000;
  178. gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT;
  179. /*
  180. * This is a little confusing but in fact the GTT is providing
  181. * a view from the GPU into memory and not vice versa. As such
  182. * this is really allocating space that is not the same as the
  183. * CPU address space on CDV.
  184. */
  185. fudge.start = 0x40000000;
  186. fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1;
  187. fudge.name = "fudge";
  188. fudge.flags = IORESOURCE_MEM;
  189. gtt_mem = &fudge;
  190. } else {
  191. gtt_mem = &pdev->resource[PSB_GATT_RESOURCE];
  192. }
  193. pg->gtt_phys_start = gtt_phys_start;
  194. pg->mmu_gatt_start = mmu_gatt_start;
  195. pg->gtt_start = gtt_start;
  196. pg->gtt_pages = gtt_pages;
  197. pg->gatt_start = gatt_start;
  198. pg->gatt_pages = gatt_pages;
  199. dev_priv->gtt_mem = gtt_mem;
  200. }
  201. int psb_gtt_init(struct drm_device *dev)
  202. {
  203. struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
  204. struct psb_gtt *pg = &dev_priv->gtt;
  205. int ret;
  206. mutex_init(&dev_priv->gtt_mutex);
  207. ret = psb_gtt_enable(dev_priv);
  208. if (ret)
  209. goto err_mutex_destroy;
  210. psb_gtt_init_ranges(dev_priv);
  211. dev_priv->gtt_map = ioremap(pg->gtt_phys_start, pg->gtt_pages << PAGE_SHIFT);
  212. if (!dev_priv->gtt_map) {
  213. dev_err(dev->dev, "Failure to map gtt.\n");
  214. ret = -ENOMEM;
  215. goto err_psb_gtt_disable;
  216. }
  217. psb_gtt_clear(dev_priv);
  218. return 0;
  219. err_psb_gtt_disable:
  220. psb_gtt_disable(dev_priv);
  221. err_mutex_destroy:
  222. mutex_destroy(&dev_priv->gtt_mutex);
  223. return ret;
  224. }
  225. int psb_gtt_resume(struct drm_device *dev)
  226. {
  227. struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
  228. struct psb_gtt *pg = &dev_priv->gtt;
  229. unsigned int old_gtt_pages = pg->gtt_pages;
  230. int ret;
  231. /* Enable the GTT */
  232. ret = psb_gtt_enable(dev_priv);
  233. if (ret)
  234. return ret;
  235. psb_gtt_init_ranges(dev_priv);
  236. if (old_gtt_pages != pg->gtt_pages) {
  237. dev_err(dev->dev, "GTT resume error.\n");
  238. ret = -ENODEV;
  239. goto err_psb_gtt_disable;
  240. }
  241. psb_gtt_clear(dev_priv);
  242. err_psb_gtt_disable:
  243. psb_gtt_disable(dev_priv);
  244. return ret;
  245. }