xref: /openbmc/u-boot/drivers/pci/pci_common.c (revision 83bf0057)
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 <dm.h>
15 #include <errno.h>
16 #include <pci.h>
17 #include <asm/io.h>
18 
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 
82 pci_dev_t pci_find_class(uint find_class, int index)
83 {
84 	int bus;
85 	int devnum;
86 	pci_dev_t bdf;
87 	uint32_t class;
88 
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)
94 				continue;
95 
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,
101 						      &class);
102 				class >>= 8;
103 
104 				if (class != find_class)
105 					continue;
106 				/*
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.
110 				 */
111 				if (index) {
112 					index--;
113 					continue;
114 				}
115 				/* Return index'th controller. */
116 				return bdf;
117 			}
118 		}
119 	}
120 
121 	return -ENODEV;
122 }
123 
124 __weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
125 {
126 	/*
127 	 * Check if pci device should be skipped in configuration
128 	 */
129 	if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
130 #if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
131 		/*
132 		 * Only skip configuration if "pciconfighost" is not set
133 		 */
134 		if (getenv("pciconfighost") == NULL)
135 			return 1;
136 #else
137 		return 1;
138 #endif
139 	}
140 
141 	return 0;
142 }
143 
144 /* Get a virtual address associated with a BAR region */
145 void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
146 {
147 	pci_addr_t pci_bus_addr;
148 	u32 bar_response;
149 
150 	/* read BAR address */
151 	pci_read_config_dword(pdev, bar, &bar_response);
152 	pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
153 
154 	/*
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.
159 	 */
160 	return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
161 }
162 
163 void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
164 		     u32 addr_and_ctrl)
165 {
166 	int bar;
167 
168 	bar = PCI_BASE_ADDRESS_0 + barnum * 4;
169 	pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl);
170 }
171 
172 u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
173 {
174 	u32 addr;
175 	int bar;
176 
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;
181 	else
182 		return addr & PCI_BASE_ADDRESS_MEM_MASK;
183 }
184 
185 int __pci_hose_bus_to_phys(struct pci_controller *hose,
186 			   pci_addr_t bus_addr,
187 			   unsigned long flags,
188 			   unsigned long skip_mask,
189 			   phys_addr_t *pa)
190 {
191 	struct pci_region *res;
192 	int i;
193 
194 	for (i = 0; i < hose->region_count; i++) {
195 		res = &hose->regions[i];
196 
197 		if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
198 			continue;
199 
200 		if (res->flags & skip_mask)
201 			continue;
202 
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);
206 			return 0;
207 		}
208 	}
209 
210 	return 1;
211 }
212 
213 phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose,
214 				 pci_addr_t bus_addr,
215 				 unsigned long flags)
216 {
217 	phys_addr_t phys_addr = 0;
218 	int ret;
219 
220 	if (!hose) {
221 		puts("pci_hose_bus_to_phys: invalid hose\n");
222 		return phys_addr;
223 	}
224 
225 #ifdef CONFIG_DM_PCI
226 	/* The root controller has the region information */
227 	hose = pci_bus_to_hose(0);
228 #endif
229 
230 	/*
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
233 	 */
234 	if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
235 		ret = __pci_hose_bus_to_phys(hose, bus_addr,
236 				flags, PCI_REGION_SYS_MEMORY, &phys_addr);
237 		if (!ret)
238 			return phys_addr;
239 	}
240 
241 	ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
242 
243 	if (ret)
244 		puts("pci_hose_bus_to_phys: invalid physical address\n");
245 
246 	return phys_addr;
247 }
248 
249 int __pci_hose_phys_to_bus(struct pci_controller *hose,
250 			   phys_addr_t phys_addr,
251 			   unsigned long flags,
252 			   unsigned long skip_mask,
253 			   pci_addr_t *ba)
254 {
255 	struct pci_region *res;
256 	pci_addr_t bus_addr;
257 	int i;
258 
259 	for (i = 0; i < hose->region_count; i++) {
260 		res = &hose->regions[i];
261 
262 		if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
263 			continue;
264 
265 		if (res->flags & skip_mask)
266 			continue;
267 
268 		bus_addr = phys_addr - res->phys_start + res->bus_start;
269 
270 		if (bus_addr >= res->bus_start &&
271 		    bus_addr < res->bus_start + res->size) {
272 			*ba = bus_addr;
273 			return 0;
274 		}
275 	}
276 
277 	return 1;
278 }
279 
280 pci_addr_t pci_hose_phys_to_bus(struct pci_controller *hose,
281 				phys_addr_t phys_addr,
282 				unsigned long flags)
283 {
284 	pci_addr_t bus_addr = 0;
285 	int ret;
286 
287 	if (!hose) {
288 		puts("pci_hose_phys_to_bus: invalid hose\n");
289 		return bus_addr;
290 	}
291 
292 #ifdef CONFIG_DM_PCI
293 	/* The root controller has the region information */
294 	hose = pci_bus_to_hose(0);
295 #endif
296 
297 	/*
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
300 	 */
301 	if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
302 		ret = __pci_hose_phys_to_bus(hose, phys_addr,
303 				flags, PCI_REGION_SYS_MEMORY, &bus_addr);
304 		if (!ret)
305 			return bus_addr;
306 	}
307 
308 	ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr);
309 
310 	if (ret)
311 		puts("pci_hose_phys_to_bus: invalid physical address\n");
312 
313 	return bus_addr;
314 }
315 
316 pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
317 {
318 	struct pci_device_id ids[2] = { {}, {0, 0} };
319 
320 	ids[0].vendor = vendor;
321 	ids[0].device = device;
322 
323 	return pci_find_devices(ids, index);
324 }
325 
326 pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
327 				struct pci_device_id *ids, int *indexp)
328 {
329 	int found_multi = 0;
330 	u16 vendor, device;
331 	u8 header_type;
332 	pci_dev_t bdf;
333 	int i;
334 
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))
339 			continue;
340 
341 		if (!PCI_FUNC(bdf)) {
342 			pci_read_config_byte(bdf, PCI_HEADER_TYPE,
343 					     &header_type);
344 			found_multi = header_type & 0x80;
345 		} else {
346 			if (!found_multi)
347 				continue;
348 		}
349 
350 		pci_read_config_word(bdf, PCI_VENDOR_ID, &vendor);
351 		pci_read_config_word(bdf, PCI_DEVICE_ID, &device);
352 
353 		for (i = 0; ids[i].vendor != 0; i++) {
354 			if (vendor == ids[i].vendor &&
355 			    device == ids[i].device) {
356 				if ((*indexp) <= 0)
357 					return bdf;
358 
359 				(*indexp)--;
360 			}
361 		}
362 	}
363 
364 	return -1;
365 }
366