sys_takara.c 7.9 KB

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