uic.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * (C) Copyright 2000-2002
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * (C) Copyright 2002 (440 port)
  6. * Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com
  7. *
  8. * (C) Copyright 2003 (440GX port)
  9. * Travis B. Sawyer, Sandburst Corporation, tsawyer@sandburst.com
  10. *
  11. * (C) Copyright 2008 (PPC440X05 port for Virtex 5 FX)
  12. * Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
  13. * Work supported by Qtechnology (htpp://qtec.com)
  14. *
  15. * See file CREDITS for list of people who contributed to this
  16. * project.
  17. *
  18. * This program is free software; you can redistribute it and/or
  19. * modify it under the terms of the GNU General Public License as
  20. * published by the Free Software Foundation; either version 2 of
  21. * the License, or (at your option) any later version.
  22. *
  23. * This program is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. * GNU General Public License for more details.
  27. *
  28. * You should have received a copy of the GNU General Public License
  29. * along with this program; if not, write to the Free Software
  30. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  31. * MA 02111-1307 USA
  32. */
  33. #include <common.h>
  34. #include <watchdog.h>
  35. #include <command.h>
  36. #include <asm/processor.h>
  37. #include <asm/interrupt.h>
  38. #include <ppc4xx.h>
  39. #include <ppc_asm.tmpl>
  40. #include <commproc.h>
  41. #if (UIC_MAX > 3)
  42. #define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI) | \
  43. UIC_MASK(VECNUM_UIC2CI) | UIC_MASK(VECNUM_UIC2NCI) | \
  44. UIC_MASK(VECNUM_UIC3CI) | UIC_MASK(VECNUM_UIC3NCI))
  45. #elif (UIC_MAX > 2)
  46. #define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI) | \
  47. UIC_MASK(VECNUM_UIC2CI) | UIC_MASK(VECNUM_UIC2NCI))
  48. #elif (UIC_MAX > 1)
  49. #define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI))
  50. #else
  51. #define UICB0_ALL 0
  52. #endif
  53. u32 get_dcr(u16);
  54. DECLARE_GLOBAL_DATA_PTR;
  55. void pic_enable(void)
  56. {
  57. #if (UIC_MAX > 1)
  58. /* Install the UIC1 handlers */
  59. irq_install_handler(VECNUM_UIC1NCI, (void *)(void *)external_interrupt,
  60. 0);
  61. irq_install_handler(VECNUM_UIC1CI, (void *)(void *)external_interrupt,
  62. 0);
  63. #endif
  64. #if (UIC_MAX > 2)
  65. irq_install_handler(VECNUM_UIC2NCI, (void *)(void *)external_interrupt,
  66. 0);
  67. irq_install_handler(VECNUM_UIC2CI, (void *)(void *)external_interrupt,
  68. 0);
  69. #endif
  70. #if (UIC_MAX > 3)
  71. irq_install_handler(VECNUM_UIC3NCI, (void *)(void *)external_interrupt,
  72. 0);
  73. irq_install_handler(VECNUM_UIC3CI, (void *)(void *)external_interrupt,
  74. 0);
  75. #endif
  76. }
  77. /* Handler for UIC interrupt */
  78. static void uic_interrupt(u32 uic_base, int vec_base)
  79. {
  80. u32 uic_msr;
  81. u32 msr_shift;
  82. int vec;
  83. /*
  84. * Read masked interrupt status register to determine interrupt source
  85. */
  86. uic_msr = get_dcr(uic_base + UIC_MSR);
  87. msr_shift = uic_msr;
  88. vec = vec_base;
  89. while (msr_shift != 0) {
  90. if (msr_shift & 0x80000000)
  91. interrupt_run_handler(vec);
  92. /*
  93. * Shift msr to next position and increment vector
  94. */
  95. msr_shift <<= 1;
  96. vec++;
  97. }
  98. }
  99. /*
  100. * Handle external interrupts
  101. */
  102. void external_interrupt(struct pt_regs *regs)
  103. {
  104. u32 uic_msr;
  105. /*
  106. * Read masked interrupt status register to determine interrupt source
  107. */
  108. uic_msr = mfdcr(uic0msr);
  109. #if (UIC_MAX > 1)
  110. if ((UIC_MASK(VECNUM_UIC1CI) & uic_msr) ||
  111. (UIC_MASK(VECNUM_UIC1NCI) & uic_msr))
  112. uic_interrupt(UIC1_DCR_BASE, 32);
  113. #endif
  114. #if (UIC_MAX > 2)
  115. if ((UIC_MASK(VECNUM_UIC2CI) & uic_msr) ||
  116. (UIC_MASK(VECNUM_UIC2NCI) & uic_msr))
  117. uic_interrupt(UIC2_DCR_BASE, 64);
  118. #endif
  119. #if (UIC_MAX > 3)
  120. if ((UIC_MASK(VECNUM_UIC3CI) & uic_msr) ||
  121. (UIC_MASK(VECNUM_UIC3NCI) & uic_msr))
  122. uic_interrupt(UIC3_DCR_BASE, 96);
  123. #endif
  124. if (uic_msr & ~(UICB0_ALL))
  125. uic_interrupt(UIC0_DCR_BASE, 0);
  126. mtdcr(uic0sr, uic_msr);
  127. return;
  128. }
  129. void pic_irq_ack(unsigned int vec)
  130. {
  131. if ((vec >= 0) && (vec < 32))
  132. mtdcr(uicsr, UIC_MASK(vec));
  133. #if (UIC_MAX > 1)
  134. else if ((vec >= 32) && (vec < 64))
  135. mtdcr(uic1sr, UIC_MASK(vec));
  136. #endif
  137. #if (UIC_MAX > 2)
  138. else if ((vec >= 64) && (vec < 96))
  139. mtdcr(uic2sr, UIC_MASK(vec));
  140. #endif
  141. #if (UIC_MAX > 3)
  142. else if (vec >= 96)
  143. mtdcr(uic3sr, UIC_MASK(vec));
  144. #endif
  145. }
  146. /*
  147. * Install and free a interrupt handler.
  148. */
  149. void pic_irq_enable(unsigned int vec)
  150. {
  151. if ((vec >= 0) && (vec < 32))
  152. mtdcr(uicer, mfdcr(uicer) | UIC_MASK(vec));
  153. #if (UIC_MAX > 1)
  154. else if ((vec >= 32) && (vec < 64))
  155. mtdcr(uic1er, mfdcr(uic1er) | UIC_MASK(vec));
  156. #endif
  157. #if (UIC_MAX > 2)
  158. else if ((vec >= 64) && (vec < 96))
  159. mtdcr(uic2er, mfdcr(uic2er) | UIC_MASK(vec));
  160. #endif
  161. #if (UIC_MAX > 3)
  162. else if (vec >= 96)
  163. mtdcr(uic3er, mfdcr(uic3er) | UIC_MASK(vec));
  164. #endif
  165. debug("Install interrupt for vector %d ==> %p\n", vec, handler);
  166. }
  167. void pic_irq_disable(unsigned int vec)
  168. {
  169. if ((vec >= 0) && (vec < 32))
  170. mtdcr(uicer, mfdcr(uicer) & ~UIC_MASK(vec));
  171. #if (UIC_MAX > 1)
  172. else if ((vec >= 32) && (vec < 64))
  173. mtdcr(uic1er, mfdcr(uic1er) & ~UIC_MASK(vec));
  174. #endif
  175. #if (UIC_MAX > 2)
  176. else if ((vec >= 64) && (vec < 96))
  177. mtdcr(uic2er, mfdcr(uic2er) & ~UIC_MASK(vec));
  178. #endif
  179. #if (UIC_MAX > 3)
  180. else if (vec >= 96)
  181. mtdcr(uic3er, mfdcr(uic3er) & ~UIC_MASK(vec));
  182. #endif
  183. }