nv04_instmem.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include "drmP.h"
  2. #include "drm.h"
  3. #include "nouveau_drv.h"
  4. #include "nouveau_ramht.h"
  5. /* returns the size of fifo context */
  6. static int
  7. nouveau_fifo_ctx_size(struct drm_device *dev)
  8. {
  9. struct drm_nouveau_private *dev_priv = dev->dev_private;
  10. if (dev_priv->chipset >= 0x40)
  11. return 128;
  12. else
  13. if (dev_priv->chipset >= 0x17)
  14. return 64;
  15. return 32;
  16. }
  17. int nv04_instmem_init(struct drm_device *dev)
  18. {
  19. struct drm_nouveau_private *dev_priv = dev->dev_private;
  20. struct nouveau_gpuobj *ramht = NULL;
  21. u32 offset, length;
  22. int ret;
  23. /* RAMIN always available */
  24. dev_priv->ramin_available = true;
  25. /* Setup shared RAMHT */
  26. ret = nouveau_gpuobj_new_fake(dev, 0x10000, ~0, 4096,
  27. NVOBJ_FLAG_ZERO_ALLOC, &ramht);
  28. if (ret)
  29. return ret;
  30. ret = nouveau_ramht_new(dev, ramht, &dev_priv->ramht);
  31. nouveau_gpuobj_ref(NULL, &ramht);
  32. if (ret)
  33. return ret;
  34. /* And RAMRO */
  35. ret = nouveau_gpuobj_new_fake(dev, 0x11200, ~0, 512,
  36. NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramro);
  37. if (ret)
  38. return ret;
  39. /* And RAMFC */
  40. length = dev_priv->engine.fifo.channels * nouveau_fifo_ctx_size(dev);
  41. switch (dev_priv->card_type) {
  42. case NV_40:
  43. offset = 0x20000;
  44. break;
  45. default:
  46. offset = 0x11400;
  47. break;
  48. }
  49. ret = nouveau_gpuobj_new_fake(dev, offset, ~0, length,
  50. NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramfc);
  51. if (ret)
  52. return ret;
  53. /* Only allow space after RAMFC to be used for object allocation */
  54. offset += length;
  55. /* It appears RAMRO (or something?) is controlled by 0x2220/0x2230
  56. * on certain NV4x chipsets as well as RAMFC. When 0x2230 == 0
  57. * ("new style" control) the upper 16-bits of 0x2220 points at this
  58. * other mysterious table that's clobbering important things.
  59. *
  60. * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting
  61. * smashed to pieces on us, so reserve 0x30000-0x40000 too..
  62. */
  63. if (dev_priv->card_type >= NV_40) {
  64. if (offset < 0x40000)
  65. offset = 0x40000;
  66. }
  67. ret = drm_mm_init(&dev_priv->ramin_heap, offset,
  68. dev_priv->ramin_rsvd_vram - offset);
  69. if (ret) {
  70. NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret);
  71. return ret;
  72. }
  73. return 0;
  74. }
  75. void
  76. nv04_instmem_takedown(struct drm_device *dev)
  77. {
  78. struct drm_nouveau_private *dev_priv = dev->dev_private;
  79. nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL);
  80. nouveau_gpuobj_ref(NULL, &dev_priv->ramro);
  81. nouveau_gpuobj_ref(NULL, &dev_priv->ramfc);
  82. if (drm_mm_initialized(&dev_priv->ramin_heap))
  83. drm_mm_takedown(&dev_priv->ramin_heap);
  84. }
  85. int
  86. nv04_instmem_suspend(struct drm_device *dev)
  87. {
  88. return 0;
  89. }
  90. void
  91. nv04_instmem_resume(struct drm_device *dev)
  92. {
  93. }
  94. int
  95. nv04_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
  96. u32 size, u32 align)
  97. {
  98. struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
  99. struct drm_mm_node *ramin = NULL;
  100. do {
  101. if (drm_mm_pre_get(&dev_priv->ramin_heap))
  102. return -ENOMEM;
  103. spin_lock(&dev_priv->ramin_lock);
  104. ramin = drm_mm_search_free(&dev_priv->ramin_heap, size, align, 0);
  105. if (ramin == NULL) {
  106. spin_unlock(&dev_priv->ramin_lock);
  107. return -ENOMEM;
  108. }
  109. ramin = drm_mm_get_block_atomic(ramin, size, align);
  110. spin_unlock(&dev_priv->ramin_lock);
  111. } while (ramin == NULL);
  112. gpuobj->node = ramin;
  113. gpuobj->vinst = ramin->start;
  114. return 0;
  115. }
  116. void
  117. nv04_instmem_put(struct nouveau_gpuobj *gpuobj)
  118. {
  119. struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
  120. spin_lock(&dev_priv->ramin_lock);
  121. drm_mm_put_block(gpuobj->node);
  122. gpuobj->node = NULL;
  123. spin_unlock(&dev_priv->ramin_lock);
  124. }
  125. int
  126. nv04_instmem_map(struct nouveau_gpuobj *gpuobj)
  127. {
  128. gpuobj->pinst = gpuobj->vinst;
  129. return 0;
  130. }
  131. void
  132. nv04_instmem_unmap(struct nouveau_gpuobj *gpuobj)
  133. {
  134. }
  135. void
  136. nv04_instmem_flush(struct drm_device *dev)
  137. {
  138. }