interrupts.c 4.6 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 <asm/ppc4xx.h>
  39. #include <ppc_asm.tmpl>
  40. #include <commproc.h>
  41. DECLARE_GLOBAL_DATA_PTR;
  42. /*
  43. * CPM interrupt vector functions.
  44. */
  45. struct irq_action {
  46. interrupt_handler_t *handler;
  47. void *arg;
  48. int count;
  49. };
  50. static struct irq_action irq_vecs[IRQ_MAX];
  51. #if defined(CONFIG_440)
  52. /* SPRN changed in 440 */
  53. static __inline__ void set_evpr(unsigned long val)
  54. {
  55. asm volatile("mtspr 0x03f,%0" : : "r" (val));
  56. }
  57. #else /* !defined(CONFIG_440) */
  58. static __inline__ void set_pit(unsigned long val)
  59. {
  60. asm volatile("mtpit %0" : : "r" (val));
  61. }
  62. static __inline__ void set_evpr(unsigned long val)
  63. {
  64. asm volatile("mtevpr %0" : : "r" (val));
  65. }
  66. #endif /* defined(CONFIG_440 */
  67. int interrupt_init_cpu (unsigned *decrementer_count)
  68. {
  69. int vec;
  70. unsigned long val;
  71. /* decrementer is automatically reloaded */
  72. *decrementer_count = 0;
  73. /*
  74. * Mark all irqs as free
  75. */
  76. for (vec = 0; vec < IRQ_MAX; vec++) {
  77. irq_vecs[vec].handler = NULL;
  78. irq_vecs[vec].arg = NULL;
  79. irq_vecs[vec].count = 0;
  80. }
  81. #ifdef CONFIG_4xx
  82. /*
  83. * Init PIT
  84. */
  85. #if defined(CONFIG_440)
  86. val = mfspr( SPRN_TCR );
  87. val &= (~0x04400000); /* clear DIS & ARE */
  88. mtspr( SPRN_TCR, val );
  89. mtspr( SPRN_DEC, 0 ); /* Prevent exception after TSR clear*/
  90. mtspr( SPRN_DECAR, 0 ); /* clear reload */
  91. mtspr( SPRN_TSR, 0x08000000 ); /* clear DEC status */
  92. val = gd->bd->bi_intfreq/1000; /* 1 msec */
  93. mtspr( SPRN_DECAR, val ); /* Set auto-reload value */
  94. mtspr( SPRN_DEC, val ); /* Set inital val */
  95. #else
  96. set_pit(gd->bd->bi_intfreq / 1000);
  97. #endif
  98. #endif /* CONFIG_4xx */
  99. #ifdef CONFIG_ADCIOP
  100. /*
  101. * Init PIT
  102. */
  103. set_pit(66000);
  104. #endif
  105. /*
  106. * Enable PIT
  107. */
  108. val = mfspr(SPRN_TCR);
  109. val |= 0x04400000;
  110. mtspr(SPRN_TCR, val);
  111. /*
  112. * Set EVPR to 0
  113. */
  114. set_evpr(0x00000000);
  115. /*
  116. * Call uic or xilinx_irq pic_enable
  117. */
  118. pic_enable();
  119. return (0);
  120. }
  121. void timer_interrupt_cpu(struct pt_regs *regs)
  122. {
  123. /* nothing to do here */
  124. return;
  125. }
  126. void interrupt_run_handler(int vec)
  127. {
  128. irq_vecs[vec].count++;
  129. if (irq_vecs[vec].handler != NULL) {
  130. /* call isr */
  131. (*irq_vecs[vec].handler) (irq_vecs[vec].arg);
  132. } else {
  133. pic_irq_disable(vec);
  134. printf("Masking bogus interrupt vector %d\n", vec);
  135. }
  136. pic_irq_ack(vec);
  137. return;
  138. }
  139. void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg)
  140. {
  141. /*
  142. * Print warning when replacing with a different irq vector
  143. */
  144. if ((irq_vecs[vec].handler != NULL) && (irq_vecs[vec].handler != handler)) {
  145. printf("Interrupt vector %d: handler 0x%x replacing 0x%x\n",
  146. vec, (uint) handler, (uint) irq_vecs[vec].handler);
  147. }
  148. irq_vecs[vec].handler = handler;
  149. irq_vecs[vec].arg = arg;
  150. pic_irq_enable(vec);
  151. return;
  152. }
  153. void irq_free_handler(int vec)
  154. {
  155. debug("Free interrupt for vector %d ==> %p\n",
  156. vec, irq_vecs[vec].handler);
  157. pic_irq_disable(vec);
  158. irq_vecs[vec].handler = NULL;
  159. irq_vecs[vec].arg = NULL;
  160. return;
  161. }
  162. #if defined(CONFIG_CMD_IRQ)
  163. int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  164. {
  165. int vec;
  166. printf ("Interrupt-Information:\n");
  167. printf ("Nr Routine Arg Count\n");
  168. for (vec = 0; vec < IRQ_MAX; vec++) {
  169. if (irq_vecs[vec].handler != NULL) {
  170. printf ("%02d %08lx %08lx %d\n",
  171. vec,
  172. (ulong)irq_vecs[vec].handler,
  173. (ulong)irq_vecs[vec].arg,
  174. irq_vecs[vec].count);
  175. }
  176. }
  177. return 0;
  178. }
  179. #endif