nile4.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  arch/mips/ddb5074/nile4.c -- NEC Vrc-5074 Nile 4 support routines
  3.  *
  4.  *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
  5.  *                     Sony Software Development Center Europe (SDCE), Brussels
  6.  */
  7. #include <linux/kernel.h>
  8. #include <linux/types.h>
  9. #include <asm/nile4.h>
  10. /*
  11.  *  Physical Device Address Registers
  12.  *
  13.  *  Note: 32 bit addressing only!
  14.  */
  15. void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width,
  16.     int on_memory_bus, int visible)
  17. {
  18. u32 maskbits;
  19. u32 widthbits;
  20. if (pdar > NILE4_BOOTCS || (pdar & 7)) {
  21. printk("nile4_set_pdar: invalid pdar %dn", pdar);
  22. return;
  23. }
  24. if (pdar == NILE4_INTCS && size != 0x00200000) {
  25. printk("nile4_set_pdar: INTCS size must be 2 MBn");
  26. return;
  27. }
  28. switch (size) {
  29. #if 0 /* We don't support 4 GB yet */
  30. case 0x100000000: /* 4 GB */
  31. maskbits = 4;
  32. break;
  33. #endif
  34. case 0x80000000: /* 2 GB */
  35. maskbits = 5;
  36. break;
  37. case 0x40000000: /* 1 GB */
  38. maskbits = 6;
  39. break;
  40. case 0x20000000: /* 512 MB */
  41. maskbits = 7;
  42. break;
  43. case 0x10000000: /* 256 MB */
  44. maskbits = 8;
  45. break;
  46. case 0x08000000: /* 128 MB */
  47. maskbits = 9;
  48. break;
  49. case 0x04000000: /* 64 MB */
  50. maskbits = 10;
  51. break;
  52. case 0x02000000: /* 32 MB */
  53. maskbits = 11;
  54. break;
  55. case 0x01000000: /* 16 MB */
  56. maskbits = 12;
  57. break;
  58. case 0x00800000: /* 8 MB */
  59. maskbits = 13;
  60. break;
  61. case 0x00400000: /* 4 MB */
  62. maskbits = 14;
  63. break;
  64. case 0x00200000: /* 2 MB */
  65. maskbits = 15;
  66. break;
  67. case 0: /* OFF */
  68. maskbits = 0;
  69. break;
  70. default:
  71. printk("nile4_set_pdar: unsupported size %pn", (void *) size);
  72. return;
  73. }
  74. switch (width) {
  75. case 8:
  76. widthbits = 0;
  77. break;
  78. case 16:
  79. widthbits = 1;
  80. break;
  81. case 32:
  82. widthbits = 2;
  83. break;
  84. case 64:
  85. widthbits = 3;
  86. break;
  87. default:
  88. printk("nile4_set_pdar: unsupported width %dn", width);
  89. return;
  90. }
  91. nile4_out32(pdar, maskbits | (on_memory_bus ? 0x10 : 0) |
  92.     (visible ? 0x20 : 0) | (widthbits << 6) |
  93.     (phys & 0xffe00000));
  94. nile4_out32(pdar + 4, 0);
  95. /*
  96.  * When programming a PDAR, the register should be read immediately
  97.  * after writing it. This ensures that address decoders are properly
  98.  * configured.
  99.  */
  100. nile4_in32(pdar);
  101. nile4_in32(pdar + 4);
  102. }
  103. /*
  104.  *  PCI Master Registers
  105.  *
  106.  *  Note: 32 bit addressing only!
  107.  */
  108. void nile4_set_pmr(u32 pmr, u32 type, u32 addr)
  109. {
  110. if (pmr != NILE4_PCIINIT0 && pmr != NILE4_PCIINIT1) {
  111. printk("nile4_set_pmr: invalid pmr %dn", pmr);
  112. return;
  113. }
  114. switch (type) {
  115. case NILE4_PCICMD_IACK: /* PCI Interrupt Acknowledge */
  116. case NILE4_PCICMD_IO: /* PCI I/O Space */
  117. case NILE4_PCICMD_MEM: /* PCI Memory Space */
  118. case NILE4_PCICMD_CFG: /* PCI Configuration Space */
  119. break;
  120. default:
  121. printk("nile4_set_pmr: invalid type %dn", type);
  122. return;
  123. }
  124. nile4_out32(pmr, (type << 1) | 0x10 | (addr & 0xffe00000));
  125. nile4_out32(pmr + 4, 0);
  126. }
  127. /*
  128.  *  Interrupt Programming
  129.  */
  130. void nile4_map_irq(int nile4_irq, int cpu_irq)
  131. {
  132. u32 offset, t;
  133. offset = NILE4_INTCTRL;
  134. if (nile4_irq >= 8) {
  135. offset += 4;
  136. nile4_irq -= 8;
  137. }
  138. t = nile4_in32(offset);
  139. t &= ~(7 << (nile4_irq * 4));
  140. t |= cpu_irq << (nile4_irq * 4);
  141. nile4_out32(offset, t);
  142. }
  143. void nile4_map_irq_all(int cpu_irq)
  144. {
  145. u32 all, t;
  146. all = cpu_irq;
  147. all |= all << 4;
  148. all |= all << 8;
  149. all |= all << 16;
  150. t = nile4_in32(NILE4_INTCTRL);
  151. t &= 0x88888888;
  152. t |= all;
  153. nile4_out32(NILE4_INTCTRL, t);
  154. t = nile4_in32(NILE4_INTCTRL + 4);
  155. t &= 0x88888888;
  156. t |= all;
  157. nile4_out32(NILE4_INTCTRL + 4, t);
  158. }
  159. void nile4_enable_irq(int nile4_irq)
  160. {
  161. u32 offset, t;
  162. offset = NILE4_INTCTRL;
  163. if (nile4_irq >= 8) {
  164. offset += 4;
  165. nile4_irq -= 8;
  166. }
  167. t = nile4_in32(offset);
  168. t |= 8 << (nile4_irq * 4);
  169. nile4_out32(offset, t);
  170. }
  171. void nile4_disable_irq(int nile4_irq)
  172. {
  173. u32 offset, t;
  174. offset = NILE4_INTCTRL;
  175. if (nile4_irq >= 8) {
  176. offset += 4;
  177. nile4_irq -= 8;
  178. }
  179. t = nile4_in32(offset);
  180. t &= ~(8 << (nile4_irq * 4));
  181. nile4_out32(offset, t);
  182. }
  183. void nile4_disable_irq_all(void)
  184. {
  185. nile4_out32(NILE4_INTCTRL, 0);
  186. nile4_out32(NILE4_INTCTRL + 4, 0);
  187. }
  188. u16 nile4_get_irq_stat(int cpu_irq)
  189. {
  190. return nile4_in16(NILE4_INTSTAT0 + cpu_irq * 2);
  191. }
  192. void nile4_enable_irq_output(int cpu_irq)
  193. {
  194. u32 t;
  195. t = nile4_in32(NILE4_INTSTAT1 + 4);
  196. t |= 1 << (16 + cpu_irq);
  197. nile4_out32(NILE4_INTSTAT1, t);
  198. }
  199. void nile4_disable_irq_output(int cpu_irq)
  200. {
  201. u32 t;
  202. t = nile4_in32(NILE4_INTSTAT1 + 4);
  203. t &= ~(1 << (16 + cpu_irq));
  204. nile4_out32(NILE4_INTSTAT1, t);
  205. }
  206. void nile4_set_pci_irq_polarity(int pci_irq, int high)
  207. {
  208. u32 t;
  209. t = nile4_in32(NILE4_INTPPES);
  210. if (high)
  211. t &= ~(1 << (pci_irq * 2));
  212. else
  213. t |= 1 << (pci_irq * 2);
  214. nile4_out32(NILE4_INTPPES, t);
  215. }
  216. void nile4_set_pci_irq_level_or_edge(int pci_irq, int level)
  217. {
  218. u32 t;
  219. t = nile4_in32(NILE4_INTPPES);
  220. if (level)
  221. t |= 2 << (pci_irq * 2);
  222. else
  223. t &= ~(2 << (pci_irq * 2));
  224. nile4_out32(NILE4_INTPPES, t);
  225. }
  226. void nile4_clear_irq(int nile4_irq)
  227. {
  228. nile4_out32(NILE4_INTCLR, 1 << nile4_irq);
  229. }
  230. void nile4_clear_irq_mask(u32 mask)
  231. {
  232. nile4_out32(NILE4_INTCLR, mask);
  233. }
  234. u8 nile4_i8259_iack(void)
  235. {
  236. u8 irq;
  237. /* Set window 0 for interrupt acknowledge */
  238. nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IACK, 0);
  239. irq = *(volatile u8 *) NILE4_PCI_IACK_BASE;
  240. /* Set window 0 for PCI I/O space */
  241. nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0);
  242. return irq;
  243. }
  244. #if 0
  245. void nile4_dump_irq_status(void)
  246. {
  247. printk("CPUSTAT = %p:%pn", (void *) nile4_in32(NILE4_CPUSTAT + 4),
  248.        (void *) nile4_in32(NILE4_CPUSTAT));
  249. printk("INTCTRL = %p:%pn", (void *) nile4_in32(NILE4_INTCTRL + 4),
  250.        (void *) nile4_in32(NILE4_INTCTRL));
  251. printk("INTSTAT0 = %p:%pn",
  252.        (void *) nile4_in32(NILE4_INTSTAT0 + 4),
  253.        (void *) nile4_in32(NILE4_INTSTAT0));
  254. printk("INTSTAT1 = %p:%pn",
  255.        (void *) nile4_in32(NILE4_INTSTAT1 + 4),
  256.        (void *) nile4_in32(NILE4_INTSTAT1));
  257. printk("INTCLR = %p:%pn", (void *) nile4_in32(NILE4_INTCLR + 4),
  258.        (void *) nile4_in32(NILE4_INTCLR));
  259. printk("INTPPES = %p:%pn", (void *) nile4_in32(NILE4_INTPPES + 4),
  260.        (void *) nile4_in32(NILE4_INTPPES));
  261. }
  262. #endif