nv10_gpio.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (C) 2009 Francisco Jerez.
  3. * All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * The above copyright notice and this permission notice (including the
  14. * next paragraph) shall be included in all copies or substantial
  15. * portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20. * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  21. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. *
  25. */
  26. #include "drmP.h"
  27. #include "nouveau_drv.h"
  28. #include "nouveau_hw.h"
  29. #include "nouveau_gpio.h"
  30. int
  31. nv10_gpio_sense(struct drm_device *dev, int line)
  32. {
  33. if (line < 2) {
  34. line = line * 16;
  35. line = NVReadCRTC(dev, 0, NV_PCRTC_GPIO) >> line;
  36. return !!(line & 0x0100);
  37. } else
  38. if (line < 10) {
  39. line = (line - 2) * 4;
  40. line = NVReadCRTC(dev, 0, NV_PCRTC_GPIO_EXT) >> line;
  41. return !!(line & 0x04);
  42. } else
  43. if (line < 14) {
  44. line = (line - 10) * 4;
  45. line = NVReadCRTC(dev, 0, NV_PCRTC_850) >> line;
  46. return !!(line & 0x04);
  47. }
  48. return -EINVAL;
  49. }
  50. int
  51. nv10_gpio_drive(struct drm_device *dev, int line, int dir, int out)
  52. {
  53. u32 reg, mask, data;
  54. if (line < 2) {
  55. line = line * 16;
  56. reg = NV_PCRTC_GPIO;
  57. mask = 0x00000011;
  58. data = (dir << 4) | out;
  59. } else
  60. if (line < 10) {
  61. line = (line - 2) * 4;
  62. reg = NV_PCRTC_GPIO_EXT;
  63. mask = 0x00000003 << ((line - 2) * 4);
  64. data = (dir << 1) | out;
  65. } else
  66. if (line < 14) {
  67. line = (line - 10) * 4;
  68. reg = NV_PCRTC_850;
  69. mask = 0x00000003;
  70. data = (dir << 1) | out;
  71. } else {
  72. return -EINVAL;
  73. }
  74. mask = NVReadCRTC(dev, 0, reg) & ~(mask << line);
  75. NVWriteCRTC(dev, 0, reg, mask | (data << line));
  76. return 0;
  77. }
  78. void
  79. nv10_gpio_irq_enable(struct drm_device *dev, int line, bool on)
  80. {
  81. u32 mask = 0x00010001 << line;
  82. nv_wr32(dev, 0x001104, mask);
  83. nv_mask(dev, 0x001144, mask, on ? mask : 0);
  84. }
  85. static void
  86. nv10_gpio_isr(struct drm_device *dev)
  87. {
  88. u32 intr = nv_rd32(dev, 0x1104);
  89. u32 hi = (intr & 0x0000ffff) >> 0;
  90. u32 lo = (intr & 0xffff0000) >> 16;
  91. nouveau_gpio_isr(dev, 0, hi | lo);
  92. nv_wr32(dev, 0x001104, intr);
  93. }
  94. int
  95. nv10_gpio_init(struct drm_device *dev)
  96. {
  97. nv_wr32(dev, 0x001140, 0x00000000);
  98. nv_wr32(dev, 0x001100, 0xffffffff);
  99. nv_wr32(dev, 0x001144, 0x00000000);
  100. nv_wr32(dev, 0x001104, 0xffffffff);
  101. nouveau_irq_register(dev, 28, nv10_gpio_isr); /* PBUS */
  102. return 0;
  103. }
  104. void
  105. nv10_gpio_fini(struct drm_device *dev)
  106. {
  107. nv_wr32(dev, 0x001140, 0x00000000);
  108. nv_wr32(dev, 0x001144, 0x00000000);
  109. nouveau_irq_unregister(dev, 28);
  110. }