Commit aab6724c90c39e1f599d4ee6354c9f2cf553dc61

Authored by Simon Glass
1 parent fa67f90fc3

dm: pci: Move common PCI functions into their own file

Driver model will share many functions with the existing PCI implementation.
Move these into their own file to avoid duplication and confusion.

Signed-off-by: Simon Glass <sjg@chromium.org>

Showing 4 changed files with 313 additions and 276 deletions Side-by-side Diff

drivers/pci/Makefile
... ... @@ -6,7 +6,7 @@
6 6 #
7 7  
8 8 obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o
9   -obj-$(CONFIG_PCI) += pci.o pci_auto.o pci_rom.o
  9 +obj-$(CONFIG_PCI) += pci.o pci_common.o pci_auto.o pci_rom.o
10 10 obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o
11 11 obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o
12 12 obj-$(CONFIG_PCI_MSC01) += pci_msc01.o
... ... @@ -101,25 +101,6 @@
101 101 PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
102 102 PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
103 103  
104   -/* Get a virtual address associated with a BAR region */
105   -void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
106   -{
107   - pci_addr_t pci_bus_addr;
108   - u32 bar_response;
109   -
110   - /* read BAR address */
111   - pci_read_config_dword(pdev, bar, &bar_response);
112   - pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
113   -
114   - /*
115   - * Pass "0" as the length argument to pci_bus_to_virt. The arg
116   - * isn't actualy used on any platform because u-boot assumes a static
117   - * linear mapping. In the future, this could read the BAR size
118   - * and pass that as the size if needed.
119   - */
120   - return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
121   -}
122   -
123 104 /*
124 105 *
125 106 */
126 107  
127 108  
128 109  
129 110  
130 111  
131 112  
132 113  
... ... @@ -187,108 +168,24 @@
187 168 pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
188 169 {
189 170 struct pci_controller * hose;
190   - u16 vendor, device;
191   - u8 header_type;
192 171 pci_dev_t bdf;
193   - int i, bus, found_multi = 0;
  172 + int bus;
194 173  
195 174 for (hose = pci_get_hose_head(); hose; hose = hose->next) {
196 175 #ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
197   - for (bus = hose->last_busno; bus >= hose->first_busno; bus--)
  176 + for (bus = hose->last_busno; bus >= hose->first_busno; bus--) {
198 177 #else
199   - for (bus = hose->first_busno; bus <= hose->last_busno; bus++)
  178 + for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
200 179 #endif
201   - for (bdf = PCI_BDF(bus, 0, 0);
202   - bdf < PCI_BDF(bus + 1, 0, 0);
203   - bdf += PCI_BDF(0, 0, 1)) {
204   - if (pci_skip_dev(hose, bdf))
205   - continue;
206   -
207   - if (!PCI_FUNC(bdf)) {
208   - pci_read_config_byte(bdf,
209   - PCI_HEADER_TYPE,
210   - &header_type);
211   -
212   - found_multi = header_type & 0x80;
213   - } else {
214   - if (!found_multi)
215   - continue;
216   - }
217   -
218   - pci_read_config_word(bdf,
219   - PCI_VENDOR_ID,
220   - &vendor);
221   - pci_read_config_word(bdf,
222   - PCI_DEVICE_ID,
223   - &device);
224   -
225   - for (i = 0; ids[i].vendor != 0; i++) {
226   - if (vendor == ids[i].vendor &&
227   - device == ids[i].device) {
228   - if (index <= 0)
229   - return bdf;
230   -
231   - index--;
232   - }
233   - }
234   - }
235   - }
236   -
237   - return -1;
238   -}
239   -
240   -pci_dev_t pci_find_class(uint find_class, int index)
241   -{
242   - int bus;
243   - int devnum;
244   - pci_dev_t bdf;
245   - uint32_t class;
246   -
247   - for (bus = 0; bus <= pci_last_busno(); bus++) {
248   - for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) {
249   - pci_read_config_dword(PCI_BDF(bus, devnum, 0),
250   - PCI_CLASS_REVISION, &class);
251   - if (class >> 16 == 0xffff)
252   - continue;
253   -
254   - for (bdf = PCI_BDF(bus, devnum, 0);
255   - bdf <= PCI_BDF(bus, devnum,
256   - PCI_MAX_PCI_FUNCTIONS - 1);
257   - bdf += PCI_BDF(0, 0, 1)) {
258   - pci_read_config_dword(bdf, PCI_CLASS_REVISION,
259   - &class);
260   - class >>= 8;
261   -
262   - if (class != find_class)
263   - continue;
264   - /*
265   - * Decrement the index. We want to return the
266   - * correct device, so index is 0 for the first
267   - * matching device, 1 for the second, etc.
268   - */
269   - if (index) {
270   - index--;
271   - continue;
272   - }
273   - /* Return index'th controller. */
  180 + bdf = pci_hose_find_devices(hose, bus, ids, &index);
  181 + if (bdf != -1)
274 182 return bdf;
275   - }
276 183 }
277 184 }
278 185  
279   - return -ENODEV;
  186 + return -1;
280 187 }
281 188  
282   -pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
283   -{
284   - struct pci_device_id ids[2] = { {}, {0, 0} };
285   -
286   - ids[0].vendor = vendor;
287   - ids[0].device = device;
288   -
289   - return pci_find_devices(ids, index);
290   -}
291   -
292 189 /*
293 190 *
294 191 */
... ... @@ -355,87 +252,6 @@
355 252 return bus_addr;
356 253 }
357 254  
358   -int __pci_hose_bus_to_phys(struct pci_controller *hose,
359   - pci_addr_t bus_addr,
360   - unsigned long flags,
361   - unsigned long skip_mask,
362   - phys_addr_t *pa)
363   -{
364   - struct pci_region *res;
365   - int i;
366   -
367   - for (i = 0; i < hose->region_count; i++) {
368   - res = &hose->regions[i];
369   -
370   - if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
371   - continue;
372   -
373   - if (res->flags & skip_mask)
374   - continue;
375   -
376   - if (bus_addr >= res->bus_start &&
377   - (bus_addr - res->bus_start) < res->size) {
378   - *pa = (bus_addr - res->bus_start + res->phys_start);
379   - return 0;
380   - }
381   - }
382   -
383   - return 1;
384   -}
385   -
386   -phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
387   - pci_addr_t bus_addr,
388   - unsigned long flags)
389   -{
390   - phys_addr_t phys_addr = 0;
391   - int ret;
392   -
393   - if (!hose) {
394   - puts("pci_hose_bus_to_phys: invalid hose\n");
395   - return phys_addr;
396   - }
397   -
398   - /*
399   - * if PCI_REGION_MEM is set we do a two pass search with preference
400   - * on matches that don't have PCI_REGION_SYS_MEMORY set
401   - */
402   - if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
403   - ret = __pci_hose_bus_to_phys(hose, bus_addr,
404   - flags, PCI_REGION_SYS_MEMORY, &phys_addr);
405   - if (!ret)
406   - return phys_addr;
407   - }
408   -
409   - ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
410   -
411   - if (ret)
412   - puts("pci_hose_bus_to_phys: invalid physical address\n");
413   -
414   - return phys_addr;
415   -}
416   -
417   -void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
418   - u32 addr_and_ctrl)
419   -{
420   - int bar;
421   -
422   - bar = PCI_BASE_ADDRESS_0 + barnum * 4;
423   - pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl);
424   -}
425   -
426   -u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
427   -{
428   - u32 addr;
429   - int bar;
430   -
431   - bar = PCI_BASE_ADDRESS_0 + barnum * 4;
432   - pci_hose_read_config_dword(hose, dev, bar, &addr);
433   - if (addr & PCI_BASE_ADDRESS_SPACE_IO)
434   - return addr & PCI_BASE_ADDRESS_IO_MASK;
435   - else
436   - return addr & PCI_BASE_ADDRESS_MEM_MASK;
437   -}
438   -
439 255 int pci_hose_config_device(struct pci_controller *hose,
440 256 pci_dev_t dev,
441 257 unsigned long io,
... ... @@ -575,91 +391,6 @@
575 391 * to get the correct result when scanning bridges
576 392 */
577 393 extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
578   -
579   -#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI_SCAN_SHOW)
580   -const char * pci_class_str(u8 class)
581   -{
582   - switch (class) {
583   - case PCI_CLASS_NOT_DEFINED:
584   - return "Build before PCI Rev2.0";
585   - break;
586   - case PCI_BASE_CLASS_STORAGE:
587   - return "Mass storage controller";
588   - break;
589   - case PCI_BASE_CLASS_NETWORK:
590   - return "Network controller";
591   - break;
592   - case PCI_BASE_CLASS_DISPLAY:
593   - return "Display controller";
594   - break;
595   - case PCI_BASE_CLASS_MULTIMEDIA:
596   - return "Multimedia device";
597   - break;
598   - case PCI_BASE_CLASS_MEMORY:
599   - return "Memory controller";
600   - break;
601   - case PCI_BASE_CLASS_BRIDGE:
602   - return "Bridge device";
603   - break;
604   - case PCI_BASE_CLASS_COMMUNICATION:
605   - return "Simple comm. controller";
606   - break;
607   - case PCI_BASE_CLASS_SYSTEM:
608   - return "Base system peripheral";
609   - break;
610   - case PCI_BASE_CLASS_INPUT:
611   - return "Input device";
612   - break;
613   - case PCI_BASE_CLASS_DOCKING:
614   - return "Docking station";
615   - break;
616   - case PCI_BASE_CLASS_PROCESSOR:
617   - return "Processor";
618   - break;
619   - case PCI_BASE_CLASS_SERIAL:
620   - return "Serial bus controller";
621   - break;
622   - case PCI_BASE_CLASS_INTELLIGENT:
623   - return "Intelligent controller";
624   - break;
625   - case PCI_BASE_CLASS_SATELLITE:
626   - return "Satellite controller";
627   - break;
628   - case PCI_BASE_CLASS_CRYPT:
629   - return "Cryptographic device";
630   - break;
631   - case PCI_BASE_CLASS_SIGNAL_PROCESSING:
632   - return "DSP";
633   - break;
634   - case PCI_CLASS_OTHERS:
635   - return "Does not fit any class";
636   - break;
637   - default:
638   - return "???";
639   - break;
640   - };
641   -}
642   -#endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */
643   -
644   -__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
645   -{
646   - /*
647   - * Check if pci device should be skipped in configuration
648   - */
649   - if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
650   -#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
651   - /*
652   - * Only skip configuration if "pciconfighost" is not set
653   - */
654   - if (getenv("pciconfighost") == NULL)
655   - return 1;
656   -#else
657   - return 1;
658   -#endif
659   - }
660   -
661   - return 0;
662   -}
663 394  
664 395 #ifdef CONFIG_PCI_SCAN_SHOW
665 396 __weak int pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
drivers/pci/pci_common.c
  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 +
  13 +#include <common.h>
  14 +#include <errno.h>
  15 +#include <pci.h>
  16 +#include <asm/io.h>
  17 +
  18 +const char *pci_class_str(u8 class)
  19 +{
  20 + switch (class) {
  21 + case PCI_CLASS_NOT_DEFINED:
  22 + return "Build before PCI Rev2.0";
  23 + break;
  24 + case PCI_BASE_CLASS_STORAGE:
  25 + return "Mass storage controller";
  26 + break;
  27 + case PCI_BASE_CLASS_NETWORK:
  28 + return "Network controller";
  29 + break;
  30 + case PCI_BASE_CLASS_DISPLAY:
  31 + return "Display controller";
  32 + break;
  33 + case PCI_BASE_CLASS_MULTIMEDIA:
  34 + return "Multimedia device";
  35 + break;
  36 + case PCI_BASE_CLASS_MEMORY:
  37 + return "Memory controller";
  38 + break;
  39 + case PCI_BASE_CLASS_BRIDGE:
  40 + return "Bridge device";
  41 + break;
  42 + case PCI_BASE_CLASS_COMMUNICATION:
  43 + return "Simple comm. controller";
  44 + break;
  45 + case PCI_BASE_CLASS_SYSTEM:
  46 + return "Base system peripheral";
  47 + break;
  48 + case PCI_BASE_CLASS_INPUT:
  49 + return "Input device";
  50 + break;
  51 + case PCI_BASE_CLASS_DOCKING:
  52 + return "Docking station";
  53 + break;
  54 + case PCI_BASE_CLASS_PROCESSOR:
  55 + return "Processor";
  56 + break;
  57 + case PCI_BASE_CLASS_SERIAL:
  58 + return "Serial bus controller";
  59 + break;
  60 + case PCI_BASE_CLASS_INTELLIGENT:
  61 + return "Intelligent controller";
  62 + break;
  63 + case PCI_BASE_CLASS_SATELLITE:
  64 + return "Satellite controller";
  65 + break;
  66 + case PCI_BASE_CLASS_CRYPT:
  67 + return "Cryptographic device";
  68 + break;
  69 + case PCI_BASE_CLASS_SIGNAL_PROCESSING:
  70 + return "DSP";
  71 + break;
  72 + case PCI_CLASS_OTHERS:
  73 + return "Does not fit any class";
  74 + break;
  75 + default:
  76 + return "???";
  77 + break;
  78 + };
  79 +}
  80 +
  81 +pci_dev_t pci_find_class(uint find_class, int index)
  82 +{
  83 + int bus;
  84 + int devnum;
  85 + pci_dev_t bdf;
  86 + uint32_t class;
  87 +
  88 + for (bus = 0; bus <= pci_last_busno(); bus++) {
  89 + for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) {
  90 + pci_read_config_dword(PCI_BDF(bus, devnum, 0),
  91 + PCI_CLASS_REVISION, &class);
  92 + if (class >> 16 == 0xffff)
  93 + continue;
  94 +
  95 + for (bdf = PCI_BDF(bus, devnum, 0);
  96 + bdf <= PCI_BDF(bus, devnum,
  97 + PCI_MAX_PCI_FUNCTIONS - 1);
  98 + bdf += PCI_BDF(0, 0, 1)) {
  99 + pci_read_config_dword(bdf, PCI_CLASS_REVISION,
  100 + &class);
  101 + class >>= 8;
  102 +
  103 + if (class != find_class)
  104 + continue;
  105 + /*
  106 + * Decrement the index. We want to return the
  107 + * correct device, so index is 0 for the first
  108 + * matching device, 1 for the second, etc.
  109 + */
  110 + if (index) {
  111 + index--;
  112 + continue;
  113 + }
  114 + /* Return index'th controller. */
  115 + return bdf;
  116 + }
  117 + }
  118 + }
  119 +
  120 + return -ENODEV;
  121 +}
  122 +
  123 +__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
  124 +{
  125 + /*
  126 + * Check if pci device should be skipped in configuration
  127 + */
  128 + if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
  129 +#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
  130 + /*
  131 + * Only skip configuration if "pciconfighost" is not set
  132 + */
  133 + if (getenv("pciconfighost") == NULL)
  134 + return 1;
  135 +#else
  136 + return 1;
  137 +#endif
  138 + }
  139 +
  140 + return 0;
  141 +}
  142 +
  143 +/* Get a virtual address associated with a BAR region */
  144 +void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
  145 +{
  146 + pci_addr_t pci_bus_addr;
  147 + u32 bar_response;
  148 +
  149 + /* read BAR address */
  150 + pci_read_config_dword(pdev, bar, &bar_response);
  151 + pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
  152 +
  153 + /*
  154 + * Pass "0" as the length argument to pci_bus_to_virt. The arg
  155 + * isn't actualy used on any platform because u-boot assumes a static
  156 + * linear mapping. In the future, this could read the BAR size
  157 + * and pass that as the size if needed.
  158 + */
  159 + return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
  160 +}
  161 +
  162 +void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
  163 + u32 addr_and_ctrl)
  164 +{
  165 + int bar;
  166 +
  167 + bar = PCI_BASE_ADDRESS_0 + barnum * 4;
  168 + pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl);
  169 +}
  170 +
  171 +u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
  172 +{
  173 + u32 addr;
  174 + int bar;
  175 +
  176 + bar = PCI_BASE_ADDRESS_0 + barnum * 4;
  177 + pci_hose_read_config_dword(hose, dev, bar, &addr);
  178 + if (addr & PCI_BASE_ADDRESS_SPACE_IO)
  179 + return addr & PCI_BASE_ADDRESS_IO_MASK;
  180 + else
  181 + return addr & PCI_BASE_ADDRESS_MEM_MASK;
  182 +}
  183 +
  184 +int __pci_hose_bus_to_phys(struct pci_controller *hose,
  185 + pci_addr_t bus_addr,
  186 + unsigned long flags,
  187 + unsigned long skip_mask,
  188 + phys_addr_t *pa)
  189 +{
  190 + struct pci_region *res;
  191 + int i;
  192 +
  193 + for (i = 0; i < hose->region_count; i++) {
  194 + res = &hose->regions[i];
  195 +
  196 + if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
  197 + continue;
  198 +
  199 + if (res->flags & skip_mask)
  200 + continue;
  201 +
  202 + if (bus_addr >= res->bus_start &&
  203 + (bus_addr - res->bus_start) < res->size) {
  204 + *pa = (bus_addr - res->bus_start + res->phys_start);
  205 + return 0;
  206 + }
  207 + }
  208 +
  209 + return 1;
  210 +}
  211 +
  212 +phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose,
  213 + pci_addr_t bus_addr,
  214 + unsigned long flags)
  215 +{
  216 + phys_addr_t phys_addr = 0;
  217 + int ret;
  218 +
  219 + if (!hose) {
  220 + puts("pci_hose_bus_to_phys: invalid hose\n");
  221 + return phys_addr;
  222 + }
  223 +
  224 + /*
  225 + * if PCI_REGION_MEM is set we do a two pass search with preference
  226 + * on matches that don't have PCI_REGION_SYS_MEMORY set
  227 + */
  228 + if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
  229 + ret = __pci_hose_bus_to_phys(hose, bus_addr,
  230 + flags, PCI_REGION_SYS_MEMORY, &phys_addr);
  231 + if (!ret)
  232 + return phys_addr;
  233 + }
  234 +
  235 + ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
  236 +
  237 + if (ret)
  238 + puts("pci_hose_bus_to_phys: invalid physical address\n");
  239 +
  240 + return phys_addr;
  241 +}
  242 +
  243 +pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
  244 +{
  245 + struct pci_device_id ids[2] = { {}, {0, 0} };
  246 +
  247 + ids[0].vendor = vendor;
  248 + ids[0].device = device;
  249 +
  250 + return pci_find_devices(ids, index);
  251 +}
  252 +
  253 +pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
  254 + struct pci_device_id *ids, int *indexp)
  255 +{
  256 + int found_multi = 0;
  257 + u16 vendor, device;
  258 + u8 header_type;
  259 + pci_dev_t bdf;
  260 + int i;
  261 +
  262 + for (bdf = PCI_BDF(busnum, 0, 0);
  263 + bdf < PCI_BDF(busnum + 1, 0, 0);
  264 + bdf += PCI_BDF(0, 0, 1)) {
  265 + if (pci_skip_dev(hose, bdf))
  266 + continue;
  267 +
  268 + if (!PCI_FUNC(bdf)) {
  269 + pci_read_config_byte(bdf, PCI_HEADER_TYPE,
  270 + &header_type);
  271 + found_multi = header_type & 0x80;
  272 + } else {
  273 + if (!found_multi)
  274 + continue;
  275 + }
  276 +
  277 + pci_read_config_word(bdf, PCI_VENDOR_ID, &vendor);
  278 + pci_read_config_word(bdf, PCI_DEVICE_ID, &device);
  279 +
  280 + for (i = 0; ids[i].vendor != 0; i++) {
  281 + if (vendor == ids[i].vendor &&
  282 + device == ids[i].device) {
  283 + if ((*indexp) <= 0)
  284 + return bdf;
  285 +
  286 + (*indexp)--;
  287 + }
  288 + }
  289 + }
  290 +
  291 + return -1;
  292 +}
... ... @@ -705,6 +705,20 @@
705 705 */
706 706 int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev);
707 707  
  708 +/**
  709 + * pci_hose_find_devices() - Find devices by vendor/device ID
  710 + *
  711 + * @hose: PCI hose to search
  712 + * @busnum: Bus number to search
  713 + * @ids: PCI vendor/device IDs to look for, terminated by 0, 0 record
  714 + * @indexp: Pointer to device index to find. To find the first matching
  715 + * device, pass 0; to find the second, pass 1, etc. This
  716 + * parameter is decremented for each non-matching device so
  717 + * can be called repeatedly.
  718 + */
  719 +pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
  720 + struct pci_device_id *ids, int *indexp);
  721 +
708 722 #endif /* __ASSEMBLY__ */
709 723 #endif /* _PCI_H */