pci-vdk.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /* pci-vdk.c: MB93090-MB00 (VDK) PCI support
  2. *
  3. * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. */
  11. #include <linux/types.h>
  12. #include <linux/kernel.h>
  13. #include <linux/sched.h>
  14. #include <linux/pci.h>
  15. #include <linux/init.h>
  16. #include <linux/ioport.h>
  17. #include <linux/delay.h>
  18. #include <asm/segment.h>
  19. #include <asm/io.h>
  20. #include <asm/mb-regs.h>
  21. #include <asm/mb86943a.h>
  22. #include "pci-frv.h"
  23. unsigned int __nongpreldata pci_probe = 1;
  24. struct pci_ops *__nongpreldata pci_root_ops;
  25. /*
  26. * The accessible PCI window does not cover the entire CPU address space, but
  27. * there are devices we want to access outside of that window, so we need to
  28. * insert specific PCI bus resources instead of using the platform-level bus
  29. * resources directly for the PCI root bus.
  30. *
  31. * These are configured and inserted by pcibios_init() and are attached to the
  32. * root bus by pcibios_fixup_bus().
  33. */
  34. static struct resource pci_ioport_resource = {
  35. .name = "PCI IO",
  36. .start = 0,
  37. .end = IO_SPACE_LIMIT,
  38. .flags = IORESOURCE_IO,
  39. };
  40. static struct resource pci_iomem_resource = {
  41. .name = "PCI mem",
  42. .start = 0,
  43. .end = -1,
  44. .flags = IORESOURCE_MEM,
  45. };
  46. /*
  47. * Functions for accessing PCI configuration space
  48. */
  49. #define CONFIG_CMD(bus, dev, where) \
  50. (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
  51. #define __set_PciCfgAddr(A) writel((A), (volatile void __iomem *) __region_CS1 + 0x80)
  52. #define __get_PciCfgDataB(A) readb((volatile void __iomem *) __region_CS1 + 0x88 + ((A) & 3))
  53. #define __get_PciCfgDataW(A) readw((volatile void __iomem *) __region_CS1 + 0x88 + ((A) & 2))
  54. #define __get_PciCfgDataL(A) readl((volatile void __iomem *) __region_CS1 + 0x88)
  55. #define __set_PciCfgDataB(A,V) \
  56. writeb((V), (volatile void __iomem *) __region_CS1 + 0x88 + (3 - ((A) & 3)))
  57. #define __set_PciCfgDataW(A,V) \
  58. writew((V), (volatile void __iomem *) __region_CS1 + 0x88 + (2 - ((A) & 2)))
  59. #define __set_PciCfgDataL(A,V) \
  60. writel((V), (volatile void __iomem *) __region_CS1 + 0x88)
  61. #define __get_PciBridgeDataB(A) readb((volatile void __iomem *) __region_CS1 + 0x800 + (A))
  62. #define __get_PciBridgeDataW(A) readw((volatile void __iomem *) __region_CS1 + 0x800 + (A))
  63. #define __get_PciBridgeDataL(A) readl((volatile void __iomem *) __region_CS1 + 0x800 + (A))
  64. #define __set_PciBridgeDataB(A,V) writeb((V), (volatile void __iomem *) __region_CS1 + 0x800 + (A))
  65. #define __set_PciBridgeDataW(A,V) writew((V), (volatile void __iomem *) __region_CS1 + 0x800 + (A))
  66. #define __set_PciBridgeDataL(A,V) writel((V), (volatile void __iomem *) __region_CS1 + 0x800 + (A))
  67. static inline int __query(const struct pci_dev *dev)
  68. {
  69. // return dev->bus->number==0 && (dev->devfn==PCI_DEVFN(0,0));
  70. // return dev->bus->number==1;
  71. // return dev->bus->number==0 &&
  72. // (dev->devfn==PCI_DEVFN(2,0) || dev->devfn==PCI_DEVFN(3,0));
  73. return 0;
  74. }
  75. /*****************************************************************************/
  76. /*
  77. *
  78. */
  79. static int pci_frv_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
  80. u32 *val)
  81. {
  82. u32 _value;
  83. if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
  84. _value = __get_PciBridgeDataL(where & ~3);
  85. }
  86. else {
  87. __set_PciCfgAddr(CONFIG_CMD(bus, devfn, where));
  88. _value = __get_PciCfgDataL(where & ~3);
  89. }
  90. switch (size) {
  91. case 1:
  92. _value = _value >> ((where & 3) * 8);
  93. break;
  94. case 2:
  95. _value = _value >> ((where & 2) * 8);
  96. break;
  97. case 4:
  98. break;
  99. default:
  100. BUG();
  101. }
  102. *val = _value;
  103. return PCIBIOS_SUCCESSFUL;
  104. }
  105. static int pci_frv_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
  106. u32 value)
  107. {
  108. switch (size) {
  109. case 1:
  110. if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
  111. __set_PciBridgeDataB(where, value);
  112. }
  113. else {
  114. __set_PciCfgAddr(CONFIG_CMD(bus, devfn, where));
  115. __set_PciCfgDataB(where, value);
  116. }
  117. break;
  118. case 2:
  119. if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
  120. __set_PciBridgeDataW(where, value);
  121. }
  122. else {
  123. __set_PciCfgAddr(CONFIG_CMD(bus, devfn, where));
  124. __set_PciCfgDataW(where, value);
  125. }
  126. break;
  127. case 4:
  128. if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
  129. __set_PciBridgeDataL(where, value);
  130. }
  131. else {
  132. __set_PciCfgAddr(CONFIG_CMD(bus, devfn, where));
  133. __set_PciCfgDataL(where, value);
  134. }
  135. break;
  136. default:
  137. BUG();
  138. }
  139. return PCIBIOS_SUCCESSFUL;
  140. }
  141. static struct pci_ops pci_direct_frv = {
  142. .read = pci_frv_read_config,
  143. .write = pci_frv_write_config,
  144. };
  145. /*
  146. * Before we decide to use direct hardware access mechanisms, we try to do some
  147. * trivial checks to ensure it at least _seems_ to be working -- we just test
  148. * whether bus 00 contains a host bridge (this is similar to checking
  149. * techniques used in XFree86, but ours should be more reliable since we
  150. * attempt to make use of direct access hints provided by the PCI BIOS).
  151. *
  152. * This should be close to trivial, but it isn't, because there are buggy
  153. * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
  154. */
  155. static int __init pci_sanity_check(struct pci_ops *o)
  156. {
  157. struct pci_bus bus; /* Fake bus and device */
  158. u32 id;
  159. bus.number = 0;
  160. if (o->read(&bus, 0, PCI_VENDOR_ID, 4, &id) == PCIBIOS_SUCCESSFUL) {
  161. printk("PCI: VDK Bridge device:vendor: %08x\n", id);
  162. if (id == 0x200e10cf)
  163. return 1;
  164. }
  165. printk("PCI: VDK Bridge: Sanity check failed\n");
  166. return 0;
  167. }
  168. static struct pci_ops * __init pci_check_direct(void)
  169. {
  170. unsigned long flags;
  171. local_irq_save(flags);
  172. /* check if access works */
  173. if (pci_sanity_check(&pci_direct_frv)) {
  174. local_irq_restore(flags);
  175. printk("PCI: Using configuration frv\n");
  176. // request_mem_region(0xBE040000, 256, "FRV bridge");
  177. // request_mem_region(0xBFFFFFF4, 12, "PCI frv");
  178. return &pci_direct_frv;
  179. }
  180. local_irq_restore(flags);
  181. return NULL;
  182. }
  183. /*
  184. * Exceptions for specific devices. Usually work-arounds for fatal design flaws.
  185. */
  186. static void __init pci_fixup_umc_ide(struct pci_dev *d)
  187. {
  188. /*
  189. * UM8886BF IDE controller sets region type bits incorrectly,
  190. * therefore they look like memory despite of them being I/O.
  191. */
  192. int i;
  193. printk("PCI: Fixing base address flags for device %s\n", pci_name(d));
  194. for(i=0; i<4; i++)
  195. d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
  196. }
  197. static void pci_fixup_ide_bases(struct pci_dev *d)
  198. {
  199. int i;
  200. /*
  201. * PCI IDE controllers use non-standard I/O port decoding, respect it.
  202. */
  203. if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
  204. return;
  205. printk("PCI: IDE base address fixup for %s\n", pci_name(d));
  206. for(i=0; i<4; i++) {
  207. struct resource *r = &d->resource[i];
  208. if ((r->start & ~0x80) == 0x374) {
  209. r->start |= 2;
  210. r->end = r->start;
  211. }
  212. }
  213. }
  214. static void pci_fixup_ide_trash(struct pci_dev *d)
  215. {
  216. int i;
  217. /*
  218. * There exist PCI IDE controllers which have utter garbage
  219. * in first four base registers. Ignore that.
  220. */
  221. printk("PCI: IDE base address trash cleared for %s\n", pci_name(d));
  222. for(i=0; i<4; i++)
  223. d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0;
  224. }
  225. static void pci_fixup_latency(struct pci_dev *d)
  226. {
  227. /*
  228. * SiS 5597 and 5598 chipsets require latency timer set to
  229. * at most 32 to avoid lockups.
  230. */
  231. DBG("PCI: Setting max latency to 32\n");
  232. pcibios_max_latency = 32;
  233. }
  234. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, pci_fixup_umc_ide);
  235. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, pci_fixup_ide_trash);
  236. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, pci_fixup_latency);
  237. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5598, pci_fixup_latency);
  238. DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
  239. /*
  240. * Called after each bus is probed, but before its children
  241. * are examined.
  242. */
  243. void pcibios_fixup_bus(struct pci_bus *bus)
  244. {
  245. #if 0
  246. printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
  247. #endif
  248. pci_read_bridge_bases(bus);
  249. if (bus->number == 0) {
  250. struct pci_dev *dev;
  251. list_for_each_entry(dev, &bus->devices, bus_list) {
  252. if (dev->devfn == 0) {
  253. dev->resource[0].start = 0;
  254. dev->resource[0].end = 0;
  255. }
  256. }
  257. }
  258. }
  259. /*
  260. * Initialization. Try all known PCI access methods. Note that we support
  261. * using both PCI BIOS and direct access: in such cases, we use I/O ports
  262. * to access config space, but we still keep BIOS order of cards to be
  263. * compatible with 2.0.X. This should go away some day.
  264. */
  265. int __init pcibios_init(void)
  266. {
  267. struct pci_bus *bus;
  268. struct pci_ops *dir = NULL;
  269. LIST_HEAD(resources);
  270. if (!mb93090_mb00_detected)
  271. return -ENXIO;
  272. __reg_MB86943_sl_ctl |= MB86943_SL_CTL_DRCT_MASTER_SWAP | MB86943_SL_CTL_DRCT_SLAVE_SWAP;
  273. __reg_MB86943_ecs_base(1) = ((__region_CS2 + 0x01000000) >> 9) | 0x08000000;
  274. __reg_MB86943_ecs_base(2) = ((__region_CS2 + 0x00000000) >> 9) | 0x08000000;
  275. *(volatile uint32_t *) (__region_CS1 + 0x848) = 0xe0000000;
  276. *(volatile uint32_t *) (__region_CS1 + 0x8b8) = 0x00000000;
  277. __reg_MB86943_sl_pci_io_base = (__region_CS2 + 0x04000000) >> 9;
  278. __reg_MB86943_sl_pci_mem_base = (__region_CS2 + 0x08000000) >> 9;
  279. __reg_MB86943_pci_sl_io_base = __region_CS2 + 0x04000000;
  280. __reg_MB86943_pci_sl_mem_base = __region_CS2 + 0x08000000;
  281. mb();
  282. /* enable PCI arbitration */
  283. __reg_MB86943_pci_arbiter = MB86943_PCIARB_EN;
  284. pci_ioport_resource.start = (__reg_MB86943_sl_pci_io_base << 9) & 0xfffffc00;
  285. pci_ioport_resource.end = (__reg_MB86943_sl_pci_io_range << 9) | 0x3ff;
  286. pci_ioport_resource.end += pci_ioport_resource.start;
  287. printk("PCI IO window: %08llx-%08llx\n",
  288. (unsigned long long) pci_ioport_resource.start,
  289. (unsigned long long) pci_ioport_resource.end);
  290. pci_iomem_resource.start = (__reg_MB86943_sl_pci_mem_base << 9) & 0xfffffc00;
  291. pci_iomem_resource.end = (__reg_MB86943_sl_pci_mem_range << 9) | 0x3ff;
  292. pci_iomem_resource.end += pci_iomem_resource.start;
  293. /* Reserve somewhere to write to flush posted writes. This is used by
  294. * __flush_PCI_writes() from asm/io.h to force the write FIFO in the
  295. * CPU-PCI bridge to flush as this doesn't happen automatically when a
  296. * read is performed on the MB93090 development kit motherboard.
  297. */
  298. pci_iomem_resource.start += 0x400;
  299. printk("PCI MEM window: %08llx-%08llx\n",
  300. (unsigned long long) pci_iomem_resource.start,
  301. (unsigned long long) pci_iomem_resource.end);
  302. printk("PCI DMA memory: %08lx-%08lx\n",
  303. dma_coherent_mem_start, dma_coherent_mem_end);
  304. if (insert_resource(&iomem_resource, &pci_iomem_resource) < 0)
  305. panic("Unable to insert PCI IOMEM resource\n");
  306. if (insert_resource(&ioport_resource, &pci_ioport_resource) < 0)
  307. panic("Unable to insert PCI IOPORT resource\n");
  308. if (!pci_probe)
  309. return -ENXIO;
  310. dir = pci_check_direct();
  311. if (dir)
  312. pci_root_ops = dir;
  313. else {
  314. printk("PCI: No PCI bus detected\n");
  315. return -ENXIO;
  316. }
  317. printk("PCI: Probing PCI hardware\n");
  318. pci_add_resource(&resources, &pci_ioport_resource);
  319. pci_add_resource(&resources, &pci_iomem_resource);
  320. bus = pci_scan_root_bus(NULL, 0, pci_root_ops, NULL, &resources);
  321. pcibios_irq_init();
  322. pcibios_fixup_irqs();
  323. pcibios_resource_survey();
  324. if (!bus)
  325. return 0;
  326. pci_bus_add_devices(bus);
  327. return 0;
  328. }
  329. arch_initcall(pcibios_init);
  330. char * __init pcibios_setup(char *str)
  331. {
  332. if (!strcmp(str, "off")) {
  333. pci_probe = 0;
  334. return NULL;
  335. }
  336. return str;
  337. }
  338. int pcibios_enable_device(struct pci_dev *dev, int mask)
  339. {
  340. int err;
  341. if ((err = pci_enable_resources(dev, mask)) < 0)
  342. return err;
  343. if (!dev->msi_enabled)
  344. pcibios_enable_irq(dev);
  345. return 0;
  346. }