intc.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. *********************************************************************************************************
  3. * AR100 SYSTEM
  4. * AR100 Software System Develop Kits
  5. * interrupt module
  6. *
  7. * (c) Copyright 2012-2016, Sunny China
  8. * All Rights Reserved
  9. *
  10. * File : intc.c
  11. * By : Sunny
  12. * Version : v1.0
  13. * Date : 2012-5-3
  14. * Descript: interrupt controller module.
  15. * Update : date auther ver notes
  16. * 2012-5-3 13:25:40 Sunny 1.0 Create this file.
  17. *********************************************************************************************************
  18. */
  19. #include "intc_i.h"
  20. #include "platform-intc.h"
  21. struct intc_regs *pintc_regs;
  22. /*
  23. *********************************************************************************************************
  24. * INTERRUPT INIT
  25. *
  26. * Description: initialize interrupt.
  27. *
  28. * Arguments : none.
  29. *
  30. * Returns : OK if initialize succeeded, others if failed.
  31. *
  32. * Note :
  33. *********************************************************************************************************
  34. */
  35. s32 intc_init(void)
  36. {
  37. pintc_regs = (struct intc_regs *)(SUNXI_R_INTC_PBASE);
  38. /*initialize interrupt controller */
  39. pintc_regs->enable = 0x0;
  40. pintc_regs->mask = 0x0;
  41. pintc_regs->pending = 0xffffffff;
  42. pintc_regs->enable1 = 0x0;
  43. pintc_regs->mask1 = 0x0;
  44. pintc_regs->pending1 = 0xffffffff;
  45. pintc_regs->enable2 = 0x0;
  46. pintc_regs->mask2 = 0x0;
  47. pintc_regs->pending2 = 0xffffffff;
  48. return OK;
  49. }
  50. /*
  51. *********************************************************************************************************
  52. * INTERRUPT EXIT
  53. *
  54. * Description: exit interrupt.
  55. *
  56. * Arguments : none.
  57. *
  58. * Returns : OK if exit succeeded, others if failed.
  59. *
  60. * Note :
  61. *********************************************************************************************************
  62. */
  63. s32 intc_exit(void)
  64. {
  65. pintc_regs = NULL;
  66. return OK;
  67. }
  68. /*
  69. *********************************************************************************************************
  70. * ENABLE INTERRUPT
  71. *
  72. * Description: enable a specific interrupt.
  73. *
  74. * Arguments : intno : the source number of interrupt to which we want to enable.
  75. *
  76. * Returns : OK if enable interrupt succeeded, others if failed.
  77. *
  78. * Note :
  79. *********************************************************************************************************
  80. */
  81. s32 intc_enable_interrupt(u32 intno)
  82. {
  83. /*intno can't beyond then IRQ_SOURCE_MAX */
  84. /* ASSERT(intno < IRQ_SOUCE_MAX); */
  85. /*
  86. * NMI interrupt should clear before enable.
  87. * by sunny at 2012-6-12 19:30:22.
  88. */
  89. if (intno == SUNXI_RINTC_IRQ_NMI) {
  90. pintc_regs->pending = (1 << intno);
  91. }
  92. /*enable interrupt which number is intno */
  93. if (intno <= 31)
  94. pintc_regs->enable |= (1 << intno);
  95. else if (intno > 31 && intno <= 63)
  96. pintc_regs->enable1 |= (1 << (intno - 32));
  97. else
  98. pintc_regs->enable2 |= (1 << (intno - 64));
  99. return OK;
  100. }
  101. /*
  102. *********************************************************************************************************
  103. * DISABLE INTERRUPT
  104. *
  105. * Description: disable a specific interrupt.
  106. *
  107. * Arguments : intno : the source number of interrupt which we want to disable.
  108. *
  109. * Returns : OK if disable interrupt succeeded, others if failed.
  110. *
  111. * Note :
  112. *********************************************************************************************************
  113. */
  114. s32 intc_disable_interrupt(u32 intno)
  115. {
  116. /*intno can't beyond then IRQ_SOURCE_MAX */
  117. /* ASSERT(intno < IRQ_SOUCE_MAX); */
  118. /*enable interrupt which number is intno */
  119. if (intno <= 31)
  120. pintc_regs->enable &= ~(1 << intno);
  121. else if (intno > 31 && intno <= 63)
  122. pintc_regs->enable1 &= ~(1 << (intno - 32));
  123. else
  124. pintc_regs->enable2 &= ~(1 << (intno - 64));
  125. return OK;
  126. }
  127. /*
  128. *********************************************************************************************************
  129. * GET CURRENT INTERRUPT
  130. *
  131. * Description: get the source number of current interrupt.
  132. *
  133. * Arguments : none.
  134. *
  135. * Returns : the source number of current interrupt.
  136. *
  137. * Note :
  138. *********************************************************************************************************
  139. */
  140. u32 intc_get_current_interrupt(void)
  141. {
  142. volatile u32 interrupt;
  143. interrupt = (u32) ((pintc_regs->vector) >> 2);
  144. return interrupt;
  145. }
  146. s32 intc_set_mask(u32 intno, u32 mask)
  147. {
  148. /* intno can't beyond then IRQ_SOURCE_MAX */
  149. /* ASSERT(intno < IRQ_SOUCE_MAX); */
  150. /* enable interrupt which number is intno */
  151. if (intno <= 31) {
  152. pintc_regs->mask &= ~(1 << intno);
  153. pintc_regs->mask |= (mask << intno);
  154. } else if (intno > 31 && intno <= 63) {
  155. pintc_regs->mask1 &= ~(1 << (intno - 32));
  156. pintc_regs->mask1 |= (mask << intno);
  157. } else {
  158. pintc_regs->mask2 &= ~(1 << (intno - 64));
  159. pintc_regs->mask2 |= (mask << intno);
  160. }
  161. return OK;
  162. }
  163. s32 intc_set_group_config(u32 grp_irq_num, u32 mask)
  164. {
  165. if (grp_irq_num <= 31) {
  166. pintc_regs->group_config0 &= ~(1 << grp_irq_num);
  167. pintc_regs->group_config0 |= (mask << grp_irq_num);
  168. } else if (grp_irq_num > 31 && grp_irq_num <= 63) {
  169. pintc_regs->group_config1 &= ~(1 << (grp_irq_num - 32));
  170. pintc_regs->group_config1 |= (mask << grp_irq_num);
  171. } else if (grp_irq_num > 63 && grp_irq_num <= 95) {
  172. pintc_regs->group_config2 &= ~(1 << (grp_irq_num - 64));
  173. pintc_regs->group_config2 |= (mask << grp_irq_num);
  174. } else {
  175. pintc_regs->group_config3 &= ~(1 << (grp_irq_num - 64));
  176. pintc_regs->group_config3 |= (mask << grp_irq_num);
  177. }
  178. return OK;
  179. }