nv40_fb.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #include "drmP.h"
  2. #include "drm.h"
  3. #include "nouveau_drv.h"
  4. #include "nouveau_drm.h"
  5. void
  6. nv40_fb_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
  7. uint32_t size, uint32_t pitch)
  8. {
  9. struct drm_nouveau_private *dev_priv = dev->dev_private;
  10. uint32_t limit = max(1u, addr + size) - 1;
  11. if (pitch)
  12. addr |= 1;
  13. switch (dev_priv->chipset) {
  14. case 0x40:
  15. nv_wr32(dev, NV10_PFB_TLIMIT(i), limit);
  16. nv_wr32(dev, NV10_PFB_TSIZE(i), pitch);
  17. nv_wr32(dev, NV10_PFB_TILE(i), addr);
  18. break;
  19. default:
  20. nv_wr32(dev, NV40_PFB_TLIMIT(i), limit);
  21. nv_wr32(dev, NV40_PFB_TSIZE(i), pitch);
  22. nv_wr32(dev, NV40_PFB_TILE(i), addr);
  23. break;
  24. }
  25. }
  26. int
  27. nv40_fb_init(struct drm_device *dev)
  28. {
  29. struct drm_nouveau_private *dev_priv = dev->dev_private;
  30. struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
  31. uint32_t tmp;
  32. int i;
  33. /* This is strictly a NV4x register (don't know about NV5x). */
  34. /* The blob sets these to all kinds of values, and they mess up our setup. */
  35. /* I got value 0x52802 instead. For some cards the blob even sets it back to 0x1. */
  36. /* Note: the blob doesn't read this value, so i'm pretty sure this is safe for all cards. */
  37. /* Any idea what this is? */
  38. nv_wr32(dev, NV40_PFB_UNK_800, 0x1);
  39. switch (dev_priv->chipset) {
  40. case 0x40:
  41. case 0x45:
  42. tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2);
  43. nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15));
  44. pfb->num_tiles = NV10_PFB_TILE__SIZE;
  45. break;
  46. case 0x46: /* G72 */
  47. case 0x47: /* G70 */
  48. case 0x49: /* G71 */
  49. case 0x4b: /* G73 */
  50. case 0x4c: /* C51 (G7X version) */
  51. pfb->num_tiles = NV40_PFB_TILE__SIZE_1;
  52. break;
  53. default:
  54. pfb->num_tiles = NV40_PFB_TILE__SIZE_0;
  55. break;
  56. }
  57. /* Turn all the tiling regions off. */
  58. for (i = 0; i < pfb->num_tiles; i++)
  59. pfb->set_region_tiling(dev, i, 0, 0, 0);
  60. return 0;
  61. }
  62. void
  63. nv40_fb_takedown(struct drm_device *dev)
  64. {
  65. }