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 (env_get("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 * if PCI_REGION_MEM is set we do a two pass search with preference
186 * on matches that don't have PCI_REGION_SYS_MEMORY set
188 if ((flags
& PCI_REGION_TYPE
) == PCI_REGION_MEM
) {
189 ret
= __pci_hose_bus_to_phys(hose
, bus_addr
,
190 flags
, PCI_REGION_SYS_MEMORY
, &phys_addr
);
195 ret
= __pci_hose_bus_to_phys(hose
, bus_addr
, flags
, 0, &phys_addr
);
198 puts("pci_hose_bus_to_phys: invalid physical address\n");
203 int __pci_hose_phys_to_bus(struct pci_controller
*hose
,
204 phys_addr_t phys_addr
,
206 unsigned long skip_mask
,
209 struct pci_region
*res
;
213 for (i
= 0; i
< hose
->region_count
; i
++) {
214 res
= &hose
->regions
[i
];
216 if (((res
->flags
^ flags
) & PCI_REGION_TYPE
) != 0)
219 if (res
->flags
& skip_mask
)
222 bus_addr
= phys_addr
- res
->phys_start
+ res
->bus_start
;
224 if (bus_addr
>= res
->bus_start
&&
225 (bus_addr
- res
->bus_start
) < res
->size
) {
235 * pci_hose_phys_to_bus(): Convert physical address to bus address
236 * @hose: PCI hose of the root PCI controller
237 * @phys_addr: physical address to convert
238 * @flags: flags of pci regions
239 * @return bus address if OK, 0 on error
241 pci_addr_t
pci_hose_phys_to_bus(struct pci_controller
*hose
,
242 phys_addr_t phys_addr
,
245 pci_addr_t bus_addr
= 0;
249 puts("pci_hose_phys_to_bus: invalid hose\n");
254 * if PCI_REGION_MEM is set we do a two pass search with preference
255 * on matches that don't have PCI_REGION_SYS_MEMORY set
257 if ((flags
& PCI_REGION_TYPE
) == PCI_REGION_MEM
) {
258 ret
= __pci_hose_phys_to_bus(hose
, phys_addr
,
259 flags
, PCI_REGION_SYS_MEMORY
, &bus_addr
);
264 ret
= __pci_hose_phys_to_bus(hose
, phys_addr
, flags
, 0, &bus_addr
);
267 puts("pci_hose_phys_to_bus: invalid physical address\n");
272 pci_dev_t
pci_find_device(unsigned int vendor
, unsigned int device
, int index
)
274 struct pci_device_id ids
[2] = { {}, {0, 0} };
276 ids
[0].vendor
= vendor
;
277 ids
[0].device
= device
;
279 return pci_find_devices(ids
, index
);
282 pci_dev_t
pci_hose_find_devices(struct pci_controller
*hose
, int busnum
,
283 struct pci_device_id
*ids
, int *indexp
)
291 for (bdf
= PCI_BDF(busnum
, 0, 0);
292 bdf
< PCI_BDF(busnum
+ 1, 0, 0);
293 bdf
+= PCI_BDF(0, 0, 1)) {
294 if (pci_skip_dev(hose
, bdf
))
297 if (!PCI_FUNC(bdf
)) {
298 pci_read_config_byte(bdf
, PCI_HEADER_TYPE
,
300 found_multi
= header_type
& 0x80;
306 pci_read_config_word(bdf
, PCI_VENDOR_ID
, &vendor
);
307 pci_read_config_word(bdf
, PCI_DEVICE_ID
, &device
);
309 for (i
= 0; ids
[i
].vendor
!= 0; i
++) {
310 if (vendor
== ids
[i
].vendor
&&
311 device
== ids
[i
].device
) {
323 pci_dev_t
pci_find_class(uint find_class
, int index
)
330 for (bus
= 0; bus
<= pci_last_busno(); bus
++) {
331 for (devnum
= 0; devnum
< PCI_MAX_PCI_DEVICES
- 1; devnum
++) {
332 pci_read_config_dword(PCI_BDF(bus
, devnum
, 0),
333 PCI_CLASS_REVISION
, &class);
334 if (class >> 16 == 0xffff)
337 for (bdf
= PCI_BDF(bus
, devnum
, 0);
338 bdf
<= PCI_BDF(bus
, devnum
,
339 PCI_MAX_PCI_FUNCTIONS
- 1);
340 bdf
+= PCI_BDF(0, 0, 1)) {
341 pci_read_config_dword(bdf
, PCI_CLASS_REVISION
,
345 if (class != find_class
)
348 * Decrement the index. We want to return the
349 * correct device, so index is 0 for the first
350 * matching device, 1 for the second, etc.
356 /* Return index'th controller. */
364 #endif /* !CONFIG_DM_PCI || CONFIG_DM_PCI_COMPAT */