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