sys_takara.c 7.8 KB

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