nile4.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

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",
  72.        (void *) size);
  73. return;
  74. }
  75. switch (width) {
  76. case 8:
  77. widthbits = 0;
  78. break;
  79. case 16:
  80. widthbits = 1;
  81. break;
  82. case 32:
  83. widthbits = 2;
  84. break;
  85. case 64:
  86. widthbits = 3;
  87. break;
  88. default:
  89. printk("nile4_set_pdar: unsupported width %dn", width);
  90. return;
  91. }
  92. nile4_out32(pdar, maskbits | (on_memory_bus ? 0x10 : 0) |
  93.     (visible ? 0x20 : 0) | (widthbits << 6) |
  94.     (phys & 0xffe00000));
  95. nile4_out32(pdar + 4, 0);
  96. /*
  97.  * When programming a PDAR, the register should be read immediately
  98.  * after writing it. This ensures that address decoders are properly
  99.  * configured.
  100.  */
  101. nile4_in32(pdar);
  102. nile4_in32(pdar + 4);
  103. }
  104. /*
  105.  *  PCI Master Registers
  106.  *
  107.  *  Note: 32 bit addressing only!
  108.  */
  109. void nile4_set_pmr(u32 pmr, u32 type, u32 addr)
  110. {
  111. if (pmr != NILE4_PCIINIT0 && pmr != NILE4_PCIINIT1) {
  112. printk("nile4_set_pmr: invalid pmr %dn", pmr);
  113. return;
  114. }
  115. switch (type) {
  116. case NILE4_PCICMD_IACK: /* PCI Interrupt Acknowledge */
  117. case NILE4_PCICMD_IO: /* PCI I/O Space */
  118. case NILE4_PCICMD_MEM: /* PCI Memory Space */
  119. case NILE4_PCICMD_CFG: /* PCI Configuration Space */
  120. break;
  121. default:
  122. printk("nile4_set_pmr: invalid type %dn", type);
  123. return;
  124. }
  125. nile4_out32(pmr, (type << 1) | 0x10 | (addr & 0xffe00000));
  126. nile4_out32(pmr + 4, 0);
  127. }
  128. /*
  129.  *  Interrupt Programming
  130.  */
  131. void nile4_map_irq(int nile4_irq, int cpu_irq)
  132. {
  133. u32 offset, t;
  134. offset = NILE4_INTCTRL;
  135. if (nile4_irq >= 8) {
  136. offset += 4;
  137. nile4_irq -= 8;
  138. }
  139. t = nile4_in32(offset);
  140. t &= ~(7 << (nile4_irq * 4));
  141. t |= cpu_irq << (nile4_irq * 4);
  142. nile4_out32(offset, t);
  143. }
  144. void nile4_map_irq_all(int cpu_irq)
  145. {
  146. u32 all, t;
  147. all = cpu_irq;
  148. all |= all << 4;
  149. all |= all << 8;
  150. all |= all << 16;
  151. t = nile4_in32(NILE4_INTCTRL);
  152. t &= 0x88888888;
  153. t |= all;
  154. nile4_out32(NILE4_INTCTRL, t);
  155. t = nile4_in32(NILE4_INTCTRL + 4);
  156. t &= 0x88888888;
  157. t |= all;
  158. nile4_out32(NILE4_INTCTRL + 4, t);
  159. }
  160. void nile4_enable_irq(int nile4_irq)
  161. {
  162. u32 offset, t;
  163. offset = NILE4_INTCTRL;
  164. if (nile4_irq >= 8) {
  165. offset += 4;
  166. nile4_irq -= 8;
  167. }
  168. t = nile4_in32(offset);
  169. t |= 8 << (nile4_irq * 4);
  170. nile4_out32(offset, t);
  171. }
  172. void nile4_disable_irq(int nile4_irq)
  173. {
  174. u32 offset, t;
  175. offset = NILE4_INTCTRL;
  176. if (nile4_irq >= 8) {
  177. offset += 4;
  178. nile4_irq -= 8;
  179. }
  180. t = nile4_in32(offset);
  181. t &= ~(8 << (nile4_irq * 4));
  182. nile4_out32(offset, t);
  183. }
  184. void nile4_disable_irq_all(void)
  185. {
  186. nile4_out32(NILE4_INTCTRL, 0);
  187. nile4_out32(NILE4_INTCTRL + 4, 0);
  188. }
  189. u16 nile4_get_irq_stat(int cpu_irq)
  190. {
  191. return nile4_in16(NILE4_INTSTAT0 + cpu_irq * 2);
  192. }
  193. void nile4_enable_irq_output(int cpu_irq)
  194. {
  195. u32 t;
  196. t = nile4_in32(NILE4_INTSTAT1 + 4);
  197. t |= 1 << (16 + cpu_irq);
  198. nile4_out32(NILE4_INTSTAT1, t);
  199. }
  200. void nile4_disable_irq_output(int cpu_irq)
  201. {
  202. u32 t;
  203. t = nile4_in32(NILE4_INTSTAT1 + 4);
  204. t &= ~(1 << (16 + cpu_irq));
  205. nile4_out32(NILE4_INTSTAT1, t);
  206. }
  207. void nile4_set_pci_irq_polarity(int pci_irq, int high)
  208. {
  209. u32 t;
  210. t = nile4_in32(NILE4_INTPPES);
  211. if (high)
  212. t &= ~(1 << (pci_irq * 2));
  213. else
  214. t |= 1 << (pci_irq * 2);
  215. nile4_out32(NILE4_INTPPES, t);
  216. }
  217. void nile4_set_pci_irq_level_or_edge(int pci_irq, int level)
  218. {
  219. u32 t;
  220. t = nile4_in32(NILE4_INTPPES);
  221. if (level)
  222. t |= 2 << (pci_irq * 2);
  223. else
  224. t &= ~(2 << (pci_irq * 2));
  225. nile4_out32(NILE4_INTPPES, t);
  226. }
  227. void nile4_clear_irq(int nile4_irq)
  228. {
  229. nile4_out32(NILE4_INTCLR, 1 << nile4_irq);
  230. }
  231. void nile4_clear_irq_mask(u32 mask)
  232. {
  233. nile4_out32(NILE4_INTCLR, mask);
  234. }
  235. u8 nile4_i8259_iack(void)
  236. {
  237. u8 irq;
  238. /* Set window 0 for interrupt acknowledge */
  239. nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IACK, 0);
  240. irq = *(volatile u8 *) NILE4_PCI_IACK_BASE;
  241. /* Set window 0 for PCI I/O space */
  242. nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0);
  243. return irq;
  244. }
  245. #if 0
  246. void nile4_dump_irq_status(void)
  247. {
  248. printk("CPUSTAT = %p:%pn", (void *) nile4_in32(NILE4_CPUSTAT + 4),
  249.        (void *) nile4_in32(NILE4_CPUSTAT));
  250. printk("INTCTRL = %p:%pn", (void *) nile4_in32(NILE4_INTCTRL + 4),
  251.        (void *) nile4_in32(NILE4_INTCTRL));
  252. printk("INTSTAT0 = %p:%pn",
  253.        (void *) nile4_in32(NILE4_INTSTAT0 + 4),
  254.        (void *) nile4_in32(NILE4_INTSTAT0));
  255. printk("INTSTAT1 = %p:%pn",
  256.        (void *) nile4_in32(NILE4_INTSTAT1 + 4),
  257.        (void *) nile4_in32(NILE4_INTSTAT1));
  258. printk("INTCLR = %p:%pn", (void *) nile4_in32(NILE4_INTCLR + 4),
  259.        (void *) nile4_in32(NILE4_INTCLR));
  260. printk("INTPPES = %p:%pn", (void *) nile4_in32(NILE4_INTPPES + 4),
  261.        (void *) nile4_in32(NILE4_INTPPES));
  262. }
  263. #endif