uaa

[wip:20200101] add F1C100s support for sunxi_intc.c

uaa
Dec 31st, 2019
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.53 KB | None | 0 0
  1. Index: sunxi_intc.c
  2. ===================================================================
  3. RCS file: /cvsroot/src/sys/arch/arm/sunxi/sunxi_intc.c,v
  4. retrieving revision 1.3
  5. diff -u -p -r1.3 sunxi_intc.c
  6. --- sunxi_intc.c 24 Oct 2017 15:07:09 -0000 1.3
  7. +++ sunxi_intc.c 31 Dec 2019 21:12:34 -0000
  8. @@ -44,26 +44,53 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_intc.c
  9. #include <arm/pic/picvar.h>
  10. #include <arm/fdt/arm_fdtvar.h>
  11.  
  12. -#define INTC_MAX_SOURCES 96
  13. -#define INTC_MAX_GROUPS 3
  14. +#define SUNXI_INTC_MAX_SOURCES 96
  15. +#define SUNXI_INTC_MAX_GROUPS 3
  16.  
  17. -#define INTC_VECTOR_REG 0x00
  18. -#define INTC_BASE_ADDR_REG 0x04
  19. -#define INTC_PROTECT_REG 0x08
  20. -#define INTC_PROTECT_EN __BIT(0)
  21. -#define INTC_NMII_CTRL_REG 0x0c
  22. -#define INTC_IRQ_PEND_REG(n) (0x10 + ((n) * 4))
  23. -#define INTC_FIQ_PEND_REG(n) (0x20 + ((n) * 4))
  24. -#define INTC_SEL_REG(n) (0x30 + ((n) * 4))
  25. -#define INTC_EN_REG(n) (0x40 + ((n) * 4))
  26. -#define INTC_MASK_REG(n) (0x50 + ((n) * 4))
  27. -#define INTC_RESP_REG(n) (0x60 + ((n) * 4))
  28. -#define INTC_FORCE_REG(n) (0x70 + ((n) * 4))
  29. -#define INTC_SRC_PRIO_REG(n) (0x80 + ((n) * 4))
  30. -
  31. -static const char * const compatible[] = {
  32. - "allwinner,sun4i-a10-ic",
  33. - NULL
  34. +#define SUNIV_INTC_MAX_SOURCES 64
  35. +#define SUNIV_INTC_MAX_GROUPS 2
  36. +
  37. +#define INTC_MAX_SOURCES(sc) ((sc)->sc_conf->max_sources)
  38. +#define INTC_MAX_GROUPS(sc) ((sc)->sc_conf->max_groups)
  39. +
  40. +#define INTC_VECTOR_REG 0x00
  41. +#define INTC_BASE_ADDR_REG 0x04
  42. +#define INTC_PROTECT_REG(sc) ((sc)->sc_conf->protect_reg_offset)
  43. +#define INTC_PROTECT_EN __BIT(0)
  44. +#define INTC_IRQ_PEND_REG(n) (0x10 + ((n) * 4))
  45. +#define INTC_EN_REG(sc, n) \
  46. + ((sc)->sc_conf->en_reg_offset + ((n) * 4))
  47. +#define INTC_MASK_REG(sc, n) \
  48. + ((sc)->sc_conf->mask_reg_offset + ((n) * 4))
  49. +
  50. +struct sunxi_intc_config {
  51. + int max_sources;
  52. + int max_groups;
  53. + int protect_reg_offset;
  54. + int en_reg_offset;
  55. + int mask_reg_offset;
  56. +};
  57. +
  58. +static const struct sunxi_intc_config sun4i_a10_ic_config = {
  59. + .max_sources = SUNXI_INTC_MAX_SOURCES,
  60. + .max_groups = SUNXI_INTC_MAX_GROUPS,
  61. + .protect_reg_offset = 0x08,
  62. + .en_reg_offset = 0x40,
  63. + .mask_reg_offset = 0x50,
  64. +};
  65. +
  66. +static const struct sunxi_intc_config suniv_ic_config = {
  67. + .max_sources = SUNIV_INTC_MAX_SOURCES,
  68. + .max_groups = SUNIV_INTC_MAX_GROUPS,
  69. + .protect_reg_offset = 0, /* no PROTECT_REG */
  70. + .en_reg_offset = 0x20,
  71. + .mask_reg_offset = 0x30,
  72. +};
  73. +
  74. +static const struct of_compat_data compat_data[] = {
  75. + { "allwinner,sun4i-a10-ic", (uintptr_t)&sun4i_a10_ic_config },
  76. + { "allwinner,suniv-ic", (uintptr_t)&suniv_ic_config },
  77. + { NULL }
  78. };
  79.  
  80. struct sunxi_intc_softc {
  81. @@ -72,7 +99,9 @@ struct sunxi_intc_softc {
  82. bus_space_handle_t sc_bsh;
  83. int sc_phandle;
  84.  
  85. - uint32_t sc_enabled_irqs[INTC_MAX_GROUPS];
  86. + const struct sunxi_intc_config *sc_conf;
  87. +
  88. + uint32_t sc_enabled_irqs[SUNXI_INTC_MAX_GROUPS];
  89.  
  90. struct pic_softc sc_pic;
  91. };
  92. @@ -95,8 +124,8 @@ sunxi_intc_unblock_irqs(struct pic_softc
  93.  
  94. KASSERT((mask & sc->sc_enabled_irqs[group]) == 0);
  95. sc->sc_enabled_irqs[group] |= mask;
  96. - INTC_WRITE(sc, INTC_EN_REG(group), sc->sc_enabled_irqs[group]);
  97. - INTC_WRITE(sc, INTC_MASK_REG(group), ~sc->sc_enabled_irqs[group]);
  98. + INTC_WRITE(sc, INTC_EN_REG(sc, group), sc->sc_enabled_irqs[group]);
  99. + INTC_WRITE(sc, INTC_MASK_REG(sc, group), ~sc->sc_enabled_irqs[group]);
  100. }
  101.  
  102. static void
  103. @@ -106,14 +135,16 @@ sunxi_intc_block_irqs(struct pic_softc *
  104. const u_int group = irqbase / 32;
  105.  
  106. sc->sc_enabled_irqs[group] &= ~mask;
  107. - INTC_WRITE(sc, INTC_EN_REG(group), sc->sc_enabled_irqs[group]);
  108. - INTC_WRITE(sc, INTC_MASK_REG(group), ~sc->sc_enabled_irqs[group]);
  109. + INTC_WRITE(sc, INTC_EN_REG(sc, group), sc->sc_enabled_irqs[group]);
  110. + INTC_WRITE(sc, INTC_MASK_REG(sc, group), ~sc->sc_enabled_irqs[group]);
  111. }
  112.  
  113. static void
  114. sunxi_intc_establish_irq(struct pic_softc *pic, struct intrsource *is)
  115. {
  116. - KASSERT(is->is_irq < INTC_MAX_SOURCES);
  117. + struct sunxi_intc_softc * const sc = PICTOSOFTC(pic);
  118. +
  119. + KASSERT(is->is_irq < INTC_MAX_SOURCES(sc));
  120. KASSERT(is->is_type == IST_LEVEL);
  121. }
  122.  
  123. @@ -133,10 +164,12 @@ static void *
  124. sunxi_intc_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags,
  125. int (*func)(void *), void *arg)
  126. {
  127. + struct sunxi_intc_softc * const sc = device_private(dev);
  128. +
  129. /* 1st cell is the interrupt number */
  130. const u_int irq = be32toh(specifier[0]);
  131.  
  132. - if (irq >= INTC_MAX_SOURCES) {
  133. + if (irq >= INTC_MAX_SOURCES(sc)) {
  134. #ifdef DIAGNOSTIC
  135. device_printf(dev, "IRQ %u is invalid\n", irq);
  136. #endif
  137. @@ -196,16 +229,14 @@ sunxi_intc_irq_handler(void *frame)
  138. struct sunxi_intc_softc * const sc = intc_softc;
  139. const int oldipl = ci->ci_cpl;
  140. const uint32_t oldipl_mask = __BIT(oldipl);
  141. - int ipl_mask = 0;
  142. + int i, ipl_mask = 0;
  143.  
  144. ci->ci_data.cpu_nintr++;
  145.  
  146. - if (sc->sc_enabled_irqs[0])
  147. - ipl_mask |= sunxi_intc_find_pending_irqs(sc, 0);
  148. - if (sc->sc_enabled_irqs[1])
  149. - ipl_mask |= sunxi_intc_find_pending_irqs(sc, 1);
  150. - if (sc->sc_enabled_irqs[2])
  151. - ipl_mask |= sunxi_intc_find_pending_irqs(sc, 2);
  152. + for (i = 0; i < INTC_MAX_GROUPS(sc); i++) {
  153. + if (sc->sc_enabled_irqs[i])
  154. + ipl_mask |= sunxi_intc_find_pending_irqs(sc, i);
  155. + }
  156.  
  157. if ((ipl_mask & ~oldipl_mask) > oldipl_mask)
  158. pic_do_pending_ints(I32_bit, oldipl, frame);
  159. @@ -216,7 +247,7 @@ sunxi_intc_match(device_t parent, cfdata
  160. {
  161. struct fdt_attach_args * const faa = aux;
  162.  
  163. - return of_match_compatible(faa->faa_phandle, compatible);
  164. + return of_match_compat_data(faa->faa_phandle, compat_data);
  165. }
  166.  
  167. static void
  168. @@ -241,22 +272,24 @@ sunxi_intc_attach(device_t parent, devic
  169. aprint_error(": couldn't map registers\n");
  170. return;
  171. }
  172. + sc->sc_conf = (void *)of_search_compatible(phandle, compat_data)->data;
  173.  
  174. aprint_naive("\n");
  175. aprint_normal(": Interrupt Controller\n");
  176.  
  177. /* Disable IRQs */
  178. - for (i = 0; i < INTC_MAX_GROUPS; i++) {
  179. - INTC_WRITE(sc, INTC_EN_REG(i), 0);
  180. - INTC_WRITE(sc, INTC_MASK_REG(i), ~0U);
  181. + for (i = 0; i < INTC_MAX_GROUPS(sc); i++) {
  182. + INTC_WRITE(sc, INTC_EN_REG(sc, i), 0);
  183. + INTC_WRITE(sc, INTC_MASK_REG(sc, i), ~0U);
  184. INTC_WRITE(sc, INTC_IRQ_PEND_REG(i),
  185. INTC_READ(sc, INTC_IRQ_PEND_REG(i)));
  186. }
  187. /* Disable user mode access to intc registers */
  188. - INTC_WRITE(sc, INTC_PROTECT_REG, INTC_PROTECT_EN);
  189. + if (INTC_PROTECT_REG(sc))
  190. + INTC_WRITE(sc, INTC_PROTECT_REG(sc), INTC_PROTECT_EN);
  191.  
  192. sc->sc_pic.pic_ops = &sunxi_intc_picops;
  193. - sc->sc_pic.pic_maxsources = INTC_MAX_SOURCES;
  194. + sc->sc_pic.pic_maxsources = INTC_MAX_SOURCES(sc);
  195. snprintf(sc->sc_pic.pic_name, sizeof(sc->sc_pic.pic_name), "intc");
  196. pic_add(&sc->sc_pic, 0);
Add Comment
Please, Sign In to add comment