sys_takara.c 8.1 KB

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