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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: %F% %I% %G% %U% %#%
  3.  */
  4. /*
  5.  * CHRP pci routines.
  6.  */
  7. #include <linux/config.h>
  8. #include <linux/kernel.h>
  9. #include <linux/pci.h>
  10. #include <linux/delay.h>
  11. #include <linux/string.h>
  12. #include <linux/init.h>
  13. #include <linux/ide.h>
  14. #include <linux/bootmem.h>
  15. #include <asm/io.h>
  16. #include <asm/pgtable.h>
  17. #include <asm/irq.h>
  18. #include <asm/hydra.h>
  19. #include <asm/prom.h>
  20. #include <asm/gg2.h>
  21. #include <asm/machdep.h>
  22. #include <asm/sections.h>
  23. #include <asm/pci-bridge.h>
  24. #include <asm/open_pic.h>
  25. /* LongTrail */
  26. unsigned long gg2_pci_config_base;
  27. #define pci_config_addr(dev, offset) 
  28. (gg2_pci_config_base | ((dev->bus->number)<<16) | ((dev->devfn)<<8) | (offset))
  29. volatile struct Hydra *Hydra = NULL;
  30. /*
  31.  * The VLSI Golden Gate II has only 512K of PCI configuration space, so we
  32.  * limit the bus number to 3 bits
  33.  */
  34. #define cfg_read(val, addr, type, op) *val = op((type)(addr))
  35. #define cfg_write(val, addr, type, op) op((type *)(addr), (val))
  36. #define cfg_read_bad(val, size) *val = bad_##size;
  37. #define cfg_write_bad(val, size)
  38. #define bad_byte 0xff
  39. #define bad_word 0xffff
  40. #define bad_dword 0xffffffffU
  41. #define GG2_PCI_OP(rw, size, type, op)     
  42. int __chrp gg2_##rw##_config_##size(struct pci_dev *dev, int off, type val) 
  43. {     
  44. if (dev->bus->number > 7) {     
  45. cfg_##rw##_bad(val, size)     
  46. return PCIBIOS_DEVICE_NOT_FOUND;     
  47. }     
  48. cfg_##rw(val, pci_config_addr(dev, off), type, op);     
  49. return PCIBIOS_SUCCESSFUL;     
  50. }
  51. GG2_PCI_OP(read, byte, u8 *, in_8)
  52. GG2_PCI_OP(read, word, u16 *, in_le16)
  53. GG2_PCI_OP(read, dword, u32 *, in_le32)
  54. GG2_PCI_OP(write, byte, u8, out_8)
  55. GG2_PCI_OP(write, word, u16, out_le16)
  56. GG2_PCI_OP(write, dword, u32, out_le32)
  57. static struct pci_ops gg2_pci_ops =
  58. {
  59. gg2_read_config_byte,
  60. gg2_read_config_word,
  61. gg2_read_config_dword,
  62. gg2_write_config_byte,
  63. gg2_write_config_word,
  64. gg2_write_config_dword
  65. };
  66. /*
  67.  * Access functions for PCI config space on IBM "python" host bridges.
  68.  */
  69. #define PYTHON_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) 
  70.  | (((o) & ~3) << 24))
  71. #define PYTHON_PCI_OP(rw, size, type, op, mask)           
  72. int __chrp      
  73. python_##rw##_config_##size(struct pci_dev *dev, int offset, type val)       
  74. {      
  75. struct pci_controller *hose = dev->sysdata;      
  76.      
  77. out_be32(hose->cfg_addr,      
  78.  PYTHON_CFA(dev->bus->number, dev->devfn, offset));      
  79. cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);         
  80. return PCIBIOS_SUCCESSFUL;      
  81. }
  82. PYTHON_PCI_OP(read, byte, u8 *, in_8, 3)
  83. PYTHON_PCI_OP(read, word, u16 *, in_le16, 2)
  84. PYTHON_PCI_OP(read, dword, u32 *, in_le32, 0)
  85. PYTHON_PCI_OP(write, byte, u8, out_8, 3)
  86. PYTHON_PCI_OP(write, word, u16, out_le16, 2)
  87. PYTHON_PCI_OP(write, dword, u32, out_le32, 0)
  88. static struct pci_ops python_pci_ops =
  89. {
  90. python_read_config_byte,
  91. python_read_config_word,
  92. python_read_config_dword,
  93. python_write_config_byte,
  94. python_write_config_word,
  95. python_write_config_dword
  96. };
  97. /*
  98.  * Access functions for PCI config space using RTAS calls.
  99.  */
  100. #define RTAS_PCI_READ_OP(size, type, nbytes)        
  101. int __chrp   
  102. rtas_read_config_##size(struct pci_dev *dev, int offset, type val)    
  103. {   
  104. unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) 
  105. | ((dev->bus->number & 0xff) << 16);   
  106. unsigned long ret = ~0UL;   
  107. int rval;   
  108.   
  109. rval = call_rtas("read-pci-config", 2, 2, &ret, addr, nbytes);   
  110. *val = ret;   
  111. return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;       
  112. }
  113. #define RTAS_PCI_WRITE_OP(size, type, nbytes)   
  114. int __chrp   
  115. rtas_write_config_##size(struct pci_dev *dev, int offset, type val)   
  116. {   
  117. unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) 
  118. | ((dev->bus->number & 0xff) << 16);   
  119. int rval;   
  120.   
  121. rval = call_rtas("write-pci-config", 3, 1, NULL,   
  122.  addr, nbytes, (ulong)val);   
  123. return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;   
  124. }
  125. RTAS_PCI_READ_OP(byte, u8 *, 1)
  126. RTAS_PCI_READ_OP(word, u16 *, 2)
  127. RTAS_PCI_READ_OP(dword, u32 *, 4)
  128. RTAS_PCI_WRITE_OP(byte, u8, 1)
  129. RTAS_PCI_WRITE_OP(word, u16, 2)
  130. RTAS_PCI_WRITE_OP(dword, u32, 4)
  131. static struct pci_ops rtas_pci_ops =
  132. {
  133. rtas_read_config_byte,
  134. rtas_read_config_word,
  135. rtas_read_config_dword,
  136. rtas_write_config_byte,
  137. rtas_write_config_word,
  138. rtas_write_config_dword
  139. };
  140. int __init
  141. hydra_init(void)
  142. {
  143. struct device_node *np;
  144. np = find_devices("mac-io");
  145. if (np == NULL || np->n_addrs == 0)
  146. return 0;
  147. Hydra = ioremap(np->addrs[0].address, np->addrs[0].size);
  148. printk("Hydra Mac I/O at %xn", np->addrs[0].address);
  149. out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN |
  150.    HYDRA_FC_SCSI_CELL_EN |
  151.    HYDRA_FC_SCCA_ENABLE |
  152.    HYDRA_FC_SCCB_ENABLE |
  153.    HYDRA_FC_ARB_BYPASS |
  154.    HYDRA_FC_MPIC_ENABLE |
  155.    HYDRA_FC_SLOW_SCC_PCLK |
  156.    HYDRA_FC_MPIC_IS_MASTER));
  157. return 1;
  158. }
  159. void __init
  160. chrp_pcibios_fixup(void)
  161. {
  162. struct pci_dev *dev;
  163. struct device_node *np;
  164. /* PCI interrupts are controlled by the OpenPIC */
  165. pci_for_each_dev(dev) {
  166. np = pci_device_to_OF_node(dev);
  167. if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
  168. dev->irq = np->intrs[0].line;
  169. pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
  170. }
  171. }
  172. #define PRG_CL_RESET_VALID 0x00010000
  173. static void __init
  174. setup_python(struct pci_controller *hose, struct device_node *dev)
  175. {
  176. u32 *reg, val;
  177. volatile unsigned char *cfg;
  178. hose->ops = &python_pci_ops;
  179. cfg = ioremap(dev->addrs[0].address + 0xf8000, 0x20);
  180. hose->cfg_addr = (volatile unsigned int *) cfg;
  181. hose->cfg_data = cfg + 0x10;
  182. /* Clear the magic go-slow bit */
  183. reg = (u32 *) ioremap(dev->addrs[0].address + 0xf6000, 0x40);
  184. val = in_be32(&reg[12]);
  185. if (val & PRG_CL_RESET_VALID) {
  186. out_be32(&reg[12], val & ~PRG_CL_RESET_VALID);
  187. in_be32(&reg[12]);
  188. }
  189. iounmap(reg);
  190. }
  191. void __init
  192. chrp_find_bridges(void)
  193. {
  194. struct device_node *dev;
  195. int *bus_range;
  196. int len, index = -1;
  197. struct pci_controller *hose;
  198. unsigned int *dma;
  199. char *model, *machine;
  200. int is_longtrail = 0, is_mot = 0;
  201. struct device_node *root = find_path_device("/");
  202. /*
  203.  * The PCI host bridge nodes on some machines don't have
  204.  * properties to adequately identify them, so we have to
  205.  * look at what sort of machine this is as well.
  206.  */
  207. machine = get_property(root, "model", NULL);
  208. if (machine != NULL) {
  209. is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0;
  210. is_mot = strncmp(machine, "MOT", 3) == 0;
  211. }
  212. for (dev = root->child; dev != NULL; dev = dev->sibling) {
  213. if (dev->type == NULL || strcmp(dev->type, "pci") != 0)
  214. continue;
  215. ++index;
  216. /* The GG2 bridge on the LongTrail doesn't have an address */
  217. if (dev->n_addrs < 1 && !is_longtrail) {
  218. printk(KERN_WARNING "Can't use %s: no addressn",
  219.        dev->full_name);
  220. continue;
  221. }
  222. bus_range = (int *) get_property(dev, "bus-range", &len);
  223. if (bus_range == NULL || len < 2 * sizeof(int)) {
  224. printk(KERN_WARNING "Can't get bus-range for %sn",
  225. dev->full_name);
  226. continue;
  227. }
  228. if (bus_range[1] == bus_range[0])
  229. printk(KERN_INFO "PCI bus %d", bus_range[0]);
  230. else
  231. printk(KERN_INFO "PCI buses %d..%d",
  232.        bus_range[0], bus_range[1]);
  233. printk(" controlled by %s", dev->type);
  234. if (dev->n_addrs > 0)
  235. printk(" at %x", dev->addrs[0].address);
  236. printk("n");
  237. hose = pcibios_alloc_controller();
  238. if (!hose) {
  239. printk("Can't allocate PCI controller structure for %sn",
  240. dev->full_name);
  241. continue;
  242. }
  243. hose->arch_data = dev;
  244. hose->first_busno = bus_range[0];
  245. hose->last_busno = bus_range[1];
  246. model = get_property(dev, "model", NULL);
  247. if (model == NULL)
  248. model = "<none>";
  249. if (device_is_compatible(dev, "IBM,python")) {
  250. setup_python(hose, dev);
  251. } else if (is_mot
  252.    || strncmp(model, "Motorola, Grackle", 17) == 0) {
  253. setup_grackle(hose);
  254. } else if (is_longtrail) {
  255. hose->ops = &gg2_pci_ops;
  256. gg2_pci_config_base = (unsigned long)
  257. ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
  258. } else if (!strncmp(model, "IBM,CPC710", 10)) {
  259. setup_indirect_pci(hose,
  260. dev->addrs[0].address + 0x000f8000,
  261. dev->addrs[0].address + 0x000f8010);
  262. if (index == 0) {
  263. dma = (unsigned int *)
  264. get_property(dev, "system-dma-base", &len);
  265.   if (dma && len >= sizeof(*dma)) {
  266. dma = (unsigned int *)(((unsigned long)dma) +
  267. len - sizeof(*dma));
  268. pci_dram_offset = *dma;
  269. }
  270. }
  271. } else {
  272. printk("No methods for %s (model %s), using RTASn",
  273.        dev->full_name, model);
  274. hose->ops = &rtas_pci_ops;
  275. }
  276. pci_process_bridge_OF_ranges(hose, dev, index == 0);
  277. /* check the first bridge for a property that we can
  278.    use to set pci_dram_offset */
  279. dma = (unsigned int *)
  280. get_property(dev, "ibm,dma-ranges", &len);
  281. if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
  282. pci_dram_offset = dma[2] - dma[3];
  283. printk("pci_dram_offset = %lxn", pci_dram_offset);
  284. }
  285. }
  286. ppc_md.pcibios_fixup = chrp_pcibios_fixup;
  287. }