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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  arch/mips/ddb5074/pci.c -- NEC DDB Vrc-5074 PCI access routines
  3.  *
  4.  *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
  5.  *                     Albert Dorofeev <albert@sonycom.com>
  6.  *                     Sony Software Development Center Europe (SDCE), Brussels
  7.  */
  8. #include <linux/init.h>
  9. #include <linux/kernel.h>
  10. #include <linux/pci.h>
  11. #include <linux/types.h>
  12. #include <linux/sched.h>
  13. #include <linux/ioport.h>
  14. #include <asm/nile4.h>
  15. static u32 nile4_pre_pci_access0(int slot_num)
  16. {
  17. u32 pci_addr = 0;
  18. u32 virt_addr = NILE4_PCI_CFG_BASE;
  19. /* Set window 1 address 8000000 - 64 bit - 2 MB (PCI config space) */
  20. nile4_set_pdar(NILE4_PCIW1, PHYSADDR(virt_addr), 0x00200000, 64, 0,
  21.        0);
  22. if (slot_num > 2)
  23. pci_addr = 0x00040000 << slot_num;
  24. else
  25. virt_addr += 0x00040000 << slot_num;
  26. nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, pci_addr);
  27. return virt_addr;
  28. }
  29. static void nile4_post_pci_access0(void)
  30. {
  31. /*
  32.  * Set window 1 back to address 8000000 - 64 bit - 128 MB
  33.  * (PCI IO space)
  34.  */
  35. nile4_set_pdar(NILE4_PCIW1, PHYSADDR(NILE4_PCI_MEM_BASE),
  36.        0x08000000, 64, 1, 1);
  37. nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0);
  38. }
  39. static int nile4_pci_read_config_dword(struct pci_dev *dev,
  40.        int where, u32 * val)
  41. {
  42. int slot_num, func_num;
  43. u32 base;
  44. /*
  45.  *  For starters let's do configuration cycle 0 only (one bus only)
  46.  */
  47. if (dev->bus->number)
  48. return PCIBIOS_FUNC_NOT_SUPPORTED;
  49. slot_num = PCI_SLOT(dev->devfn);
  50. func_num = PCI_FUNC(dev->devfn);
  51. if (slot_num == 5) {
  52. /*
  53.  * This is Nile 4 and it will crash if we access it like other
  54.  * devices
  55.  */
  56. *val = nile4_in32(NILE4_PCI_BASE + where);
  57. return PCIBIOS_SUCCESSFUL;
  58. }
  59. base = nile4_pre_pci_access0(slot_num);
  60. *val =
  61.     *((volatile u32 *) (base + (func_num << 8) + (where & 0xfc)));
  62. nile4_post_pci_access0();
  63. return PCIBIOS_SUCCESSFUL;
  64. }
  65. static int nile4_pci_write_config_dword(struct pci_dev *dev, int where,
  66. u32 val)
  67. {
  68. int slot_num, func_num;
  69. u32 base;
  70. /*
  71.  * For starters let's do configuration cycle 0 only (one bus only)
  72.  */
  73. if (dev->bus->number)
  74. return PCIBIOS_FUNC_NOT_SUPPORTED;
  75. slot_num = PCI_SLOT(dev->devfn);
  76. func_num = PCI_FUNC(dev->devfn);
  77. if (slot_num == 5) {
  78. /*
  79.  * This is Nile 4 and it will crash if we access it like other
  80.  * devices
  81.  */
  82. nile4_out32(NILE4_PCI_BASE + where, val);
  83. return PCIBIOS_SUCCESSFUL;
  84. }
  85. base = nile4_pre_pci_access0(slot_num);
  86. *((volatile u32 *) (base + (func_num << 8) + (where & 0xfc))) =
  87.     val;
  88. nile4_post_pci_access0();
  89. return PCIBIOS_SUCCESSFUL;
  90. }
  91. static int nile4_pci_read_config_word(struct pci_dev *dev, int where,
  92.       u16 * val)
  93. {
  94. int status;
  95. u32 result;
  96. status = nile4_pci_read_config_dword(dev, where, &result);
  97. if (status != PCIBIOS_SUCCESSFUL)
  98. return status;
  99. if (where & 2)
  100. result >>= 16;
  101. *val = result & 0xffff;
  102. return PCIBIOS_SUCCESSFUL;
  103. }
  104. static int nile4_pci_read_config_byte(struct pci_dev *dev, int where,
  105.       u8 * val)
  106. {
  107. int status;
  108. u32 result;
  109. status = nile4_pci_read_config_dword(dev, where, &result);
  110. if (status != PCIBIOS_SUCCESSFUL)
  111. return status;
  112. if (where & 1)
  113. result >>= 8;
  114. if (where & 2)
  115. result >>= 16;
  116. *val = result & 0xff;
  117. return PCIBIOS_SUCCESSFUL;
  118. }
  119. static int nile4_pci_write_config_word(struct pci_dev *dev, int where,
  120.        u16 val)
  121. {
  122. int status, shift = 0;
  123. u32 result;
  124. status = nile4_pci_read_config_dword(dev, where, &result);
  125. if (status != PCIBIOS_SUCCESSFUL)
  126. return status;
  127. if (where & 2)
  128. shift += 16;
  129. result &= ~(0xffff << shift);
  130. result |= val << shift;
  131. return nile4_pci_write_config_dword(dev, where, result);
  132. }
  133. static int nile4_pci_write_config_byte(struct pci_dev *dev, int where,
  134.        u8 val)
  135. {
  136. int status, shift = 0;
  137. u32 result;
  138. status = nile4_pci_read_config_dword(dev, where, &result);
  139. if (status != PCIBIOS_SUCCESSFUL)
  140. return status;
  141. if (where & 2)
  142. shift += 16;
  143. if (where & 1)
  144. shift += 8;
  145. result &= ~(0xff << shift);
  146. result |= val << shift;
  147. return nile4_pci_write_config_dword(dev, where, result);
  148. }
  149. struct pci_ops nile4_pci_ops = {
  150. nile4_pci_read_config_byte,
  151. nile4_pci_read_config_word,
  152. nile4_pci_read_config_dword,
  153. nile4_pci_write_config_byte,
  154. nile4_pci_write_config_word,
  155. nile4_pci_write_config_dword
  156. };
  157. struct {
  158. struct resource ram;
  159. struct resource flash;
  160. struct resource isa_io;
  161. struct resource pci_io;
  162. struct resource isa_mem;
  163. struct resource pci_mem;
  164. struct resource nile4;
  165. struct resource boot;
  166. } ddb5074_resources = {
  167. { "RAM", 0x00000000, 0x03ffffff,
  168.   IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64},
  169. { "Flash ROM", 0x04000000, 0x043fffff},
  170. { "Nile4 ISA I/O", 0x06000000, 0x060fffff},
  171. { "Nile4 PCI I/O", 0x06100000, 0x07ffffff},
  172. { "Nile4 ISA mem", 0x08000000, 0x08ffffff, IORESOURCE_MEM},
  173. { "Nile4 PCI mem", 0x09000000, 0x0fffffff, IORESOURCE_MEM},
  174. { "Nile4 ctrl", 0x1fa00000, 0x1fbfffff,
  175.   IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64},
  176. { "Boot ROM", 0x1fc00000, 0x1fffffff}
  177. };
  178. static void __init ddb5074_pci_fixup(void)
  179. {
  180. struct pci_dev *dev;
  181. pci_for_each_dev(dev) {
  182. if (dev->vendor == PCI_VENDOR_ID_NEC &&
  183.     dev->device == PCI_DEVICE_ID_NEC_NILE4) {
  184. /*
  185.  * The first 64-bit PCI base register should point to
  186.  * the Nile4 control registers. Unfortunately this
  187.  * isn't the case, so we fix it ourselves. This allows
  188.  * the serial driver to find the UART.
  189.  */
  190. dev->resource[0] = ddb5074_resources.nile4;
  191. request_resource(&iomem_resource,
  192.  &dev->resource[0]);
  193. /*
  194.  * The second 64-bit PCI base register points to the
  195.  * first memory bank. Unfortunately the address is
  196.  * wrong, so we fix it (again).
  197.  */
  198. dev->resource[2] = ddb5074_resources.ram;
  199. request_resource(&iomem_resource,
  200.  &dev->resource[2]);
  201. } else if (dev->vendor == PCI_VENDOR_ID_AL
  202.    && dev->device == PCI_DEVICE_ID_AL_M7101) {
  203. /*
  204.  * It's nice to have the LEDs on the GPIO pins
  205.  * available for debugging
  206.  */
  207. extern struct pci_dev *pci_pmu;
  208. u8 t8;
  209. pci_pmu = dev; /* for LEDs D2 and D3 */
  210. /* Program the lines for LEDs D2 and D3 to output */
  211. nile4_pci_read_config_byte(dev, 0x7d, &t8);
  212. t8 |= 0xc0;
  213. nile4_pci_write_config_byte(dev, 0x7d, t8);
  214. /* Turn LEDs D2 and D3 off */
  215. nile4_pci_read_config_byte(dev, 0x7e, &t8);
  216. t8 |= 0xc0;
  217. nile4_pci_write_config_byte(dev, 0x7e, t8);
  218. }
  219. }
  220. }
  221. static void __init pcibios_fixup_irqs(void)
  222. {
  223. struct pci_dev *dev;
  224. int slot_num;
  225. pci_for_each_dev(dev) {
  226. slot_num = PCI_SLOT(dev->devfn);
  227. switch (slot_num) {
  228. case 0:
  229. dev->irq = nile4_to_irq(NILE4_INT_INTE);
  230. break;
  231. case 1:
  232. dev->irq = nile4_to_irq(NILE4_INT_INTA);
  233. break;
  234. case 2: /* slot 1 */
  235. dev->irq = nile4_to_irq(NILE4_INT_INTA);
  236. break;
  237. case 3: /* slot 2 */
  238. dev->irq = nile4_to_irq(NILE4_INT_INTB);
  239. break;
  240. case 4: /* slot 3 */
  241. dev->irq = nile4_to_irq(NILE4_INT_INTC);
  242. break;
  243. case 5:
  244. /*
  245.  * Fixup so the serial driver can use the UART
  246.  */
  247. dev->irq = nile4_to_irq(NILE4_INT_UART);
  248. break;
  249. case 13:
  250. dev->irq = nile4_to_irq(NILE4_INT_INTE);
  251. break;
  252. default:
  253. break;
  254. }
  255. }
  256. }
  257. void __init pcibios_init(void)
  258. {
  259. printk("PCI: Probing PCI hardwaren");
  260. ioport_resource.end = 0x1ffffff; /*  32 MB */
  261. iomem_resource.end = 0x1fffffff; /* 512 MB */
  262. /* `ram' and `nile4' are requested through the Nile4 pci_dev */
  263. request_resource(&iomem_resource, &ddb5074_resources.flash);
  264. request_resource(&iomem_resource, &ddb5074_resources.isa_io);
  265. request_resource(&iomem_resource, &ddb5074_resources.pci_io);
  266. request_resource(&iomem_resource, &ddb5074_resources.isa_mem);
  267. request_resource(&iomem_resource, &ddb5074_resources.pci_mem);
  268. request_resource(&iomem_resource, &ddb5074_resources.boot);
  269. pci_scan_bus(0, &nile4_pci_ops, NULL);
  270. ddb5074_pci_fixup();
  271. pci_assign_unassigned_resources();
  272. pcibios_fixup_irqs();
  273. }
  274. void __init pcibios_fixup_bus(struct pci_bus *bus)
  275. {
  276. bus->resource[1] = &ddb5074_resources.pci_mem;
  277. }
  278. char *pcibios_setup(char *str)
  279. {
  280. return str;
  281. }
  282. void __init pcibios_update_irq(struct pci_dev *dev, int irq)
  283. {
  284. pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
  285. }
  286. void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus,
  287.       struct pbus_set_ranges_data *ranges)
  288. {
  289. ranges->io_start -= bus->resource[0]->start;
  290. ranges->io_end -= bus->resource[0]->start;
  291. ranges->mem_start -= bus->resource[1]->start;
  292. ranges->mem_end -= bus->resource[1]->start;
  293. }
  294. int pcibios_enable_resources(struct pci_dev *dev)
  295. {
  296. u16 cmd, old_cmd;
  297. int idx;
  298. struct resource *r;
  299. /*
  300.  *  Don't touch the Nile 4
  301.  */
  302. if (dev->vendor == PCI_VENDOR_ID_NEC &&
  303.     dev->device == PCI_DEVICE_ID_NEC_NILE4) return 0;
  304. pci_read_config_word(dev, PCI_COMMAND, &cmd);
  305. old_cmd = cmd;
  306. for (idx = 0; idx < 6; idx++) {
  307. r = &dev->resource[idx];
  308. if (!r->start && r->end) {
  309. printk(KERN_ERR "PCI: Device %s not available because "
  310.        "of resource collisionsn", dev->slot_name);
  311. return -EINVAL;
  312. }
  313. if (r->flags & IORESOURCE_IO)
  314. cmd |= PCI_COMMAND_IO;
  315. if (r->flags & IORESOURCE_MEM)
  316. cmd |= PCI_COMMAND_MEMORY;
  317. }
  318. if (cmd != old_cmd) {
  319. printk("PCI: Enabling device %s (%04x -> %04x)n",
  320.        dev->slot_name, old_cmd, cmd);
  321. pci_write_config_word(dev, PCI_COMMAND, cmd);
  322. }
  323. return 0;
  324. }
  325. int pcibios_enable_device(struct pci_dev *dev)
  326. {
  327. return pcibios_enable_resources(dev);
  328. }
  329. void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
  330.      struct resource *res, int resource)
  331. {
  332. u32 new, check;
  333. int reg;
  334. new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
  335. if (resource < 6) {
  336. reg = PCI_BASE_ADDRESS_0 + 4 * resource;
  337. } else if (resource == PCI_ROM_RESOURCE) {
  338. res->flags |= PCI_ROM_ADDRESS_ENABLE;
  339. reg = dev->rom_base_reg;
  340. } else {
  341. /*
  342.  * Somebody might have asked allocation of a non-standard
  343.  * resource
  344.  */
  345. return;
  346. }
  347. pci_write_config_dword(dev, reg, new);
  348. pci_read_config_dword(dev, reg, &check);
  349. if ((new ^ check) &
  350.     ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
  351.      PCI_BASE_ADDRESS_MEM_MASK)) {
  352. printk(KERN_ERR "PCI: Error while updating region "
  353.        "%s/%d (%08x != %08x)n", dev->slot_name, resource,
  354.        new, check);
  355. }
  356. }
  357. void pcibios_align_resource(void *data, struct resource *res,
  358.     unsigned long size, unsigned long align)
  359. {
  360. struct pci_dev *dev = data;
  361. if (res->flags & IORESOURCE_IO) {
  362. unsigned long start = res->start;
  363. /* We need to avoid collisions with `mirrored' VGA ports
  364.    and other strange ISA hardware, so we always want the
  365.    addresses kilobyte aligned.  */
  366. if (size > 0x100) {
  367. printk(KERN_ERR "PCI: I/O Region %s/%d too large"
  368.        " (%ld bytes)n", dev->slot_name,
  369.        dev->resource - res, size);
  370. }
  371. start = (start + 1024 - 1) & ~(1024 - 1);
  372. res->start = start;
  373. }
  374. }
  375. unsigned __init int pcibios_assign_all_busses(void)
  376. {
  377. return 1;
  378. }
  379. struct pci_fixup pcibios_fixups[] = { };