sys_takara.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. * linux/arch/alpha/kernel/sys_takara.c
  3. *
  4. * Copyright (C) 1995 David A Rusling
  5. * Copyright (C) 1996 Jay A Estabrook
  6. * Copyright (C) 1998, 1999 Richard Henderson
  7. *
  8. * Code supporting the TAKARA.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/types.h>
  12. #include <linux/mm.h>
  13. #include <linux/sched.h>
  14. #include <linux/pci.h>
  15. #include <linux/init.h>
  16. #include <asm/ptrace.h>
  17. #include <asm/system.h>
  18. #include <asm/dma.h>
  19. #include <asm/irq.h>
  20. #include <asm/mmu_context.h>
  21. #include <asm/io.h>
  22. #include <asm/pgtable.h>
  23. #include <asm/core_cia.h>
  24. #include <asm/tlbflush.h>
  25. #include "proto.h"
  26. #include "irq_impl.h"
  27. #include "pci_impl.h"
  28. #include "machvec_impl.h"
  29. /* Note mask bit is true for DISABLED irqs. */
  30. static unsigned long cached_irq_mask[2] = { -1, -1 };
  31. static inline void
  32. takara_update_irq_hw(unsigned long irq, unsigned long mask)
  33. {
  34. int regaddr;
  35. mask = (irq >= 64 ? mask << 16 : mask >> ((irq - 16) & 0x30));
  36. regaddr = 0x510 + (((irq - 16) >> 2) & 0x0c);
  37. outl(mask & 0xffff0000UL, regaddr);
  38. }
  39. static inline void
  40. takara_enable_irq(unsigned int irq)
  41. {
  42. unsigned long mask;
  43. mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63)));
  44. takara_update_irq_hw(irq, mask);
  45. }
  46. static void
  47. takara_disable_irq(unsigned int irq)
  48. {
  49. unsigned long mask;
  50. mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63));
  51. takara_update_irq_hw(irq, mask);
  52. }
  53. static unsigned int
  54. takara_startup_irq(unsigned int irq)
  55. {
  56. takara_enable_irq(irq);
  57. return 0; /* never anything pending */
  58. }
  59. static void
  60. takara_end_irq(unsigned int irq)
  61. {
  62. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  63. takara_enable_irq(irq);
  64. }
  65. static struct hw_interrupt_type takara_irq_type = {
  66. .typename = "TAKARA",
  67. .startup = takara_startup_irq,
  68. .shutdown = takara_disable_irq,
  69. .enable = takara_enable_irq,
  70. .disable = takara_disable_irq,
  71. .ack = takara_disable_irq,
  72. .end = takara_end_irq,
  73. };
  74. static void
  75. takara_device_interrupt(unsigned long vector)
  76. {
  77. unsigned intstatus;
  78. /*
  79. * The PALcode will have passed us vectors 0x800 or 0x810,
  80. * which are fairly arbitrary values and serve only to tell
  81. * us whether an interrupt has come in on IRQ0 or IRQ1. If
  82. * it's IRQ1 it's a PCI interrupt; if it's IRQ0, it's
  83. * probably ISA, but PCI interrupts can come through IRQ0
  84. * as well if the interrupt controller isn't in accelerated
  85. * mode.
  86. *
  87. * OTOH, the accelerator thing doesn't seem to be working
  88. * overly well, so what we'll do instead is try directly
  89. * examining the Master Interrupt Register to see if it's a
  90. * PCI interrupt, and if _not_ then we'll pass it on to the
  91. * ISA handler.
  92. */
  93. intstatus = inw(0x500) & 15;
  94. if (intstatus) {
  95. /*
  96. * This is a PCI interrupt. Check each bit and
  97. * despatch an interrupt if it's set.
  98. */
  99. if (intstatus & 8) handle_irq(16+3);
  100. if (intstatus & 4) handle_irq(16+2);
  101. if (intstatus & 2) handle_irq(16+1);
  102. if (intstatus & 1) handle_irq(16+0);
  103. } else {
  104. isa_device_interrupt (vector);
  105. }
  106. }
  107. static void
  108. takara_srm_device_interrupt(unsigned long vector)
  109. {
  110. int irq = (vector - 0x800) >> 4;
  111. handle_irq(irq);
  112. }
  113. static void __init
  114. takara_init_irq(void)
  115. {
  116. long i;
  117. init_i8259a_irqs();
  118. if (alpha_using_srm) {
  119. alpha_mv.device_interrupt = takara_srm_device_interrupt;
  120. } else {
  121. unsigned int ctlreg = inl(0x500);
  122. /* Return to non-accelerated mode. */
  123. ctlreg &= ~0x8000;
  124. outl(ctlreg, 0x500);
  125. /* Enable the PCI interrupt register. */
  126. ctlreg = 0x05107c00;
  127. outl(ctlreg, 0x500);
  128. }
  129. for (i = 16; i < 128; i += 16)
  130. takara_update_irq_hw(i, -1);
  131. for (i = 16; i < 128; ++i) {
  132. irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
  133. irq_desc[i].chip = &takara_irq_type;
  134. }
  135. common_init_isa_dma();
  136. }
  137. /*
  138. * The Takara has PCI devices 1, 2, and 3 configured to slots 20,
  139. * 19, and 18 respectively, in the default configuration. They can
  140. * also be jumpered to slots 8, 7, and 6 respectively, which is fun
  141. * because the SIO ISA bridge can also be slot 7. However, the SIO
  142. * doesn't explicitly generate PCI-type interrupts, so we can
  143. * assign it whatever the hell IRQ we like and it doesn't matter.
  144. */
  145. static int __init
  146. takara_map_irq_srm(struct pci_dev *dev, u8 slot, u8 pin)
  147. {
  148. static char irq_tab[15][5] __initdata = {
  149. { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */
  150. { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */
  151. { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */
  152. { -1, -1, -1, -1, -1}, /* slot 9 == nothing */
  153. { -1, -1, -1, -1, -1}, /* slot 10 == nothing */
  154. { -1, -1, -1, -1, -1}, /* slot 11 == nothing */
  155. /* These are behind the bridges. */
  156. { 12, 12, 13, 14, 15}, /* slot 12 == nothing */
  157. { 8, 8, 9, 19, 11}, /* slot 13 == nothing */
  158. { 4, 4, 5, 6, 7}, /* slot 14 == nothing */
  159. { 0, 0, 1, 2, 3}, /* slot 15 == nothing */
  160. { -1, -1, -1, -1, -1}, /* slot 16 == nothing */
  161. {64+ 0, 64+0, 64+1, 64+2, 64+3}, /* slot 17= device 4 */
  162. {48+ 0, 48+0, 48+1, 48+2, 48+3}, /* slot 18= device 3 */
  163. {32+ 0, 32+0, 32+1, 32+2, 32+3}, /* slot 19= device 2 */
  164. {16+ 0, 16+0, 16+1, 16+2, 16+3}, /* slot 20= device 1 */
  165. };
  166. const long min_idsel = 6, max_idsel = 20, irqs_per_slot = 5;
  167. int irq = COMMON_TABLE_LOOKUP;
  168. if (irq >= 0 && irq < 16) {
  169. /* Guess that we are behind a bridge. */
  170. unsigned int busslot = PCI_SLOT(dev->bus->self->devfn);
  171. irq += irq_tab[busslot-min_idsel][0];
  172. }
  173. return irq;
  174. }
  175. static int __init
  176. takara_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
  177. {
  178. static char irq_tab[15][5] __initdata = {
  179. { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */
  180. { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */
  181. { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */
  182. { -1, -1, -1, -1, -1}, /* slot 9 == nothing */
  183. { -1, -1, -1, -1, -1}, /* slot 10 == nothing */
  184. { -1, -1, -1, -1, -1}, /* slot 11 == nothing */
  185. { -1, -1, -1, -1, -1}, /* slot 12 == nothing */
  186. { -1, -1, -1, -1, -1}, /* slot 13 == nothing */
  187. { -1, -1, -1, -1, -1}, /* slot 14 == nothing */
  188. { -1, -1, -1, -1, -1}, /* slot 15 == nothing */
  189. { -1, -1, -1, -1, -1}, /* slot 16 == nothing */
  190. { -1, -1, -1, -1, -1}, /* slot 17 == nothing */
  191. { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 18 == device 3 */
  192. { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 19 == device 2 */
  193. { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 20 == device 1 */
  194. };
  195. const long min_idsel = 6, max_idsel = 20, irqs_per_slot = 5;
  196. return COMMON_TABLE_LOOKUP;
  197. }
  198. static u8 __init
  199. takara_swizzle(struct pci_dev *dev, u8 *pinp)
  200. {
  201. int slot = PCI_SLOT(dev->devfn);
  202. int pin = *pinp;
  203. unsigned int ctlreg = inl(0x500);
  204. unsigned int busslot;
  205. if (!dev->bus->self)
  206. return slot;
  207. busslot = PCI_SLOT(dev->bus->self->devfn);
  208. /* Check for built-in bridges. */
  209. if (dev->bus->number != 0
  210. && busslot > 16
  211. && ((1<<(36-busslot)) & ctlreg)) {
  212. if (pin == 1)
  213. pin += (20 - busslot);
  214. else {
  215. printk(KERN_WARNING "takara_swizzle: can only "
  216. "handle cards with INTA IRQ pin.\n");
  217. }
  218. } else {
  219. /* Must be a card-based bridge. */
  220. printk(KERN_WARNING "takara_swizzle: cannot handle "
  221. "card-bridge behind builtin bridge yet.\n");
  222. }
  223. *pinp = pin;
  224. return slot;
  225. }
  226. static void __init
  227. takara_init_pci(void)
  228. {
  229. if (alpha_using_srm)
  230. alpha_mv.pci_map_irq = takara_map_irq_srm;
  231. cia_init_pci();
  232. ns87312_enable_ide(0x26e);
  233. }
  234. /*
  235. * The System Vector
  236. */
  237. struct alpha_machine_vector takara_mv __initmv = {
  238. .vector_name = "Takara",
  239. DO_EV5_MMU,
  240. DO_DEFAULT_RTC,
  241. DO_CIA_IO,
  242. .machine_check = cia_machine_check,
  243. .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
  244. .min_io_address = DEFAULT_IO_BASE,
  245. .min_mem_address = CIA_DEFAULT_MEM_BASE,
  246. .nr_irqs = 128,
  247. .device_interrupt = takara_device_interrupt,
  248. .init_arch = cia_init_arch,
  249. .init_irq = takara_init_irq,
  250. .init_rtc = common_init_rtc,
  251. .init_pci = takara_init_pci,
  252. .kill_arch = cia_kill_arch,
  253. .pci_map_irq = takara_map_irq,
  254. .pci_swizzle = takara_swizzle,
  255. };
  256. ALIAS_MV(takara)