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 #if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT)
103 /* Get a virtual address associated with a BAR region */
104 void *pci_map_bar(pci_dev_t pdev
, int bar
, int flags
)
106 pci_addr_t pci_bus_addr
;
109 /* read BAR address */
110 pci_read_config_dword(pdev
, bar
, &bar_response
);
111 pci_bus_addr
= (pci_addr_t
)(bar_response
& ~0xf);
114 * Pass "0" as the length argument to pci_bus_to_virt. The arg
115 * isn't actualy used on any platform because u-boot assumes a static
116 * linear mapping. In the future, this could read the BAR size
117 * and pass that as the size if needed.
119 return pci_bus_to_virt(pdev
, pci_bus_addr
, flags
, 0, MAP_NOCACHE
);
122 void pci_write_bar32(struct pci_controller
*hose
, pci_dev_t dev
, int barnum
,
127 bar
= PCI_BASE_ADDRESS_0
+ barnum
* 4;
128 pci_hose_write_config_dword(hose
, dev
, bar
, addr_and_ctrl
);
131 u32
pci_read_bar32(struct pci_controller
*hose
, pci_dev_t dev
, int barnum
)
136 bar
= PCI_BASE_ADDRESS_0
+ barnum
* 4;
137 pci_hose_read_config_dword(hose
, dev
, bar
, &addr
);
138 if (addr
& PCI_BASE_ADDRESS_SPACE_IO
)
139 return addr
& PCI_BASE_ADDRESS_IO_MASK
;
141 return addr
& PCI_BASE_ADDRESS_MEM_MASK
;
144 int __pci_hose_bus_to_phys(struct pci_controller
*hose
,
147 unsigned long skip_mask
,
150 struct pci_region
*res
;
153 for (i
= 0; i
< hose
->region_count
; i
++) {
154 res
= &hose
->regions
[i
];
156 if (((res
->flags
^ flags
) & PCI_REGION_TYPE
) != 0)
159 if (res
->flags
& skip_mask
)
162 if (bus_addr
>= res
->bus_start
&&
163 (bus_addr
- res
->bus_start
) < res
->size
) {
164 *pa
= (bus_addr
- res
->bus_start
+ res
->phys_start
);
172 phys_addr_t
pci_hose_bus_to_phys(struct pci_controller
*hose
,
176 phys_addr_t phys_addr
= 0;
180 puts("pci_hose_bus_to_phys: invalid hose\n");
185 /* The root controller has the region information */
186 hose
= pci_bus_to_hose(0);
190 * if PCI_REGION_MEM is set we do a two pass search with preference
191 * on matches that don't have PCI_REGION_SYS_MEMORY set
193 if ((flags
& PCI_REGION_TYPE
) == PCI_REGION_MEM
) {
194 ret
= __pci_hose_bus_to_phys(hose
, bus_addr
,
195 flags
, PCI_REGION_SYS_MEMORY
, &phys_addr
);
200 ret
= __pci_hose_bus_to_phys(hose
, bus_addr
, flags
, 0, &phys_addr
);
203 puts("pci_hose_bus_to_phys: invalid physical address\n");
208 int __pci_hose_phys_to_bus(struct pci_controller
*hose
,
209 phys_addr_t phys_addr
,
211 unsigned long skip_mask
,
214 struct pci_region
*res
;
218 for (i
= 0; i
< hose
->region_count
; i
++) {
219 res
= &hose
->regions
[i
];
221 if (((res
->flags
^ flags
) & PCI_REGION_TYPE
) != 0)
224 if (res
->flags
& skip_mask
)
227 bus_addr
= phys_addr
- res
->phys_start
+ res
->bus_start
;
229 if (bus_addr
>= res
->bus_start
&&
230 (bus_addr
- res
->bus_start
) < res
->size
) {
239 pci_addr_t
pci_hose_phys_to_bus(struct pci_controller
*hose
,
240 phys_addr_t phys_addr
,
243 pci_addr_t bus_addr
= 0;
247 puts("pci_hose_phys_to_bus: invalid hose\n");
252 /* The root controller has the region information */
253 hose
= pci_bus_to_hose(0);
257 * if PCI_REGION_MEM is set we do a two pass search with preference
258 * on matches that don't have PCI_REGION_SYS_MEMORY set
260 if ((flags
& PCI_REGION_TYPE
) == PCI_REGION_MEM
) {
261 ret
= __pci_hose_phys_to_bus(hose
, phys_addr
,
262 flags
, PCI_REGION_SYS_MEMORY
, &bus_addr
);
267 ret
= __pci_hose_phys_to_bus(hose
, phys_addr
, flags
, 0, &bus_addr
);
270 puts("pci_hose_phys_to_bus: invalid physical address\n");
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 */