1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 2014 Google, Inc
4 *
5 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
6 * Andreas Heppel <aheppel@sysgo.de>
7 *
8 * (C) Copyright 2002, 2003
9 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
10 */
11
12 #include <common.h>
13 #include <dm.h>
14 #include <env.h>
15 #include <errno.h>
16 #include <pci.h>
17 #include <asm/io.h>
18
pci_class_str(u8 class)19 const char *pci_class_str(u8 class)
20 {
21 switch (class) {
22 case PCI_CLASS_NOT_DEFINED:
23 return "Build before PCI Rev2.0";
24 break;
25 case PCI_BASE_CLASS_STORAGE:
26 return "Mass storage controller";
27 break;
28 case PCI_BASE_CLASS_NETWORK:
29 return "Network controller";
30 break;
31 case PCI_BASE_CLASS_DISPLAY:
32 return "Display controller";
33 break;
34 case PCI_BASE_CLASS_MULTIMEDIA:
35 return "Multimedia device";
36 break;
37 case PCI_BASE_CLASS_MEMORY:
38 return "Memory controller";
39 break;
40 case PCI_BASE_CLASS_BRIDGE:
41 return "Bridge device";
42 break;
43 case PCI_BASE_CLASS_COMMUNICATION:
44 return "Simple comm. controller";
45 break;
46 case PCI_BASE_CLASS_SYSTEM:
47 return "Base system peripheral";
48 break;
49 case PCI_BASE_CLASS_INPUT:
50 return "Input device";
51 break;
52 case PCI_BASE_CLASS_DOCKING:
53 return "Docking station";
54 break;
55 case PCI_BASE_CLASS_PROCESSOR:
56 return "Processor";
57 break;
58 case PCI_BASE_CLASS_SERIAL:
59 return "Serial bus controller";
60 break;
61 case PCI_BASE_CLASS_INTELLIGENT:
62 return "Intelligent controller";
63 break;
64 case PCI_BASE_CLASS_SATELLITE:
65 return "Satellite controller";
66 break;
67 case PCI_BASE_CLASS_CRYPT:
68 return "Cryptographic device";
69 break;
70 case PCI_BASE_CLASS_SIGNAL_PROCESSING:
71 return "DSP";
72 break;
73 case PCI_CLASS_OTHERS:
74 return "Does not fit any class";
75 break;
76 default:
77 return "???";
78 break;
79 };
80 }
81
pci_skip_dev(struct pci_controller * hose,pci_dev_t dev)82 __weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
83 {
84 /*
85 * Check if pci device should be skipped in configuration
86 */
87 if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
88 #if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
89 /*
90 * Only skip configuration if "pciconfighost" is not set
91 */
92 #ifndef CONFIG_PCIE_BVT
93 if (env_get("pciconfighost") == NULL)
94 return 1;
95 #endif
96 return 0;
97 #else
98 return 1;
99 #endif
100 }
101
102 return 0;
103 }
104
105 #if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT)
106 /* Get a virtual address associated with a BAR region */
pci_map_bar(pci_dev_t pdev,int bar,int flags)107 void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
108 {
109 pci_addr_t pci_bus_addr;
110 u32 bar_response;
111
112 /* read BAR address */
113 pci_read_config_dword(pdev, bar, &bar_response);
114 pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
115
116 /*
117 * Pass "0" as the length argument to pci_bus_to_virt. The arg
118 * isn't actualy used on any platform because u-boot assumes a static
119 * linear mapping. In the future, this could read the BAR size
120 * and pass that as the size if needed.
121 */
122 return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
123 }
124
pci_write_bar32(struct pci_controller * hose,pci_dev_t dev,int barnum,u32 addr_and_ctrl)125 void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
126 u32 addr_and_ctrl)
127 {
128 int bar;
129
130 bar = PCI_BASE_ADDRESS_0 + barnum * 4;
131 pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl);
132 }
133
pci_read_bar32(struct pci_controller * hose,pci_dev_t dev,int barnum)134 u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
135 {
136 u32 addr;
137 int bar;
138
139 bar = PCI_BASE_ADDRESS_0 + barnum * 4;
140 pci_hose_read_config_dword(hose, dev, bar, &addr);
141 if (addr & PCI_BASE_ADDRESS_SPACE_IO)
142 return addr & PCI_BASE_ADDRESS_IO_MASK;
143 else
144 return addr & PCI_BASE_ADDRESS_MEM_MASK;
145 }
146
__pci_hose_bus_to_phys(struct pci_controller * hose,pci_addr_t bus_addr,unsigned long flags,unsigned long skip_mask,phys_addr_t * pa)147 int __pci_hose_bus_to_phys(struct pci_controller *hose,
148 pci_addr_t bus_addr,
149 unsigned long flags,
150 unsigned long skip_mask,
151 phys_addr_t *pa)
152 {
153 struct pci_region *res;
154 int i;
155
156 for (i = 0; i < hose->region_count; i++) {
157 res = &hose->regions[i];
158
159 if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
160 continue;
161
162 if (res->flags & skip_mask)
163 continue;
164
165 if (bus_addr >= res->bus_start &&
166 (bus_addr - res->bus_start) < res->size) {
167 *pa = (bus_addr - res->bus_start + res->phys_start);
168 return 0;
169 }
170 }
171
172 return 1;
173 }
174
pci_hose_bus_to_phys(struct pci_controller * hose,pci_addr_t bus_addr,unsigned long flags)175 phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose,
176 pci_addr_t bus_addr,
177 unsigned long flags)
178 {
179 phys_addr_t phys_addr = 0;
180 int ret;
181
182 if (!hose) {
183 puts("pci_hose_bus_to_phys: invalid hose\n");
184 return phys_addr;
185 }
186
187 /*
188 * if PCI_REGION_MEM is set we do a two pass search with preference
189 * on matches that don't have PCI_REGION_SYS_MEMORY set
190 */
191 if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) {
192 ret = __pci_hose_bus_to_phys(hose, bus_addr,
193 flags, PCI_REGION_SYS_MEMORY, &phys_addr);
194 if (!ret)
195 return phys_addr;
196 }
197
198 ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
199
200 if (ret)
201 puts("pci_hose_bus_to_phys: invalid physical address\n");
202
203 return phys_addr;
204 }
205
__pci_hose_phys_to_bus(struct pci_controller * hose,phys_addr_t phys_addr,unsigned long flags,unsigned long skip_mask,pci_addr_t * ba)206 int __pci_hose_phys_to_bus(struct pci_controller *hose,
207 phys_addr_t phys_addr,
208 unsigned long flags,
209 unsigned long skip_mask,
210 pci_addr_t *ba)
211 {
212 struct pci_region *res;
213 pci_addr_t bus_addr;
214 int i;
215
216 for (i = 0; i < hose->region_count; i++) {
217 res = &hose->regions[i];
218
219 if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
220 continue;
221
222 if (res->flags & skip_mask)
223 continue;
224
225 bus_addr = phys_addr - res->phys_start + res->bus_start;
226
227 if (bus_addr >= res->bus_start &&
228 (bus_addr - res->bus_start) < res->size) {
229 *ba = bus_addr;
230 return 0;
231 }
232 }
233
234 return 1;
235 }
236
237 /*
238 * pci_hose_phys_to_bus(): Convert physical address to bus address
239 * @hose: PCI hose of the root PCI controller
240 * @phys_addr: physical address to convert
241 * @flags: flags of pci regions
242 * @return bus address if OK, 0 on error
243 */
pci_hose_phys_to_bus(struct pci_controller * hose,phys_addr_t phys_addr,unsigned long flags)244 pci_addr_t pci_hose_phys_to_bus(struct pci_controller *hose,
245 phys_addr_t phys_addr,
246 unsigned long flags)
247 {
248 pci_addr_t bus_addr = 0;
249 int ret;
250
251 if (!hose) {
252 puts("pci_hose_phys_to_bus: invalid hose\n");
253 return bus_addr;
254 }
255
256 /*
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
259 */
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);
263 if (!ret)
264 return bus_addr;
265 }
266
267 ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr);
268
269 if (ret)
270 puts("pci_hose_phys_to_bus: invalid physical address\n");
271
272 return bus_addr;
273 }
274
pci_find_device(unsigned int vendor,unsigned int device,int index)275 pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
276 {
277 struct pci_device_id ids[2] = { {}, {0, 0} };
278
279 ids[0].vendor = vendor;
280 ids[0].device = device;
281
282 return pci_find_devices(ids, index);
283 }
284
pci_hose_find_devices(struct pci_controller * hose,int busnum,struct pci_device_id * ids,int * indexp)285 pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
286 struct pci_device_id *ids, int *indexp)
287 {
288 int found_multi = 0;
289 u16 vendor, device;
290 u8 header_type;
291 pci_dev_t bdf;
292 int i;
293
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))
298 continue;
299
300 if (!PCI_FUNC(bdf)) {
301 pci_read_config_byte(bdf, PCI_HEADER_TYPE,
302 &header_type);
303 found_multi = header_type & 0x80;
304 } else {
305 if (!found_multi)
306 continue;
307 }
308
309 pci_read_config_word(bdf, PCI_VENDOR_ID, &vendor);
310 pci_read_config_word(bdf, PCI_DEVICE_ID, &device);
311
312 for (i = 0; ids[i].vendor != 0; i++) {
313 if (vendor == ids[i].vendor &&
314 device == ids[i].device) {
315 if ((*indexp) <= 0)
316 return bdf;
317
318 (*indexp)--;
319 }
320 }
321 }
322
323 return -1;
324 }
325
pci_find_class(uint find_class,int index)326 pci_dev_t pci_find_class(uint find_class, int index)
327 {
328 int bus;
329 int devnum;
330 pci_dev_t bdf;
331 uint32_t class;
332
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)
338 continue;
339
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,
345 &class);
346 class >>= 8;
347
348 if (class != find_class)
349 continue;
350 /*
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.
354 */
355 if (index) {
356 index--;
357 continue;
358 }
359 /* Return index'th controller. */
360 return bdf;
361 }
362 }
363 }
364
365 return -ENODEV;
366 }
367 #endif /* !CONFIG_DM_PCI || CONFIG_DM_PCI_COMPAT */
368