uic.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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, 0);
  60. irq_install_handler(VECNUM_UIC1CI, (void *)(void *)external_interrupt, 0);
  61. #endif
  62. #if (UIC_MAX > 2)
  63. irq_install_handler(VECNUM_UIC2NCI, (void *)(void *)external_interrupt, 0);
  64. irq_install_handler(VECNUM_UIC2CI, (void *)(void *)external_interrupt, 0);
  65. #endif
  66. #if (UIC_MAX > 3)
  67. irq_install_handler(VECNUM_UIC3NCI, (void *)(void *)external_interrupt, 0);
  68. irq_install_handler(VECNUM_UIC3CI, (void *)(void *)external_interrupt, 0);
  69. #endif
  70. }
  71. /* Handler for UIC interrupt */
  72. static void uic_interrupt(u32 uic_base, int vec_base)
  73. {
  74. u32 uic_msr;
  75. u32 msr_shift;
  76. int vec;
  77. /*
  78. * Read masked interrupt status register to determine interrupt source
  79. */
  80. uic_msr = get_dcr(uic_base + UIC_MSR);
  81. msr_shift = uic_msr;
  82. vec = vec_base;
  83. while (msr_shift != 0) {
  84. if (msr_shift & 0x80000000)
  85. interrupt_run_handler(vec);
  86. /*
  87. * Shift msr to next position and increment vector
  88. */
  89. msr_shift <<= 1;
  90. vec++;
  91. }
  92. }
  93. /*
  94. * Handle external interrupts
  95. */
  96. void external_interrupt(struct pt_regs *regs)
  97. {
  98. u32 uic_msr;
  99. /*
  100. * Read masked interrupt status register to determine interrupt source
  101. */
  102. uic_msr = mfdcr(uic0msr);
  103. #if (UIC_MAX > 1)
  104. if ((UIC_MASK(VECNUM_UIC1CI) & uic_msr) ||
  105. (UIC_MASK(VECNUM_UIC1NCI) & uic_msr))
  106. uic_interrupt(UIC1_DCR_BASE, 32);
  107. #endif
  108. #if (UIC_MAX > 2)
  109. if ((UIC_MASK(VECNUM_UIC2CI) & uic_msr) ||
  110. (UIC_MASK(VECNUM_UIC2NCI) & uic_msr))
  111. uic_interrupt(UIC2_DCR_BASE, 64);
  112. #endif
  113. #if (UIC_MAX > 3)
  114. if ((UIC_MASK(VECNUM_UIC3CI) & uic_msr) ||
  115. (UIC_MASK(VECNUM_UIC3NCI) & uic_msr))
  116. uic_interrupt(UIC3_DCR_BASE, 96);
  117. #endif
  118. if (uic_msr & ~(UICB0_ALL))
  119. uic_interrupt(UIC0_DCR_BASE, 0);
  120. mtdcr(uic0sr, uic_msr);
  121. return;
  122. }
  123. void pic_irq_ack(unsigned int vec)
  124. {
  125. if ((vec >= 0) && (vec < 32))
  126. mtdcr(uicsr, UIC_MASK(vec));
  127. else if ((vec >= 32) && (vec < 64))
  128. mtdcr(uic1sr, UIC_MASK(vec));
  129. else if ((vec >= 64) && (vec < 96))
  130. mtdcr(uic2sr, UIC_MASK(vec));
  131. else if (vec >= 96)
  132. mtdcr(uic3sr, UIC_MASK(vec));
  133. }
  134. /*
  135. * Install and free a interrupt handler.
  136. */
  137. void pic_irq_enable(unsigned int vec)
  138. {
  139. if ((vec >= 0) && (vec < 32))
  140. mtdcr(uicer, mfdcr(uicer) | UIC_MASK(vec));
  141. else if ((vec >= 32) && (vec < 64))
  142. mtdcr(uic1er, mfdcr(uic1er) | UIC_MASK(vec));
  143. else if ((vec >= 64) && (vec < 96))
  144. mtdcr(uic2er, mfdcr(uic2er) | UIC_MASK(vec));
  145. else if (vec >= 96)
  146. mtdcr(uic3er, mfdcr(uic3er) | UIC_MASK(vec));
  147. debug("Install interrupt for vector %d ==> %p\n", vec, handler);
  148. }
  149. void pic_irq_disable(unsigned int vec)
  150. {
  151. if ((vec >= 0) && (vec < 32))
  152. mtdcr(uicer, mfdcr(uicer) & ~UIC_MASK(vec));
  153. else if ((vec >= 32) && (vec < 64))
  154. mtdcr(uic1er, mfdcr(uic1er) & ~UIC_MASK(vec));
  155. else if ((vec >= 64) && (vec < 96))
  156. mtdcr(uic2er, mfdcr(uic2er) & ~UIC_MASK(vec));
  157. else if (vec >= 96)
  158. mtdcr(uic3er, mfdcr(uic3er) & ~UIC_MASK(vec));
  159. }