pcit.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. * PCI Tower specific code
  3. *
  4. * This file is subject to the terms and conditions of the GNU General Public
  5. * License. See the file "COPYING" in the main directory of this archive
  6. * for more details.
  7. *
  8. * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  9. */
  10. #include <linux/init.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/pci.h>
  13. #include <linux/serial_8250.h>
  14. #include <asm/sni.h>
  15. #include <asm/time.h>
  16. #include <asm/irq_cpu.h>
  17. #define PORT(_base,_irq) \
  18. { \
  19. .iobase = _base, \
  20. .irq = _irq, \
  21. .uartclk = 1843200, \
  22. .iotype = UPIO_PORT, \
  23. .flags = UPF_BOOT_AUTOCONF, \
  24. }
  25. static struct plat_serial8250_port pcit_data[] = {
  26. PORT(0x3f8, 0),
  27. PORT(0x2f8, 3),
  28. { },
  29. };
  30. static struct platform_device pcit_serial8250_device = {
  31. .name = "serial8250",
  32. .id = PLAT8250_DEV_PLATFORM,
  33. .dev = {
  34. .platform_data = pcit_data,
  35. },
  36. };
  37. static struct plat_serial8250_port pcit_cplus_data[] = {
  38. PORT(0x3f8, 0),
  39. PORT(0x2f8, 3),
  40. PORT(0x3e8, 4),
  41. PORT(0x2e8, 3),
  42. { },
  43. };
  44. static struct platform_device pcit_cplus_serial8250_device = {
  45. .name = "serial8250",
  46. .id = PLAT8250_DEV_PLATFORM,
  47. .dev = {
  48. .platform_data = pcit_cplus_data,
  49. },
  50. };
  51. static struct resource pcit_cmos_rsrc[] = {
  52. {
  53. .start = 0x70,
  54. .end = 0x71,
  55. .flags = IORESOURCE_IO
  56. },
  57. {
  58. .start = 8,
  59. .end = 8,
  60. .flags = IORESOURCE_IRQ
  61. }
  62. };
  63. static struct platform_device pcit_cmos_device = {
  64. .name = "rtc_cmos",
  65. .num_resources = ARRAY_SIZE(pcit_cmos_rsrc),
  66. .resource = pcit_cmos_rsrc
  67. };
  68. static struct resource sni_io_resource = {
  69. .start = 0x00000000UL,
  70. .end = 0x03bfffffUL,
  71. .name = "PCIT IO",
  72. .flags = IORESOURCE_IO,
  73. };
  74. static struct resource pcit_io_resources[] = {
  75. {
  76. .start = 0x00,
  77. .end = 0x1f,
  78. .name = "dma1",
  79. .flags = IORESOURCE_BUSY
  80. }, {
  81. .start = 0x40,
  82. .end = 0x5f,
  83. .name = "timer",
  84. .flags = IORESOURCE_BUSY
  85. }, {
  86. .start = 0x60,
  87. .end = 0x6f,
  88. .name = "keyboard",
  89. .flags = IORESOURCE_BUSY
  90. }, {
  91. .start = 0x80,
  92. .end = 0x8f,
  93. .name = "dma page reg",
  94. .flags = IORESOURCE_BUSY
  95. }, {
  96. .start = 0xc0,
  97. .end = 0xdf,
  98. .name = "dma2",
  99. .flags = IORESOURCE_BUSY
  100. }, {
  101. .start = 0xcf8,
  102. .end = 0xcfb,
  103. .name = "PCI config addr",
  104. .flags = IORESOURCE_BUSY
  105. }, {
  106. .start = 0xcfc,
  107. .end = 0xcff,
  108. .name = "PCI config data",
  109. .flags = IORESOURCE_BUSY
  110. }
  111. };
  112. static struct resource sni_mem_resource = {
  113. .start = 0x18000000UL,
  114. .end = 0x1fbfffffUL,
  115. .name = "PCIT PCI MEM",
  116. .flags = IORESOURCE_MEM
  117. };
  118. static void __init sni_pcit_resource_init(void)
  119. {
  120. int i;
  121. /* request I/O space for devices used on all i[345]86 PCs */
  122. for (i = 0; i < ARRAY_SIZE(pcit_io_resources); i++)
  123. request_resource(&sni_io_resource, pcit_io_resources + i);
  124. }
  125. extern struct pci_ops sni_pcit_ops;
  126. static struct pci_controller sni_pcit_controller = {
  127. .pci_ops = &sni_pcit_ops,
  128. .mem_resource = &sni_mem_resource,
  129. .mem_offset = 0x00000000UL,
  130. .io_resource = &sni_io_resource,
  131. .io_offset = 0x00000000UL,
  132. .io_map_base = SNI_PORT_BASE
  133. };
  134. static void enable_pcit_irq(unsigned int irq)
  135. {
  136. u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
  137. *(volatile u32 *)SNI_PCIT_INT_REG |= mask;
  138. }
  139. void disable_pcit_irq(unsigned int irq)
  140. {
  141. u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
  142. *(volatile u32 *)SNI_PCIT_INT_REG &= ~mask;
  143. }
  144. void end_pcit_irq(unsigned int irq)
  145. {
  146. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  147. enable_pcit_irq(irq);
  148. }
  149. static struct irq_chip pcit_irq_type = {
  150. .typename = "PCIT",
  151. .ack = disable_pcit_irq,
  152. .mask = disable_pcit_irq,
  153. .mask_ack = disable_pcit_irq,
  154. .unmask = enable_pcit_irq,
  155. .end = end_pcit_irq,
  156. };
  157. static void pcit_hwint1(void)
  158. {
  159. u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
  160. int irq;
  161. clear_c0_status(IE_IRQ1);
  162. irq = ffs((pending >> 16) & 0x7f);
  163. if (likely(irq > 0))
  164. do_IRQ(irq + SNI_PCIT_INT_START - 1);
  165. set_c0_status(IE_IRQ1);
  166. }
  167. static void pcit_hwint0(void)
  168. {
  169. u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
  170. int irq;
  171. clear_c0_status(IE_IRQ0);
  172. irq = ffs((pending >> 16) & 0x3f);
  173. if (likely(irq > 0))
  174. do_IRQ(irq + SNI_PCIT_INT_START - 1);
  175. set_c0_status(IE_IRQ0);
  176. }
  177. static void sni_pcit_hwint(void)
  178. {
  179. u32 pending = read_c0_cause() & read_c0_status();
  180. if (pending & C_IRQ1)
  181. pcit_hwint1();
  182. else if (pending & C_IRQ2)
  183. do_IRQ(MIPS_CPU_IRQ_BASE + 4);
  184. else if (pending & C_IRQ3)
  185. do_IRQ(MIPS_CPU_IRQ_BASE + 5);
  186. else if (pending & C_IRQ5)
  187. do_IRQ(MIPS_CPU_IRQ_BASE + 7);
  188. }
  189. static void sni_pcit_hwint_cplus(void)
  190. {
  191. u32 pending = read_c0_cause() & read_c0_status();
  192. if (pending & C_IRQ0)
  193. pcit_hwint0();
  194. else if (pending & C_IRQ1)
  195. do_IRQ(MIPS_CPU_IRQ_BASE + 3);
  196. else if (pending & C_IRQ2)
  197. do_IRQ(MIPS_CPU_IRQ_BASE + 4);
  198. else if (pending & C_IRQ3)
  199. do_IRQ(MIPS_CPU_IRQ_BASE + 5);
  200. else if (pending & C_IRQ5)
  201. do_IRQ(MIPS_CPU_IRQ_BASE + 7);
  202. }
  203. void __init sni_pcit_irq_init(void)
  204. {
  205. int i;
  206. mips_cpu_irq_init();
  207. for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
  208. set_irq_chip(i, &pcit_irq_type);
  209. *(volatile u32 *)SNI_PCIT_INT_REG = 0;
  210. sni_hwint = sni_pcit_hwint;
  211. change_c0_status(ST0_IM, IE_IRQ1);
  212. setup_irq(SNI_PCIT_INT_START + 6, &sni_isa_irq);
  213. }
  214. void __init sni_pcit_cplus_irq_init(void)
  215. {
  216. int i;
  217. mips_cpu_irq_init();
  218. for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
  219. set_irq_chip(i, &pcit_irq_type);
  220. *(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000;
  221. sni_hwint = sni_pcit_hwint_cplus;
  222. change_c0_status(ST0_IM, IE_IRQ0);
  223. setup_irq(MIPS_CPU_IRQ_BASE + 3, &sni_isa_irq);
  224. }
  225. void __init sni_pcit_init(void)
  226. {
  227. ioport_resource.end = sni_io_resource.end;
  228. #ifdef CONFIG_PCI
  229. PCIBIOS_MIN_IO = 0x9000;
  230. register_pci_controller(&sni_pcit_controller);
  231. #endif
  232. sni_pcit_resource_init();
  233. }
  234. static int __init snirm_pcit_setup_devinit(void)
  235. {
  236. switch (sni_brd_type) {
  237. case SNI_BRD_PCI_TOWER:
  238. platform_device_register(&pcit_serial8250_device);
  239. platform_device_register(&pcit_cmos_device);
  240. break;
  241. case SNI_BRD_PCI_TOWER_CPLUS:
  242. platform_device_register(&pcit_cplus_serial8250_device);
  243. platform_device_register(&pcit_cmos_device);
  244. break;
  245. }
  246. return 0;
  247. }
  248. device_initcall(snirm_pcit_setup_devinit);