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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * SNI specific PCI support for RM200/RM300.
  7.  *
  8.  * Copyright (C) 1997 - 2000 Ralf Baechle
  9.  */
  10. #include <linux/config.h>
  11. #include <linux/kernel.h>
  12. #include <linux/init.h>
  13. #include <linux/pci.h>
  14. #include <linux/types.h>
  15. #include <asm/byteorder.h>
  16. #include <asm/sni.h>
  17. #ifdef CONFIG_PCI
  18. #define mkaddr(dev, where)                                                   
  19. do {                                                                         
  20. if ((dev)->bus->number == 0)                                         
  21. return -1;                                                   
  22. *(volatile u32 *)PCIMT_CONFIG_ADDRESS =                              
  23.  ((dev->bus->number    & 0xff) << 0x10) |                    
  24.          ((dev->devfn & 0xff) << 0x08) |                             
  25.          (where  & 0xfc);                                            
  26. } while(0);
  27. #if 0
  28. /* To do:  Bring this uptodate ...  */
  29. static void pcimt_pcibios_fixup (void)
  30. {
  31. struct pci_dev *dev;
  32. pci_for_each_dev(dev) {
  33. /*
  34.  * TODO: Take care of RM300 revision D boards for where the
  35.  * network slot became an ordinary PCI slot.
  36.  */
  37. if (dev->devfn == PCI_DEVFN(1, 0)) {
  38. /* Evil hack ...  */
  39. set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NO_WA);
  40. dev->irq = PCIMT_IRQ_SCSI;
  41. continue;
  42. }
  43. if (dev->devfn == PCI_DEVFN(2, 0)) {
  44. dev->irq = PCIMT_IRQ_ETHERNET;
  45. continue;
  46. }
  47. switch(dev->irq) {
  48. case 1 ... 4:
  49. dev->irq += PCIMT_IRQ_INTA - 1;
  50. break;
  51. case 0:
  52. break;
  53. default:
  54. printk("PCI device on bus %d, dev %d, function %d "
  55.        "impossible interrupt configured.n",
  56.        dev->bus->number, PCI_SLOT(dev->devfn),
  57.        PCI_SLOT(dev->devfn));
  58. }
  59. }
  60. }
  61. #endif
  62. /*
  63.  * We can't address 8 and 16 bit words directly.  Instead we have to
  64.  * read/write a 32bit word and mask/modify the data we actually want.
  65.  */
  66. static int pcimt_read_config_byte (struct pci_dev *dev,
  67.                                    int where, unsigned char *val)
  68. {
  69. u32 res;
  70. mkaddr(dev, where);
  71. res = *(volatile u32 *)PCIMT_CONFIG_DATA;
  72. res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff;
  73. *val = res;
  74. return PCIBIOS_SUCCESSFUL;
  75. }
  76. static int pcimt_read_config_word (struct pci_dev *dev,
  77.                                    int where, unsigned short *val)
  78. {
  79. u32 res;
  80. if (where & 1)
  81. return PCIBIOS_BAD_REGISTER_NUMBER;
  82. mkaddr(dev, where);
  83. res = *(volatile u32 *)PCIMT_CONFIG_DATA;
  84. res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff;
  85. *val = res;
  86. return PCIBIOS_SUCCESSFUL;
  87. }
  88. static int pcimt_read_config_dword (struct pci_dev *dev,
  89.                                     int where, unsigned int *val)
  90. {
  91. u32 res;
  92. if (where & 3)
  93. return PCIBIOS_BAD_REGISTER_NUMBER;
  94. mkaddr(dev, where);
  95. res = *(volatile u32 *)PCIMT_CONFIG_DATA;
  96. res = le32_to_cpu(res);
  97. *val = res;
  98. return PCIBIOS_SUCCESSFUL;
  99. }
  100. static int pcimt_write_config_byte (struct pci_dev *dev,
  101.                                     int where, unsigned char val)
  102. {
  103. mkaddr(dev, where);
  104. *(volatile u8 *)(PCIMT_CONFIG_DATA + (where & 3)) = val;
  105. return PCIBIOS_SUCCESSFUL;
  106. }
  107. static int pcimt_write_config_word (struct pci_dev *dev,
  108.                                     int where, unsigned short val)
  109. {
  110. if (where & 1)
  111. return PCIBIOS_BAD_REGISTER_NUMBER;
  112. mkaddr(dev, where);
  113. *(volatile u16 *)(PCIMT_CONFIG_DATA + (where & 3)) = le16_to_cpu(val);
  114. return PCIBIOS_SUCCESSFUL;
  115. }
  116. static int pcimt_write_config_dword (struct pci_dev *dev,
  117.                                      int where, unsigned int val)
  118. {
  119. if (where & 3)
  120. return PCIBIOS_BAD_REGISTER_NUMBER;
  121. mkaddr(dev, where);
  122. *(volatile u32 *)PCIMT_CONFIG_DATA = le32_to_cpu(val);
  123. return PCIBIOS_SUCCESSFUL;
  124. }
  125. struct pci_ops sni_pci_ops = {
  126. pcimt_read_config_byte,
  127. pcimt_read_config_word,
  128. pcimt_read_config_dword,
  129. pcimt_write_config_byte,
  130. pcimt_write_config_word,
  131. pcimt_write_config_dword
  132. };
  133. void __init
  134. pcibios_fixup_bus(struct pci_bus *b)
  135. {
  136. }
  137. void
  138. pcibios_update_resource(struct pci_dev *dev, struct resource *root,
  139. struct resource *res, int resource)
  140. {
  141. u32 new, check;
  142. int reg;
  143. new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
  144. if (resource < 6) {
  145. reg = PCI_BASE_ADDRESS_0 + 4*resource;
  146. } else if (resource == PCI_ROM_RESOURCE) {
  147. res->flags |= PCI_ROM_ADDRESS_ENABLE;
  148. new |= PCI_ROM_ADDRESS_ENABLE;
  149. reg = dev->rom_base_reg;
  150. } else {
  151. /* Somebody might have asked allocation of a non-standard resource */
  152. return;
  153. }
  154. pci_write_config_dword(dev, reg, new);
  155. pci_read_config_dword(dev, reg, &check);
  156. if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
  157. printk(KERN_ERR "PCI: Error while updating region "
  158.        "%s/%d (%08x != %08x)n", dev->slot_name, resource,
  159.        new, check);
  160. }
  161. }
  162. void __init pcibios_init(void)
  163. {
  164. struct pci_ops *ops = &sni_pci_ops;
  165. pci_scan_bus(0, ops, NULL);
  166. }
  167. int __init pcibios_enable_device(struct pci_dev *dev)
  168. {
  169. /* Not needed, since we enable all devices at startup.  */
  170. return 0;
  171. }
  172. void __init
  173. pcibios_align_resource(void *data, struct resource *res, unsigned long size)
  174. {
  175. }
  176. unsigned __init int pcibios_assign_all_busses(void)
  177. {
  178. return 0;
  179. }
  180. char * __init
  181. pcibios_setup(char *str)
  182. {
  183. /* Nothing to do for now.  */
  184. return str;
  185. }
  186. struct pci_fixup pcibios_fixups[] = {
  187. { 0 }
  188. };
  189. #endif /* CONFIG_PCI */