interrupts.c 4.6 KB

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