2 * Copyright (c) 2014 Google, Inc
4 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
5 * Andreas Heppel <aheppel@sysgo.de>
7 * (C) Copyright 2002, 2003
8 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
10 * SPDX-License-Identifier: GPL-2.0+
19 const char *pci_class_str(u8 class)
22 case PCI_CLASS_NOT_DEFINED:
23 return "Build before PCI Rev2.0";
25 case PCI_BASE_CLASS_STORAGE:
26 return "Mass storage controller";
28 case PCI_BASE_CLASS_NETWORK:
29 return "Network controller";
31 case PCI_BASE_CLASS_DISPLAY:
32 return "Display controller";
34 case PCI_BASE_CLASS_MULTIMEDIA:
35 return "Multimedia device";
37 case PCI_BASE_CLASS_MEMORY:
38 return "Memory controller";
40 case PCI_BASE_CLASS_BRIDGE:
41 return "Bridge device";
43 case PCI_BASE_CLASS_COMMUNICATION:
44 return "Simple comm. controller";
46 case PCI_BASE_CLASS_SYSTEM:
47 return "Base system peripheral";
49 case PCI_BASE_CLASS_INPUT:
50 return "Input device";
52 case PCI_BASE_CLASS_DOCKING:
53 return "Docking station";
55 case PCI_BASE_CLASS_PROCESSOR:
58 case PCI_BASE_CLASS_SERIAL:
59 return "Serial bus controller";
61 case PCI_BASE_CLASS_INTELLIGENT:
62 return "Intelligent controller";
64 case PCI_BASE_CLASS_SATELLITE:
65 return "Satellite controller";
67 case PCI_BASE_CLASS_CRYPT:
68 return "Cryptographic device";
70 case PCI_BASE_CLASS_SIGNAL_PROCESSING:
73 case PCI_CLASS_OTHERS:
74 return "Does not fit any class";
82 __weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
85 * Check if pci device should be skipped in configuration
87 if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
88 #if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
90 * Only skip configuration if "pciconfighost" is not set
92 if (getenv("pciconfighost") == NULL)
102 /* Get a virtual address associated with a BAR region */
103 void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
105 pci_addr_t pci_bus_addr;
108 /* read BAR address */
109 pci_read_config_dword(pdev, bar, &bar_response);
110 pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
113 * Pass "0" as the length argument to pci_bus_to_virt. The arg
114 * isn't actualy used on any platform because u-boot assumes a static
115 * linear mapping. In the future, this could read the BAR size
116 * and pass that as the size if needed.
118 return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
121 void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
126 bar = PCI_BASE_ADDRESS_0 + barnum * 4;
127 pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl);
130 u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
135 bar = PCI_BASE_ADDRESS_0 + barnum * 4;
136 pci_hose_read_config_dword(hose, dev, bar, &addr);
137 if (addr & PCI_BASE_ADDRESS_SPACE_IO)
138 return addr & PCI_BASE_ADDRESS_IO_MASK;
140 return addr & PCI_BASE_ADDRESS_MEM_MASK;
143 int __pci_hose_bus_to_phys(struct pci_controller *hose,
146 unsigned long skip_mask,
149 struct pci_region *res;
152 for (i = 0; i < hose->region_count; i++) {
153 res = &hose->regions[i];
155 if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
158 if (res->flags & skip_mask)
161 if (bus_addr >= res->bus_start &&
162 (bus_addr - res->bus_start) < res->size) {
163 *pa = (bus_addr - res->bus_start + res->phys_start);
171 phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose,
175 phys_addr_t phys_addr = 0;
179 puts("pci_hose_bus_to_phys: invalid hose\n");
184 /* The root controller has the region information */
185 hose = pci_bus_to_hose(0);
189 * if PCI_REGION_MEM is set we do a two pass search with preference
190 * on matches that don't have PCI_REGION_SYS_MEMORY set
192 if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) {
193 ret = __pci_hose_bus_to_phys(hose, bus_addr,
194 flags, PCI_REGION_SYS_MEMORY, &phys_addr);
199 ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
202 puts("pci_hose_bus_to_phys: invalid physical address\n");
207 int __pci_hose_phys_to_bus(struct pci_controller *hose,
208 phys_addr_t phys_addr,
210 unsigned long skip_mask,
213 struct pci_region *res;
217 for (i = 0; i < hose->region_count; i++) {
218 res = &hose->regions[i];
220 if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
223 if (res->flags & skip_mask)
226 bus_addr = phys_addr - res->phys_start + res->bus_start;
228 if (bus_addr >= res->bus_start &&
229 (bus_addr - res->bus_start) < res->size) {
238 pci_addr_t pci_hose_phys_to_bus(struct pci_controller *hose,
239 phys_addr_t phys_addr,
242 pci_addr_t bus_addr = 0;
246 puts("pci_hose_phys_to_bus: invalid hose\n");
251 /* The root controller has the region information */
252 hose = pci_bus_to_hose(0);
256 * if PCI_REGION_MEM is set we do a two pass search with preference
257 * on matches that don't have PCI_REGION_SYS_MEMORY set
259 if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) {
260 ret = __pci_hose_phys_to_bus(hose, phys_addr,
261 flags, PCI_REGION_SYS_MEMORY, &bus_addr);
266 ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr);
269 puts("pci_hose_phys_to_bus: invalid physical address\n");
274 #if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT)
275 pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
277 struct pci_device_id ids[2] = { {}, {0, 0} };
279 ids[0].vendor = vendor;
280 ids[0].device = device;
282 return pci_find_devices(ids, index);
285 pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
286 struct pci_device_id *ids, int *indexp)
294 for (bdf = PCI_BDF(busnum, 0, 0);
295 bdf < PCI_BDF(busnum + 1, 0, 0);
296 bdf += PCI_BDF(0, 0, 1)) {
297 if (pci_skip_dev(hose, bdf))
300 if (!PCI_FUNC(bdf)) {
301 pci_read_config_byte(bdf, PCI_HEADER_TYPE,
303 found_multi = header_type & 0x80;
309 pci_read_config_word(bdf, PCI_VENDOR_ID, &vendor);
310 pci_read_config_word(bdf, PCI_DEVICE_ID, &device);
312 for (i = 0; ids[i].vendor != 0; i++) {
313 if (vendor == ids[i].vendor &&
314 device == ids[i].device) {
326 pci_dev_t pci_find_class(uint find_class, int index)
333 for (bus = 0; bus <= pci_last_busno(); bus++) {
334 for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) {
335 pci_read_config_dword(PCI_BDF(bus, devnum, 0),
336 PCI_CLASS_REVISION, &class);
337 if (class >> 16 == 0xffff)
340 for (bdf = PCI_BDF(bus, devnum, 0);
341 bdf <= PCI_BDF(bus, devnum,
342 PCI_MAX_PCI_FUNCTIONS - 1);
343 bdf += PCI_BDF(0, 0, 1)) {
344 pci_read_config_dword(bdf, PCI_CLASS_REVISION,
348 if (class != find_class)
351 * Decrement the index. We want to return the
352 * correct device, so index is 0 for the first
353 * matching device, 1 for the second, etc.
359 /* Return index'th controller. */
367 #endif /* !CONFIG_DM_PCI || CONFIG_DM_PCI_COMPAT */