entry-macro.S 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * arch/arm/plat-omap/include/mach/entry-macro.S
  3. *
  4. * Low-level IRQ helper macros for OMAP-based platforms
  5. *
  6. * Copyright (C) 2009 Texas Instruments
  7. * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
  8. *
  9. * This file is licensed under the terms of the GNU General Public
  10. * License version 2. This program is licensed "as is" without any
  11. * warranty of any kind, whether express or implied.
  12. */
  13. #include <mach/hardware.h>
  14. #include <mach/io.h>
  15. #include <mach/irqs.h>
  16. #include <asm/hardware/gic.h>
  17. #if defined(CONFIG_ARCH_OMAP1)
  18. #if defined(CONFIG_ARCH_OMAP730) && \
  19. (defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX))
  20. #error "FIXME: OMAP730 doesn't support multiple-OMAP"
  21. #elif defined(CONFIG_ARCH_OMAP730)
  22. #define INT_IH2_IRQ INT_730_IH2_IRQ
  23. #elif defined(CONFIG_ARCH_OMAP15XX)
  24. #define INT_IH2_IRQ INT_1510_IH2_IRQ
  25. #elif defined(CONFIG_ARCH_OMAP16XX)
  26. #define INT_IH2_IRQ INT_1610_IH2_IRQ
  27. #else
  28. #warning "IH2 IRQ defaulted"
  29. #define INT_IH2_IRQ INT_1510_IH2_IRQ
  30. #endif
  31. .macro disable_fiq
  32. .endm
  33. .macro get_irqnr_preamble, base, tmp
  34. .endm
  35. .macro arch_ret_to_user, tmp1, tmp2
  36. .endm
  37. .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
  38. ldr \base, =OMAP1_IO_ADDRESS(OMAP_IH1_BASE)
  39. ldr \irqnr, [\base, #IRQ_ITR_REG_OFFSET]
  40. ldr \tmp, [\base, #IRQ_MIR_REG_OFFSET]
  41. mov \irqstat, #0xffffffff
  42. bic \tmp, \irqstat, \tmp
  43. tst \irqnr, \tmp
  44. beq 1510f
  45. ldr \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
  46. cmp \irqnr, #0
  47. ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
  48. cmpeq \irqnr, #INT_IH2_IRQ
  49. ldreq \base, =OMAP1_IO_ADDRESS(OMAP_IH2_BASE)
  50. ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
  51. addeqs \irqnr, \irqnr, #32
  52. 1510:
  53. .endm
  54. #endif
  55. #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
  56. defined(CONFIG_ARCH_OMAP4)
  57. #include <mach/omap24xx.h>
  58. #include <mach/omap34xx.h>
  59. /* REVISIT: This should be set dynamically if CONFIG_MULTI_OMAP2 is selected */
  60. #if defined(CONFIG_ARCH_OMAP2420) || defined(CONFIG_ARCH_OMAP2430)
  61. #define OMAP2_VA_IC_BASE OMAP2_IO_ADDRESS(OMAP24XX_IC_BASE)
  62. #elif defined(CONFIG_ARCH_OMAP34XX)
  63. #define OMAP2_VA_IC_BASE OMAP2_IO_ADDRESS(OMAP34XX_IC_BASE)
  64. #endif
  65. #if defined(CONFIG_ARCH_OMAP4)
  66. #include <mach/omap44xx.h>
  67. #endif
  68. #define INTCPS_SIR_IRQ_OFFSET 0x0040 /* Active interrupt offset */
  69. #define ACTIVEIRQ_MASK 0x7f /* Active interrupt bits */
  70. .macro disable_fiq
  71. .endm
  72. .macro get_irqnr_preamble, base, tmp
  73. .endm
  74. .macro arch_ret_to_user, tmp1, tmp2
  75. .endm
  76. #ifndef CONFIG_ARCH_OMAP4
  77. .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
  78. ldr \base, =OMAP2_VA_IC_BASE
  79. ldr \irqnr, [\base, #0x98] /* IRQ pending reg 1 */
  80. cmp \irqnr, #0x0
  81. bne 2222f
  82. ldr \irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
  83. cmp \irqnr, #0x0
  84. bne 2222f
  85. ldr \irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
  86. cmp \irqnr, #0x0
  87. 2222:
  88. ldrne \irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
  89. and \irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
  90. .endm
  91. #else
  92. /*
  93. * The interrupt numbering scheme is defined in the
  94. * interrupt controller spec. To wit:
  95. *
  96. * Interrupts 0-15 are IPI
  97. * 16-28 are reserved
  98. * 29-31 are local. We allow 30 to be used for the watchdog.
  99. * 32-1020 are global
  100. * 1021-1022 are reserved
  101. * 1023 is "spurious" (no interrupt)
  102. *
  103. * For now, we ignore all local interrupts so only return an
  104. * interrupt if it's between 30 and 1020. The test_for_ipi
  105. * routine below will pick up on IPIs.
  106. * A simple read from the controller will tell us the number
  107. * of the highest priority enabled interrupt.
  108. * We then just need to check whether it is in the
  109. * valid range for an IRQ (30-1020 inclusive).
  110. */
  111. .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
  112. ldr \base, =OMAP44XX_VA_GIC_CPU_BASE
  113. ldr \irqstat, [\base, #GIC_CPU_INTACK]
  114. ldr \tmp, =1021
  115. bic \irqnr, \irqstat, #0x1c00
  116. cmp \irqnr, #29
  117. cmpcc \irqnr, \irqnr
  118. cmpne \irqnr, \tmp
  119. cmpcs \irqnr, \irqnr
  120. .endm
  121. /* We assume that irqstat (the raw value of the IRQ acknowledge
  122. * register) is preserved from the macro above.
  123. * If there is an IPI, we immediately signal end of interrupt
  124. * on the controller, since this requires the original irqstat
  125. * value which we won't easily be able to recreate later.
  126. */
  127. .macro test_for_ipi, irqnr, irqstat, base, tmp
  128. bic \irqnr, \irqstat, #0x1c00
  129. cmp \irqnr, #16
  130. it cc
  131. strcc \irqstat, [\base, #GIC_CPU_EOI]
  132. it cs
  133. cmpcs \irqnr, \irqnr
  134. .endm
  135. /* As above, this assumes that irqstat and base are preserved */
  136. .macro test_for_ltirq, irqnr, irqstat, base, tmp
  137. bic \irqnr, \irqstat, #0x1c00
  138. mov \tmp, #0
  139. cmp \irqnr, #29
  140. itt eq
  141. moveq \tmp, #1
  142. streq \irqstat, [\base, #GIC_CPU_EOI]
  143. cmp \tmp, #0
  144. .endm
  145. #endif
  146. .macro irq_prio_table
  147. .endm
  148. #endif