uic.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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@gmail.com
  13. * Work supported by Qtechnology (htpp://qtec.com)
  14. *
  15. * SPDX-License-Identifier: GPL-2.0+
  16. */
  17. #include <common.h>
  18. #include <watchdog.h>
  19. #include <command.h>
  20. #include <asm/processor.h>
  21. #include <asm/interrupt.h>
  22. #include <asm/ppc4xx.h>
  23. #include <ppc_asm.tmpl>
  24. #include <commproc.h>
  25. #if (UIC_MAX > 3)
  26. #define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI) | \
  27. UIC_MASK(VECNUM_UIC2CI) | UIC_MASK(VECNUM_UIC2NCI) | \
  28. UIC_MASK(VECNUM_UIC3CI) | UIC_MASK(VECNUM_UIC3NCI))
  29. #elif (UIC_MAX > 2)
  30. #define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI) | \
  31. UIC_MASK(VECNUM_UIC2CI) | UIC_MASK(VECNUM_UIC2NCI))
  32. #elif (UIC_MAX > 1)
  33. #define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI))
  34. #else
  35. #define UICB0_ALL 0
  36. #endif
  37. u32 get_dcr(u16);
  38. DECLARE_GLOBAL_DATA_PTR;
  39. void pic_enable(void)
  40. {
  41. #if (UIC_MAX > 1)
  42. /* Install the UIC1 handlers */
  43. irq_install_handler(VECNUM_UIC1NCI, (void *)(void *)external_interrupt, 0);
  44. irq_install_handler(VECNUM_UIC1CI, (void *)(void *)external_interrupt, 0);
  45. #endif
  46. #if (UIC_MAX > 2)
  47. irq_install_handler(VECNUM_UIC2NCI, (void *)(void *)external_interrupt, 0);
  48. irq_install_handler(VECNUM_UIC2CI, (void *)(void *)external_interrupt, 0);
  49. #endif
  50. #if (UIC_MAX > 3)
  51. irq_install_handler(VECNUM_UIC3NCI, (void *)(void *)external_interrupt, 0);
  52. irq_install_handler(VECNUM_UIC3CI, (void *)(void *)external_interrupt, 0);
  53. #endif
  54. }
  55. /* Handler for UIC interrupt */
  56. static void uic_interrupt(u32 uic_base, int vec_base)
  57. {
  58. u32 uic_msr;
  59. u32 msr_shift;
  60. int vec;
  61. /*
  62. * Read masked interrupt status register to determine interrupt source
  63. */
  64. uic_msr = get_dcr(uic_base + UIC_MSR);
  65. msr_shift = uic_msr;
  66. vec = vec_base;
  67. while (msr_shift != 0) {
  68. if (msr_shift & 0x80000000)
  69. interrupt_run_handler(vec);
  70. /*
  71. * Shift msr to next position and increment vector
  72. */
  73. msr_shift <<= 1;
  74. vec++;
  75. }
  76. }
  77. /*
  78. * Handle external interrupts
  79. */
  80. void external_interrupt(struct pt_regs *regs)
  81. {
  82. u32 uic_msr;
  83. /*
  84. * Read masked interrupt status register to determine interrupt source
  85. */
  86. uic_msr = mfdcr(UIC0MSR);
  87. #if (UIC_MAX > 1)
  88. if ((UIC_MASK(VECNUM_UIC1CI) & uic_msr) ||
  89. (UIC_MASK(VECNUM_UIC1NCI) & uic_msr))
  90. uic_interrupt(UIC1_DCR_BASE, 32);
  91. #endif
  92. #if (UIC_MAX > 2)
  93. if ((UIC_MASK(VECNUM_UIC2CI) & uic_msr) ||
  94. (UIC_MASK(VECNUM_UIC2NCI) & uic_msr))
  95. uic_interrupt(UIC2_DCR_BASE, 64);
  96. #endif
  97. #if (UIC_MAX > 3)
  98. if ((UIC_MASK(VECNUM_UIC3CI) & uic_msr) ||
  99. (UIC_MASK(VECNUM_UIC3NCI) & uic_msr))
  100. uic_interrupt(UIC3_DCR_BASE, 96);
  101. #endif
  102. mtdcr(UIC0SR, (uic_msr & UICB0_ALL));
  103. if (uic_msr & ~(UICB0_ALL))
  104. uic_interrupt(UIC0_DCR_BASE, 0);
  105. return;
  106. }
  107. void pic_irq_ack(unsigned int vec)
  108. {
  109. if ((vec >= 0) && (vec < 32))
  110. mtdcr(UIC0SR, UIC_MASK(vec));
  111. else if ((vec >= 32) && (vec < 64))
  112. mtdcr(UIC1SR, UIC_MASK(vec));
  113. else if ((vec >= 64) && (vec < 96))
  114. mtdcr(UIC2SR, UIC_MASK(vec));
  115. else if (vec >= 96)
  116. mtdcr(UIC3SR, UIC_MASK(vec));
  117. }
  118. /*
  119. * Install and free a interrupt handler.
  120. */
  121. void pic_irq_enable(unsigned int vec)
  122. {
  123. if ((vec >= 0) && (vec < 32))
  124. mtdcr(UIC0ER, mfdcr(UIC0ER) | UIC_MASK(vec));
  125. else if ((vec >= 32) && (vec < 64))
  126. mtdcr(UIC1ER, mfdcr(UIC1ER) | UIC_MASK(vec));
  127. else if ((vec >= 64) && (vec < 96))
  128. mtdcr(UIC2ER, mfdcr(UIC2ER) | UIC_MASK(vec));
  129. else if (vec >= 96)
  130. mtdcr(UIC3ER, mfdcr(UIC3ER) | UIC_MASK(vec));
  131. debug("Install interrupt vector %d\n", vec);
  132. }
  133. void pic_irq_disable(unsigned int vec)
  134. {
  135. if ((vec >= 0) && (vec < 32))
  136. mtdcr(UIC0ER, mfdcr(UIC0ER) & ~UIC_MASK(vec));
  137. else if ((vec >= 32) && (vec < 64))
  138. mtdcr(UIC1ER, mfdcr(UIC1ER) & ~UIC_MASK(vec));
  139. else if ((vec >= 64) && (vec < 96))
  140. mtdcr(UIC2ER, mfdcr(UIC2ER) & ~UIC_MASK(vec));
  141. else if (vec >= 96)
  142. mtdcr(UIC3ER, mfdcr(UIC3ER) & ~UIC_MASK(vec));
  143. }