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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  arch/mips/ddb5476/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-mips/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. /* work around the bug for Vrc5476 */
  20. if (slot_num == 13)
  21. return NILE4_BASE + NILE4_PCI_BASE;
  22. /* Set window 1 address 08000000 - 32 bit - 128 MB (PCI config space) */
  23. nile4_set_pdar(NILE4_PCIW1, PHYSADDR(virt_addr), 0x08000000, 32, 0,
  24.        0);
  25. // [jsun] we start scanning from addr:10, 
  26. // with 128M we can go up to addr:26 (slot 16)
  27. if (slot_num <= 16) {
  28. virt_addr += 0x00000400 << slot_num;
  29. } else {
  30. /* for high slot, we have to set higher PCI base addr */
  31. pci_addr = 0x00000400 << slot_num;
  32. }
  33. nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, pci_addr);
  34. return virt_addr;
  35. }
  36. static void nile4_post_pci_access0(void)
  37. {
  38. /*
  39.  * Set window 1 back to address 08000000 - 32 bit - 128 MB
  40.  * (PCI IO space)
  41.  */
  42. nile4_set_pdar(NILE4_PCIW1, PHYSADDR(NILE4_PCI_MEM_BASE),
  43.        0x08000000, 32, 1, 1);
  44. // nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0);
  45. nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0x08000000);
  46. }
  47. static int nile4_pci_read_config_dword(struct pci_dev *dev,
  48.        int where, u32 * val)
  49. {
  50. int slot_num, func_num;
  51. u32 base;
  52. u32 addr;
  53. /*
  54.  *  Do we need to generate type 1 configure transaction?
  55.  */
  56. if (dev->bus->number) {
  57. /* FIXME - not working yet */
  58. return PCIBIOS_FUNC_NOT_SUPPORTED;
  59. /*
  60.  * the largest type 1 configuration addr is 16M, < 256M
  61.  * config space
  62.  */
  63. slot_num = 0;
  64. addr =
  65.     (dev->bus->number << 16) | (dev->devfn <
  66. 8) | where | 1;
  67. } else {
  68. slot_num = PCI_SLOT(dev->devfn);
  69. func_num = PCI_FUNC(dev->devfn);
  70. addr = (func_num << 8) + where;
  71. }
  72. base = nile4_pre_pci_access0(slot_num);
  73. *val = *(volatile u32 *) (base + addr);
  74. nile4_post_pci_access0();
  75. return PCIBIOS_SUCCESSFUL;
  76. }
  77. static int nile4_pci_write_config_dword(struct pci_dev *dev, int where,
  78. u32 val)
  79. {
  80. int slot_num, func_num;
  81. u32 base;
  82. u32 addr;
  83. /*
  84.  *  Do we need to generate type 1 configure transaction?
  85.  */
  86. if (dev->bus->number) {
  87. /* FIXME - not working yet */
  88. return PCIBIOS_FUNC_NOT_SUPPORTED;
  89. /* the largest type 1 configuration addr is 16M, < 256M config space */
  90. slot_num = 0;
  91. addr =
  92.     (dev->bus->number << 16) | (dev->devfn <
  93. 8) | where | 1;
  94. } else {
  95. slot_num = PCI_SLOT(dev->devfn);
  96. func_num = PCI_FUNC(dev->devfn);
  97. addr = (func_num << 8) + where;
  98. }
  99. base = nile4_pre_pci_access0(slot_num);
  100. *(volatile u32 *) (base + addr) = val;
  101. nile4_post_pci_access0();
  102. return PCIBIOS_SUCCESSFUL;
  103. }
  104. static int nile4_pci_read_config_word(struct pci_dev *dev, int where,
  105.       u16 * val)
  106. {
  107. int status;
  108. u32 result;
  109. status = nile4_pci_read_config_dword(dev, where & ~3, &result);
  110. if (status != PCIBIOS_SUCCESSFUL)
  111. return status;
  112. if (where & 2)
  113. result >>= 16;
  114. *val = result & 0xffff;
  115. return PCIBIOS_SUCCESSFUL;
  116. }
  117. static int nile4_pci_read_config_byte(struct pci_dev *dev, int where,
  118.       u8 * val)
  119. {
  120. int status;
  121. u32 result;
  122. status = nile4_pci_read_config_dword(dev, where & ~3, &result);
  123. if (status != PCIBIOS_SUCCESSFUL)
  124. return status;
  125. if (where & 1)
  126. result >>= 8;
  127. if (where & 2)
  128. result >>= 16;
  129. *val = result & 0xff;
  130. return PCIBIOS_SUCCESSFUL;
  131. }
  132. static int nile4_pci_write_config_word(struct pci_dev *dev, int where,
  133.        u16 val)
  134. {
  135. int status, shift = 0;
  136. u32 result;
  137. status = nile4_pci_read_config_dword(dev, where & ~3, &result);
  138. if (status != PCIBIOS_SUCCESSFUL)
  139. return status;
  140. if (where & 2)
  141. shift += 16;
  142. result &= ~(0xffff << shift);
  143. result |= val << shift;
  144. return nile4_pci_write_config_dword(dev, where & ~3, result);
  145. }
  146. static int nile4_pci_write_config_byte(struct pci_dev *dev, int where,
  147.        u8 val)
  148. {
  149. int status, shift = 0;
  150. u32 result;
  151. status = nile4_pci_read_config_dword(dev, where & ~3, &result);
  152. if (status != PCIBIOS_SUCCESSFUL)
  153. return status;
  154. if (where & 2)
  155. shift += 16;
  156. if (where & 1)
  157. shift += 8;
  158. result &= ~(0xff << shift);
  159. result |= val << shift;
  160. return nile4_pci_write_config_dword(dev, where & ~3, result);
  161. }
  162. struct pci_ops nile4_pci_ops = {
  163. nile4_pci_read_config_byte,
  164. nile4_pci_read_config_word,
  165. nile4_pci_read_config_dword,
  166. nile4_pci_write_config_byte,
  167. nile4_pci_write_config_word,
  168. nile4_pci_write_config_dword
  169. };
  170. struct {
  171. struct resource ram;
  172. struct resource flash;
  173. struct resource isa_io;
  174. struct resource pci_io;
  175. struct resource isa_mem;
  176. struct resource pci_mem;
  177. struct resource nile4;
  178. struct resource boot;
  179. } ddb5476_resources = {
  180. // { "RAM", 0x00000000, 0x03ffffff, IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64 },
  181. {
  182. "RAM", 0x00000000, 0x03ffffff, IORESOURCE_MEM}, {
  183. "Flash ROM", 0x04000000, 0x043fffff}, {
  184. "Nile4 ISA I/O", 0x06000000, 0x060fffff}, {
  185. "Nile4 PCI I/O", 0x06100000, 0x07ffffff}, {
  186. "Nile4 ISA mem", 0x08000000, 0x08ffffff, IORESOURCE_MEM}, {
  187. "Nile4 PCI mem", 0x09000000, 0x0fffffff, IORESOURCE_MEM},
  188.     // { "Nile4 ctrl", 0x1fa00000, 0x1fbfffff, IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64 },
  189. {
  190. "Nile4 ctrl", 0x1fa00000, 0x1fbfffff, IORESOURCE_MEM}, {
  191. "Boot ROM", 0x1fc00000, 0x1fffffff}
  192. };
  193. struct resource M5229_resources[5] = {
  194. {"M5229 BAR0", 0x1f0, 0x1f3, IORESOURCE_IO},
  195. {"M5229 BAR1", 0x3f4, 0x3f7, IORESOURCE_IO},
  196. {"M5229 BAR2", 0x170, 0x173, IORESOURCE_IO},
  197. {"M5229 BAR3", 0x374, 0x377, IORESOURCE_IO},
  198. {"M5229 BAR4", 0xf000, 0xf00f, IORESOURCE_IO}
  199. };
  200. static void __init ddb5476_pci_fixup(void)
  201. {
  202. struct pci_dev *dev;
  203. pci_for_each_dev(dev) {
  204. if (dev->vendor == PCI_VENDOR_ID_NEC &&
  205.     dev->device == PCI_DEVICE_ID_NEC_VRC5476) {
  206. /*
  207.  * The first 64-bit PCI base register should point to
  208.  * the Nile4 control registers. Unfortunately this
  209.  * isn't the case, so we fix it ourselves. This allows
  210.  * the serial driver to find the UART.
  211.  */
  212. dev->resource[0] = ddb5476_resources.nile4;
  213. request_resource(&iomem_resource,
  214.  &dev->resource[0]);
  215. /*
  216.  * The second 64-bit PCI base register points to the
  217.  * first memory bank. Unfortunately the address is
  218.  * wrong, so we fix it (again).
  219.  */
  220. /* [jsun] We cannot request the resource anymore,
  221.  * because kernel/setup.c has already reserved "System 
  222.  * RAM" resource at the same spot.  
  223.  * The fundamental problem here is that PCI host 
  224.  * controller should not put system RAM mapping in BAR
  225.  * and make subject to PCI resource assignement.
  226.  * Current fix is a total hack.  We set parent to 1 so
  227.                          * so that PCI resource assignement code is fooled to 
  228.                          * think the resource is assigned, and will not attempt
  229.                          * to mess with it.
  230.  */
  231. dev->resource[2] = ddb5476_resources.ram;
  232. if (request_resource(&iomem_resource,
  233.                      &dev->resource[2]) ) {
  234. dev->resource[2].parent = 0x1;
  235.                         }
  236. } else if (dev->vendor == PCI_VENDOR_ID_AL
  237.    && dev->device == PCI_DEVICE_ID_AL_M7101) {
  238. /*
  239.  * It's nice to have the LEDs on the GPIO pins
  240.  * available for debugging
  241.  */
  242. extern struct pci_dev *pci_pmu;
  243. u8 t8;
  244. pci_pmu = dev; /* for LEDs D2 and D3 */
  245. /* Program the lines for LEDs D2 and D3 to output */
  246. nile4_pci_read_config_byte(dev, 0x7d, &t8);
  247. t8 |= 0xc0;
  248. nile4_pci_write_config_byte(dev, 0x7d, t8);
  249. /* Turn LEDs D2 and D3 off */
  250. nile4_pci_read_config_byte(dev, 0x7e, &t8);
  251. t8 |= 0xc0;
  252. nile4_pci_write_config_byte(dev, 0x7e, t8);
  253. } else if (dev->vendor == PCI_VENDOR_ID_AL &&
  254.    dev->device == 0x5229) {
  255. int i;
  256. for (i = 0; i < 5; i++) {
  257. dev->resource[i] = M5229_resources[i];
  258. request_resource(&ioport_resource,
  259.  &dev->resource[i]);
  260. }
  261. }
  262. }
  263. }
  264. static void __init pcibios_fixup_irqs(void)
  265. {
  266. struct pci_dev *dev;
  267. int slot_num;
  268. pci_for_each_dev(dev) {
  269. slot_num = PCI_SLOT(dev->devfn);
  270. switch (slot_num) {
  271. case 3: /* re-programmed to USB */
  272. dev->irq = 9; /* hard-coded; see irq.c */
  273. break;
  274. case 4: /* re-programmed to PMU */
  275. dev->irq = 10; /* hard-coded; see irq.c */
  276. break;
  277. case 6: /* on-board pci-pci bridge */
  278. dev->irq = 0xff;
  279. break;
  280. case 7: /* on-board ether */
  281. dev->irq = nile4_to_irq(NILE4_INT_INTB);
  282. break;
  283. case 8: /* ISA-PCI bridge  */
  284. dev->irq = nile4_to_irq(NILE4_INT_INTC);
  285. break;
  286. case 9: /* ext slot #3 */
  287. dev->irq = nile4_to_irq(NILE4_INT_INTD);
  288. break;
  289. case 10: /* ext slot #4 */
  290. dev->irq = nile4_to_irq(NILE4_INT_INTA);
  291. break;
  292. case 13: /* Vrc5476 */
  293. dev->irq = 0xff;
  294. break;
  295. case 14: /* HD controller, M5229 */
  296. dev->irq = 14;
  297. break;
  298. default:
  299. printk
  300.     ("JSUN : in pcibios_fixup_irqs - unkown slot %dn",
  301.      slot_num);
  302. panic
  303.     ("JSUN : in pcibios_fixup_irqs - unkown slot.n");
  304. }
  305. }
  306. }
  307. void __init pcibios_init(void)
  308. {
  309. printk("PCI: Emulate bios initialization n");
  310. /* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */
  311. *(long *) (NILE4_BASE + NILE4_BAR0) = 0x8;
  312. printk("PCI: Probing PCI hardwaren");
  313. ioport_resource.end = 0x1ffffff; /*  32 MB */
  314. iomem_resource.end = 0x1fffffff; /* 512 MB */
  315. /* `ram' and `nile4' are requested through the Nile4 pci_dev */
  316. request_resource(&iomem_resource, &ddb5476_resources.flash);
  317. request_resource(&iomem_resource, &ddb5476_resources.isa_io);
  318. request_resource(&iomem_resource, &ddb5476_resources.pci_io);
  319. request_resource(&iomem_resource, &ddb5476_resources.isa_mem);
  320. request_resource(&iomem_resource, &ddb5476_resources.pci_mem);
  321. request_resource(&iomem_resource, &ddb5476_resources.boot);
  322. pci_scan_bus(0, &nile4_pci_ops, NULL);
  323. ddb5476_pci_fixup();
  324. pci_assign_unassigned_resources();
  325. pcibios_fixup_irqs();
  326. }
  327. void __init pcibios_fixup_bus(struct pci_bus *bus)
  328. {
  329. /* [jsun] we don't know how to fix sub-buses yet */
  330. if (bus->number == 0) {
  331. bus->resource[1] = &ddb5476_resources.pci_mem;
  332. }
  333. }
  334. char *pcibios_setup(char *str)
  335. {
  336. return str;
  337. }
  338. void __init pcibios_update_irq(struct pci_dev *dev, int irq)
  339. {
  340. pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
  341. }
  342. void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus,
  343.       struct pbus_set_ranges_data *ranges)
  344. {
  345. /*
  346.  * our caller figure out range by going through the dev structures.  
  347.  * I guess this is the place to fix things up if the bus is using a 
  348.  * different view of the addressing space.
  349.  */
  350. #if 0 /*  original DDB5074 code */
  351.    if (bus->number == 0) {
  352.    ranges->io_start -= bus->resource[0]->start;
  353.    ranges->io_end -= bus->resource[0]->start;
  354.    ranges->mem_start -= bus->resource[1]->start;
  355.    ranges->mem_end -= bus->resource[1]->start;
  356.    }
  357. #endif
  358. }
  359. int pcibios_enable_resources(struct pci_dev *dev)
  360. {
  361. u16 cmd, old_cmd;
  362. int idx;
  363. struct resource *r;
  364. /*
  365.  *  Don't touch the Nile 4
  366.  */
  367. if (dev->vendor == PCI_VENDOR_ID_NEC &&
  368.     dev->device == PCI_DEVICE_ID_NEC_VRC5476) return 0;
  369. pci_read_config_word(dev, PCI_COMMAND, &cmd);
  370. old_cmd = cmd;
  371. for (idx = 0; idx < 6; idx++) {
  372. r = &dev->resource[idx];
  373. if (!r->start && r->end) {
  374. printk(KERN_ERR "PCI: Device %s not available because "
  375.        "of resource collisionsn", dev->slot_name);
  376. return -EINVAL;
  377. }
  378. if (r->flags & IORESOURCE_IO)
  379. cmd |= PCI_COMMAND_IO;
  380. if (r->flags & IORESOURCE_MEM)
  381. cmd |= PCI_COMMAND_MEMORY;
  382. }
  383. if (cmd != old_cmd) {
  384. printk("PCI: Enabling device %s (%04x -> %04x)n",
  385.        dev->slot_name, old_cmd, cmd);
  386. pci_write_config_word(dev, PCI_COMMAND, cmd);
  387. }
  388. return 0;
  389. }
  390. int pcibios_enable_device(struct pci_dev *dev)
  391. {
  392. return pcibios_enable_resources(dev);
  393. }
  394. void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
  395.      struct resource *res, int resource)
  396. {
  397. u32 new, check;
  398. int reg;
  399. new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
  400. if (resource < 6) {
  401. reg = PCI_BASE_ADDRESS_0 + 4 * resource;
  402. } else if (resource == PCI_ROM_RESOURCE) {
  403. res->flags |= PCI_ROM_ADDRESS_ENABLE;
  404. reg = dev->rom_base_reg;
  405. } else {
  406. /*
  407.  * Somebody might have asked allocation of a non-standard
  408.  * resource
  409.  */
  410. return;
  411. }
  412. pci_write_config_dword(dev, reg, new);
  413. pci_read_config_dword(dev, reg, &check);
  414. if ((new ^ check) &
  415.     ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
  416.      PCI_BASE_ADDRESS_MEM_MASK)) {
  417. printk(KERN_ERR "PCI: Error while updating region "
  418.        "%s/%d (%08x != %08x)n", dev->slot_name, resource,
  419.        new, check);
  420. }
  421. }
  422. void pcibios_align_resource(void *data, struct resource *res,
  423.     unsigned long size)
  424. {
  425. struct pci_dev *dev = data;
  426. if (res->flags & IORESOURCE_IO) {
  427. unsigned long start = res->start;
  428. /* We need to avoid collisions with `mirrored' VGA ports
  429.    and other strange ISA hardware, so we always want the
  430.    addresses kilobyte aligned.  */
  431. if (size > 0x100) {
  432. printk(KERN_ERR "PCI: I/O Region %s/%d too large"
  433.        " (%ld bytes)n", dev->slot_name,
  434.        dev->resource - res, size);
  435. }
  436. start = (start + 1024 - 1) & ~(1024 - 1);
  437. res->start = start;
  438. }
  439. }
  440. unsigned __init int pcibios_assign_all_busses(void)
  441. {
  442. return 1;
  443. }
  444. struct pci_fixup pcibios_fixups[] = { {0} };