nouveau_agp.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include <linux/module.h>
  2. #include "drmP.h"
  3. #include "drm.h"
  4. #include "nouveau_drv.h"
  5. #include "nouveau_agp.h"
  6. #if __OS_HAS_AGP
  7. MODULE_PARM_DESC(agpmode, "AGP mode (0 to disable AGP)");
  8. static int nouveau_agpmode = -1;
  9. module_param_named(agpmode, nouveau_agpmode, int, 0400);
  10. static unsigned long
  11. get_agp_mode(struct drm_device *dev, unsigned long mode)
  12. {
  13. struct drm_nouveau_private *dev_priv = dev->dev_private;
  14. /*
  15. * FW seems to be broken on nv18, it makes the card lock up
  16. * randomly.
  17. */
  18. if (dev_priv->chipset == 0x18)
  19. mode &= ~PCI_AGP_COMMAND_FW;
  20. /*
  21. * AGP mode set in the command line.
  22. */
  23. if (nouveau_agpmode > 0) {
  24. bool agpv3 = mode & 0x8;
  25. int rate = agpv3 ? nouveau_agpmode / 4 : nouveau_agpmode;
  26. mode = (mode & ~0x7) | (rate & 0x7);
  27. }
  28. return mode;
  29. }
  30. static bool
  31. nouveau_agp_enabled(struct drm_device *dev)
  32. {
  33. struct drm_nouveau_private *dev_priv = dev->dev_private;
  34. if (!drm_pci_device_is_agp(dev) || !dev->agp)
  35. return false;
  36. switch (dev_priv->gart_info.type) {
  37. case NOUVEAU_GART_NONE:
  38. if (!nouveau_agpmode)
  39. return false;
  40. break;
  41. case NOUVEAU_GART_AGP:
  42. break;
  43. default:
  44. return false;
  45. }
  46. return true;
  47. }
  48. #endif
  49. void
  50. nouveau_agp_reset(struct drm_device *dev)
  51. {
  52. #if __OS_HAS_AGP
  53. u32 save[2];
  54. int ret;
  55. if (!nouveau_agp_enabled(dev))
  56. return;
  57. /* First of all, disable fast writes, otherwise if it's
  58. * already enabled in the AGP bridge and we disable the card's
  59. * AGP controller we might be locking ourselves out of it. */
  60. if ((nv_rd32(dev, NV04_PBUS_PCI_NV_19) |
  61. dev->agp->mode) & PCI_AGP_COMMAND_FW) {
  62. struct drm_agp_info info;
  63. struct drm_agp_mode mode;
  64. ret = drm_agp_info(dev, &info);
  65. if (ret)
  66. return;
  67. mode.mode = get_agp_mode(dev, info.mode);
  68. mode.mode &= ~PCI_AGP_COMMAND_FW;
  69. ret = drm_agp_enable(dev, mode);
  70. if (ret)
  71. return;
  72. }
  73. /* clear busmaster bit, and disable AGP */
  74. save[0] = nv_mask(dev, NV04_PBUS_PCI_NV_1, 0x00000004, 0x00000000);
  75. nv_wr32(dev, NV04_PBUS_PCI_NV_19, 0);
  76. /* reset PGRAPH, PFIFO and PTIMER */
  77. save[1] = nv_mask(dev, 0x000200, 0x00011100, 0x00000000);
  78. nv_mask(dev, 0x000200, 0x00011100, save[1]);
  79. /* and restore bustmaster bit (gives effect of resetting AGP) */
  80. nv_wr32(dev, NV04_PBUS_PCI_NV_1, save[0]);
  81. #endif
  82. }
  83. void
  84. nouveau_agp_init(struct drm_device *dev)
  85. {
  86. #if __OS_HAS_AGP
  87. struct drm_nouveau_private *dev_priv = dev->dev_private;
  88. struct drm_agp_info info;
  89. struct drm_agp_mode mode;
  90. int ret;
  91. if (!nouveau_agp_enabled(dev))
  92. return;
  93. ret = drm_agp_acquire(dev);
  94. if (ret) {
  95. NV_ERROR(dev, "Unable to acquire AGP: %d\n", ret);
  96. return;
  97. }
  98. ret = drm_agp_info(dev, &info);
  99. if (ret) {
  100. NV_ERROR(dev, "Unable to get AGP info: %d\n", ret);
  101. return;
  102. }
  103. /* see agp.h for the AGPSTAT_* modes available */
  104. mode.mode = get_agp_mode(dev, info.mode);
  105. ret = drm_agp_enable(dev, mode);
  106. if (ret) {
  107. NV_ERROR(dev, "Unable to enable AGP: %d\n", ret);
  108. return;
  109. }
  110. dev_priv->gart_info.type = NOUVEAU_GART_AGP;
  111. dev_priv->gart_info.aper_base = info.aperture_base;
  112. dev_priv->gart_info.aper_size = info.aperture_size;
  113. #endif
  114. }
  115. void
  116. nouveau_agp_fini(struct drm_device *dev)
  117. {
  118. #if __OS_HAS_AGP
  119. if (dev->agp && dev->agp->acquired)
  120. drm_agp_release(dev);
  121. #endif
  122. }