pci_common.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*
  2. * Copyright (c) 2014 Google, Inc
  3. *
  4. * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  5. * Andreas Heppel <aheppel@sysgo.de>
  6. *
  7. * (C) Copyright 2002, 2003
  8. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  9. *
  10. * SPDX-License-Identifier: GPL-2.0+
  11. */
  12. #include <common.h>
  13. #include <errno.h>
  14. #include <pci.h>
  15. #include <asm/io.h>
  16. const char *pci_class_str(u8 class)
  17. {
  18. switch (class) {
  19. case PCI_CLASS_NOT_DEFINED:
  20. return "Build before PCI Rev2.0";
  21. break;
  22. case PCI_BASE_CLASS_STORAGE:
  23. return "Mass storage controller";
  24. break;
  25. case PCI_BASE_CLASS_NETWORK:
  26. return "Network controller";
  27. break;
  28. case PCI_BASE_CLASS_DISPLAY:
  29. return "Display controller";
  30. break;
  31. case PCI_BASE_CLASS_MULTIMEDIA:
  32. return "Multimedia device";
  33. break;
  34. case PCI_BASE_CLASS_MEMORY:
  35. return "Memory controller";
  36. break;
  37. case PCI_BASE_CLASS_BRIDGE:
  38. return "Bridge device";
  39. break;
  40. case PCI_BASE_CLASS_COMMUNICATION:
  41. return "Simple comm. controller";
  42. break;
  43. case PCI_BASE_CLASS_SYSTEM:
  44. return "Base system peripheral";
  45. break;
  46. case PCI_BASE_CLASS_INPUT:
  47. return "Input device";
  48. break;
  49. case PCI_BASE_CLASS_DOCKING:
  50. return "Docking station";
  51. break;
  52. case PCI_BASE_CLASS_PROCESSOR:
  53. return "Processor";
  54. break;
  55. case PCI_BASE_CLASS_SERIAL:
  56. return "Serial bus controller";
  57. break;
  58. case PCI_BASE_CLASS_INTELLIGENT:
  59. return "Intelligent controller";
  60. break;
  61. case PCI_BASE_CLASS_SATELLITE:
  62. return "Satellite controller";
  63. break;
  64. case PCI_BASE_CLASS_CRYPT:
  65. return "Cryptographic device";
  66. break;
  67. case PCI_BASE_CLASS_SIGNAL_PROCESSING:
  68. return "DSP";
  69. break;
  70. case PCI_CLASS_OTHERS:
  71. return "Does not fit any class";
  72. break;
  73. default:
  74. return "???";
  75. break;
  76. };
  77. }
  78. pci_dev_t pci_find_class(uint find_class, int index)
  79. {
  80. int bus;
  81. int devnum;
  82. pci_dev_t bdf;
  83. uint32_t class;
  84. for (bus = 0; bus <= pci_last_busno(); bus++) {
  85. for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) {
  86. pci_read_config_dword(PCI_BDF(bus, devnum, 0),
  87. PCI_CLASS_REVISION, &class);
  88. if (class >> 16 == 0xffff)
  89. continue;
  90. for (bdf = PCI_BDF(bus, devnum, 0);
  91. bdf <= PCI_BDF(bus, devnum,
  92. PCI_MAX_PCI_FUNCTIONS - 1);
  93. bdf += PCI_BDF(0, 0, 1)) {
  94. pci_read_config_dword(bdf, PCI_CLASS_REVISION,
  95. &class);
  96. class >>= 8;
  97. if (class != find_class)
  98. continue;
  99. /*
  100. * Decrement the index. We want to return the
  101. * correct device, so index is 0 for the first
  102. * matching device, 1 for the second, etc.
  103. */
  104. if (index) {
  105. index--;
  106. continue;
  107. }
  108. /* Return index'th controller. */
  109. return bdf;
  110. }
  111. }
  112. }
  113. return -ENODEV;
  114. }
  115. __weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
  116. {
  117. /*
  118. * Check if pci device should be skipped in configuration
  119. */
  120. if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
  121. #if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
  122. /*
  123. * Only skip configuration if "pciconfighost" is not set
  124. */
  125. if (getenv("pciconfighost") == NULL)
  126. return 1;
  127. #else
  128. return 1;
  129. #endif
  130. }
  131. return 0;
  132. }
  133. /* Get a virtual address associated with a BAR region */
  134. void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
  135. {
  136. pci_addr_t pci_bus_addr;
  137. u32 bar_response;
  138. /* read BAR address */
  139. pci_read_config_dword(pdev, bar, &bar_response);
  140. pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
  141. /*
  142. * Pass "0" as the length argument to pci_bus_to_virt. The arg
  143. * isn't actualy used on any platform because u-boot assumes a static
  144. * linear mapping. In the future, this could read the BAR size
  145. * and pass that as the size if needed.
  146. */
  147. return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
  148. }
  149. void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
  150. u32 addr_and_ctrl)
  151. {
  152. int bar;
  153. bar = PCI_BASE_ADDRESS_0 + barnum * 4;
  154. pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl);
  155. }
  156. u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
  157. {
  158. u32 addr;
  159. int bar;
  160. bar = PCI_BASE_ADDRESS_0 + barnum * 4;
  161. pci_hose_read_config_dword(hose, dev, bar, &addr);
  162. if (addr & PCI_BASE_ADDRESS_SPACE_IO)
  163. return addr & PCI_BASE_ADDRESS_IO_MASK;
  164. else
  165. return addr & PCI_BASE_ADDRESS_MEM_MASK;
  166. }
  167. int __pci_hose_bus_to_phys(struct pci_controller *hose,
  168. pci_addr_t bus_addr,
  169. unsigned long flags,
  170. unsigned long skip_mask,
  171. phys_addr_t *pa)
  172. {
  173. struct pci_region *res;
  174. int i;
  175. for (i = 0; i < hose->region_count; i++) {
  176. res = &hose->regions[i];
  177. if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
  178. continue;
  179. if (res->flags & skip_mask)
  180. continue;
  181. if (bus_addr >= res->bus_start &&
  182. (bus_addr - res->bus_start) < res->size) {
  183. *pa = (bus_addr - res->bus_start + res->phys_start);
  184. return 0;
  185. }
  186. }
  187. return 1;
  188. }
  189. phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose,
  190. pci_addr_t bus_addr,
  191. unsigned long flags)
  192. {
  193. phys_addr_t phys_addr = 0;
  194. int ret;
  195. if (!hose) {
  196. puts("pci_hose_bus_to_phys: invalid hose\n");
  197. return phys_addr;
  198. }
  199. /*
  200. * if PCI_REGION_MEM is set we do a two pass search with preference
  201. * on matches that don't have PCI_REGION_SYS_MEMORY set
  202. */
  203. if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
  204. ret = __pci_hose_bus_to_phys(hose, bus_addr,
  205. flags, PCI_REGION_SYS_MEMORY, &phys_addr);
  206. if (!ret)
  207. return phys_addr;
  208. }
  209. ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
  210. if (ret)
  211. puts("pci_hose_bus_to_phys: invalid physical address\n");
  212. return phys_addr;
  213. }
  214. pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
  215. {
  216. struct pci_device_id ids[2] = { {}, {0, 0} };
  217. ids[0].vendor = vendor;
  218. ids[0].device = device;
  219. return pci_find_devices(ids, index);
  220. }
  221. pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
  222. struct pci_device_id *ids, int *indexp)
  223. {
  224. int found_multi = 0;
  225. u16 vendor, device;
  226. u8 header_type;
  227. pci_dev_t bdf;
  228. int i;
  229. for (bdf = PCI_BDF(busnum, 0, 0);
  230. bdf < PCI_BDF(busnum + 1, 0, 0);
  231. bdf += PCI_BDF(0, 0, 1)) {
  232. if (pci_skip_dev(hose, bdf))
  233. continue;
  234. if (!PCI_FUNC(bdf)) {
  235. pci_read_config_byte(bdf, PCI_HEADER_TYPE,
  236. &header_type);
  237. found_multi = header_type & 0x80;
  238. } else {
  239. if (!found_multi)
  240. continue;
  241. }
  242. pci_read_config_word(bdf, PCI_VENDOR_ID, &vendor);
  243. pci_read_config_word(bdf, PCI_DEVICE_ID, &device);
  244. for (i = 0; ids[i].vendor != 0; i++) {
  245. if (vendor == ids[i].vendor &&
  246. device == ids[i].device) {
  247. if ((*indexp) <= 0)
  248. return bdf;
  249. (*indexp)--;
  250. }
  251. }
  252. }
  253. return -1;
  254. }