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 pci_dev_t
pci_find_class(uint find_class
, int index
)
89 for (bus
= 0; bus
<= pci_last_busno(); bus
++) {
90 for (devnum
= 0; devnum
< PCI_MAX_PCI_DEVICES
- 1; devnum
++) {
91 pci_read_config_dword(PCI_BDF(bus
, devnum
, 0),
92 PCI_CLASS_REVISION
, &class);
93 if (class >> 16 == 0xffff)
96 for (bdf
= PCI_BDF(bus
, devnum
, 0);
97 bdf
<= PCI_BDF(bus
, devnum
,
98 PCI_MAX_PCI_FUNCTIONS
- 1);
99 bdf
+= PCI_BDF(0, 0, 1)) {
100 pci_read_config_dword(bdf
, PCI_CLASS_REVISION
,
104 if (class != find_class
)
107 * Decrement the index. We want to return the
108 * correct device, so index is 0 for the first
109 * matching device, 1 for the second, etc.
115 /* Return index'th controller. */
124 __weak
int pci_skip_dev(struct pci_controller
*hose
, pci_dev_t dev
)
127 * Check if pci device should be skipped in configuration
129 if (dev
== PCI_BDF(hose
->first_busno
, 0, 0)) {
130 #if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
132 * Only skip configuration if "pciconfighost" is not set
134 if (getenv("pciconfighost") == NULL
)
144 /* Get a virtual address associated with a BAR region */
145 void *pci_map_bar(pci_dev_t pdev
, int bar
, int flags
)
147 pci_addr_t pci_bus_addr
;
150 /* read BAR address */
151 pci_read_config_dword(pdev
, bar
, &bar_response
);
152 pci_bus_addr
= (pci_addr_t
)(bar_response
& ~0xf);
155 * Pass "0" as the length argument to pci_bus_to_virt. The arg
156 * isn't actualy used on any platform because u-boot assumes a static
157 * linear mapping. In the future, this could read the BAR size
158 * and pass that as the size if needed.
160 return pci_bus_to_virt(pdev
, pci_bus_addr
, flags
, 0, MAP_NOCACHE
);
163 void pci_write_bar32(struct pci_controller
*hose
, pci_dev_t dev
, int barnum
,
168 bar
= PCI_BASE_ADDRESS_0
+ barnum
* 4;
169 pci_hose_write_config_dword(hose
, dev
, bar
, addr_and_ctrl
);
172 u32
pci_read_bar32(struct pci_controller
*hose
, pci_dev_t dev
, int barnum
)
177 bar
= PCI_BASE_ADDRESS_0
+ barnum
* 4;
178 pci_hose_read_config_dword(hose
, dev
, bar
, &addr
);
179 if (addr
& PCI_BASE_ADDRESS_SPACE_IO
)
180 return addr
& PCI_BASE_ADDRESS_IO_MASK
;
182 return addr
& PCI_BASE_ADDRESS_MEM_MASK
;
185 int __pci_hose_bus_to_phys(struct pci_controller
*hose
,
188 unsigned long skip_mask
,
191 struct pci_region
*res
;
194 for (i
= 0; i
< hose
->region_count
; i
++) {
195 res
= &hose
->regions
[i
];
197 if (((res
->flags
^ flags
) & PCI_REGION_TYPE
) != 0)
200 if (res
->flags
& skip_mask
)
203 if (bus_addr
>= res
->bus_start
&&
204 (bus_addr
- res
->bus_start
) < res
->size
) {
205 *pa
= (bus_addr
- res
->bus_start
+ res
->phys_start
);
213 phys_addr_t
pci_hose_bus_to_phys(struct pci_controller
*hose
,
217 phys_addr_t phys_addr
= 0;
221 puts("pci_hose_bus_to_phys: invalid hose\n");
226 /* The root controller has the region information */
227 hose
= pci_bus_to_hose(0);
231 * if PCI_REGION_MEM is set we do a two pass search with preference
232 * on matches that don't have PCI_REGION_SYS_MEMORY set
234 if ((flags
& PCI_REGION_TYPE
) == PCI_REGION_MEM
) {
235 ret
= __pci_hose_bus_to_phys(hose
, bus_addr
,
236 flags
, PCI_REGION_SYS_MEMORY
, &phys_addr
);
241 ret
= __pci_hose_bus_to_phys(hose
, bus_addr
, flags
, 0, &phys_addr
);
244 puts("pci_hose_bus_to_phys: invalid physical address\n");
249 int __pci_hose_phys_to_bus(struct pci_controller
*hose
,
250 phys_addr_t phys_addr
,
252 unsigned long skip_mask
,
255 struct pci_region
*res
;
259 for (i
= 0; i
< hose
->region_count
; i
++) {
260 res
= &hose
->regions
[i
];
262 if (((res
->flags
^ flags
) & PCI_REGION_TYPE
) != 0)
265 if (res
->flags
& skip_mask
)
268 bus_addr
= phys_addr
- res
->phys_start
+ res
->bus_start
;
270 if (bus_addr
>= res
->bus_start
&&
271 bus_addr
< res
->bus_start
+ res
->size
) {
280 pci_addr_t
pci_hose_phys_to_bus(struct pci_controller
*hose
,
281 phys_addr_t phys_addr
,
284 pci_addr_t bus_addr
= 0;
288 puts("pci_hose_phys_to_bus: invalid hose\n");
293 /* The root controller has the region information */
294 hose
= pci_bus_to_hose(0);
298 * if PCI_REGION_MEM is set we do a two pass search with preference
299 * on matches that don't have PCI_REGION_SYS_MEMORY set
301 if ((flags
& PCI_REGION_TYPE
) == PCI_REGION_MEM
) {
302 ret
= __pci_hose_phys_to_bus(hose
, phys_addr
,
303 flags
, PCI_REGION_SYS_MEMORY
, &bus_addr
);
308 ret
= __pci_hose_phys_to_bus(hose
, phys_addr
, flags
, 0, &bus_addr
);
311 puts("pci_hose_phys_to_bus: invalid physical address\n");
316 pci_dev_t
pci_find_device(unsigned int vendor
, unsigned int device
, int index
)
318 struct pci_device_id ids
[2] = { {}, {0, 0} };
320 ids
[0].vendor
= vendor
;
321 ids
[0].device
= device
;
323 return pci_find_devices(ids
, index
);
326 pci_dev_t
pci_hose_find_devices(struct pci_controller
*hose
, int busnum
,
327 struct pci_device_id
*ids
, int *indexp
)
335 for (bdf
= PCI_BDF(busnum
, 0, 0);
336 bdf
< PCI_BDF(busnum
+ 1, 0, 0);
337 bdf
+= PCI_BDF(0, 0, 1)) {
338 if (pci_skip_dev(hose
, bdf
))
341 if (!PCI_FUNC(bdf
)) {
342 pci_read_config_byte(bdf
, PCI_HEADER_TYPE
,
344 found_multi
= header_type
& 0x80;
350 pci_read_config_word(bdf
, PCI_VENDOR_ID
, &vendor
);
351 pci_read_config_word(bdf
, PCI_DEVICE_ID
, &device
);
353 for (i
= 0; ids
[i
].vendor
!= 0; i
++) {
354 if (vendor
== ids
[i
].vendor
&&
355 device
== ids
[i
].device
) {