xref: /rk3399_rockchip-uboot/drivers/pci/pci-uclass.c (revision 069155cbb44c1e9e45676ac64e3c95f76a8d5820)
1ff3e077bSSimon Glass /*
2ff3e077bSSimon Glass  * Copyright (c) 2014 Google, Inc
3ff3e077bSSimon Glass  * Written by Simon Glass <sjg@chromium.org>
4ff3e077bSSimon Glass  *
5ff3e077bSSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
6ff3e077bSSimon Glass  */
7ff3e077bSSimon Glass 
8ff3e077bSSimon Glass #include <common.h>
9ff3e077bSSimon Glass #include <dm.h>
10ff3e077bSSimon Glass #include <errno.h>
11ff3e077bSSimon Glass #include <fdtdec.h>
12ff3e077bSSimon Glass #include <inttypes.h>
13ff3e077bSSimon Glass #include <pci.h>
14ff3e077bSSimon Glass #include <dm/lists.h>
15ff3e077bSSimon Glass #include <dm/root.h>
16ff3e077bSSimon Glass #include <dm/device-internal.h>
17348b744bSBin Meng #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
18348b744bSBin Meng #include <asm/fsp/fsp_support.h>
19348b744bSBin Meng #endif
20ff3e077bSSimon Glass 
21ff3e077bSSimon Glass DECLARE_GLOBAL_DATA_PTR;
22ff3e077bSSimon Glass 
23983c6ba2SSimon Glass static int pci_get_bus(int busnum, struct udevice **busp)
24983c6ba2SSimon Glass {
25983c6ba2SSimon Glass 	int ret;
26983c6ba2SSimon Glass 
27983c6ba2SSimon Glass 	ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, busp);
28983c6ba2SSimon Glass 
29983c6ba2SSimon Glass 	/* Since buses may not be numbered yet try a little harder with bus 0 */
30983c6ba2SSimon Glass 	if (ret == -ENODEV) {
31983c6ba2SSimon Glass 		ret = uclass_first_device(UCLASS_PCI, busp);
32983c6ba2SSimon Glass 		if (ret)
33983c6ba2SSimon Glass 			return ret;
34983c6ba2SSimon Glass 		else if (!*busp)
35983c6ba2SSimon Glass 			return -ENODEV;
36983c6ba2SSimon Glass 		ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, busp);
37983c6ba2SSimon Glass 	}
38983c6ba2SSimon Glass 
39983c6ba2SSimon Glass 	return ret;
40983c6ba2SSimon Glass }
41983c6ba2SSimon Glass 
42ff3e077bSSimon Glass struct pci_controller *pci_bus_to_hose(int busnum)
43ff3e077bSSimon Glass {
44ff3e077bSSimon Glass 	struct udevice *bus;
45ff3e077bSSimon Glass 	int ret;
46ff3e077bSSimon Glass 
47983c6ba2SSimon Glass 	ret = pci_get_bus(busnum, &bus);
48ff3e077bSSimon Glass 	if (ret) {
49ff3e077bSSimon Glass 		debug("%s: Cannot get bus %d: ret=%d\n", __func__, busnum, ret);
50ff3e077bSSimon Glass 		return NULL;
51ff3e077bSSimon Glass 	}
52983c6ba2SSimon Glass 
53ff3e077bSSimon Glass 	return dev_get_uclass_priv(bus);
54ff3e077bSSimon Glass }
55ff3e077bSSimon Glass 
564b515e4fSSimon Glass pci_dev_t pci_get_bdf(struct udevice *dev)
574b515e4fSSimon Glass {
584b515e4fSSimon Glass 	struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
594b515e4fSSimon Glass 	struct udevice *bus = dev->parent;
604b515e4fSSimon Glass 
614b515e4fSSimon Glass 	return PCI_ADD_BUS(bus->seq, pplat->devfn);
624b515e4fSSimon Glass }
634b515e4fSSimon Glass 
64ff3e077bSSimon Glass /**
65ff3e077bSSimon Glass  * pci_get_bus_max() - returns the bus number of the last active bus
66ff3e077bSSimon Glass  *
67ff3e077bSSimon Glass  * @return last bus number, or -1 if no active buses
68ff3e077bSSimon Glass  */
69ff3e077bSSimon Glass static int pci_get_bus_max(void)
70ff3e077bSSimon Glass {
71ff3e077bSSimon Glass 	struct udevice *bus;
72ff3e077bSSimon Glass 	struct uclass *uc;
73ff3e077bSSimon Glass 	int ret = -1;
74ff3e077bSSimon Glass 
75ff3e077bSSimon Glass 	ret = uclass_get(UCLASS_PCI, &uc);
76ff3e077bSSimon Glass 	uclass_foreach_dev(bus, uc) {
77ff3e077bSSimon Glass 		if (bus->seq > ret)
78ff3e077bSSimon Glass 			ret = bus->seq;
79ff3e077bSSimon Glass 	}
80ff3e077bSSimon Glass 
81ff3e077bSSimon Glass 	debug("%s: ret=%d\n", __func__, ret);
82ff3e077bSSimon Glass 
83ff3e077bSSimon Glass 	return ret;
84ff3e077bSSimon Glass }
85ff3e077bSSimon Glass 
86ff3e077bSSimon Glass int pci_last_busno(void)
87ff3e077bSSimon Glass {
88*069155cbSBin Meng 	return pci_get_bus_max();
89ff3e077bSSimon Glass }
90ff3e077bSSimon Glass 
91ff3e077bSSimon Glass int pci_get_ff(enum pci_size_t size)
92ff3e077bSSimon Glass {
93ff3e077bSSimon Glass 	switch (size) {
94ff3e077bSSimon Glass 	case PCI_SIZE_8:
95ff3e077bSSimon Glass 		return 0xff;
96ff3e077bSSimon Glass 	case PCI_SIZE_16:
97ff3e077bSSimon Glass 		return 0xffff;
98ff3e077bSSimon Glass 	default:
99ff3e077bSSimon Glass 		return 0xffffffff;
100ff3e077bSSimon Glass 	}
101ff3e077bSSimon Glass }
102ff3e077bSSimon Glass 
103ff3e077bSSimon Glass int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn,
104ff3e077bSSimon Glass 		       struct udevice **devp)
105ff3e077bSSimon Glass {
106ff3e077bSSimon Glass 	struct udevice *dev;
107ff3e077bSSimon Glass 
108ff3e077bSSimon Glass 	for (device_find_first_child(bus, &dev);
109ff3e077bSSimon Glass 	     dev;
110ff3e077bSSimon Glass 	     device_find_next_child(&dev)) {
111ff3e077bSSimon Glass 		struct pci_child_platdata *pplat;
112ff3e077bSSimon Glass 
113ff3e077bSSimon Glass 		pplat = dev_get_parent_platdata(dev);
114ff3e077bSSimon Glass 		if (pplat && pplat->devfn == find_devfn) {
115ff3e077bSSimon Glass 			*devp = dev;
116ff3e077bSSimon Glass 			return 0;
117ff3e077bSSimon Glass 		}
118ff3e077bSSimon Glass 	}
119ff3e077bSSimon Glass 
120ff3e077bSSimon Glass 	return -ENODEV;
121ff3e077bSSimon Glass }
122ff3e077bSSimon Glass 
123ff3e077bSSimon Glass int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp)
124ff3e077bSSimon Glass {
125ff3e077bSSimon Glass 	struct udevice *bus;
126ff3e077bSSimon Glass 	int ret;
127ff3e077bSSimon Glass 
128983c6ba2SSimon Glass 	ret = pci_get_bus(PCI_BUS(bdf), &bus);
129ff3e077bSSimon Glass 	if (ret)
130ff3e077bSSimon Glass 		return ret;
131ff3e077bSSimon Glass 	return pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), devp);
132ff3e077bSSimon Glass }
133ff3e077bSSimon Glass 
134ff3e077bSSimon Glass static int pci_device_matches_ids(struct udevice *dev,
135ff3e077bSSimon Glass 				  struct pci_device_id *ids)
136ff3e077bSSimon Glass {
137ff3e077bSSimon Glass 	struct pci_child_platdata *pplat;
138ff3e077bSSimon Glass 	int i;
139ff3e077bSSimon Glass 
140ff3e077bSSimon Glass 	pplat = dev_get_parent_platdata(dev);
141ff3e077bSSimon Glass 	if (!pplat)
142ff3e077bSSimon Glass 		return -EINVAL;
143ff3e077bSSimon Glass 	for (i = 0; ids[i].vendor != 0; i++) {
144ff3e077bSSimon Glass 		if (pplat->vendor == ids[i].vendor &&
145ff3e077bSSimon Glass 		    pplat->device == ids[i].device)
146ff3e077bSSimon Glass 			return i;
147ff3e077bSSimon Glass 	}
148ff3e077bSSimon Glass 
149ff3e077bSSimon Glass 	return -EINVAL;
150ff3e077bSSimon Glass }
151ff3e077bSSimon Glass 
152ff3e077bSSimon Glass int pci_bus_find_devices(struct udevice *bus, struct pci_device_id *ids,
153ff3e077bSSimon Glass 			 int *indexp, struct udevice **devp)
154ff3e077bSSimon Glass {
155ff3e077bSSimon Glass 	struct udevice *dev;
156ff3e077bSSimon Glass 
157ff3e077bSSimon Glass 	/* Scan all devices on this bus */
158ff3e077bSSimon Glass 	for (device_find_first_child(bus, &dev);
159ff3e077bSSimon Glass 	     dev;
160ff3e077bSSimon Glass 	     device_find_next_child(&dev)) {
161ff3e077bSSimon Glass 		if (pci_device_matches_ids(dev, ids) >= 0) {
162ff3e077bSSimon Glass 			if ((*indexp)-- <= 0) {
163ff3e077bSSimon Glass 				*devp = dev;
164ff3e077bSSimon Glass 				return 0;
165ff3e077bSSimon Glass 			}
166ff3e077bSSimon Glass 		}
167ff3e077bSSimon Glass 	}
168ff3e077bSSimon Glass 
169ff3e077bSSimon Glass 	return -ENODEV;
170ff3e077bSSimon Glass }
171ff3e077bSSimon Glass 
172ff3e077bSSimon Glass int pci_find_device_id(struct pci_device_id *ids, int index,
173ff3e077bSSimon Glass 		       struct udevice **devp)
174ff3e077bSSimon Glass {
175ff3e077bSSimon Glass 	struct udevice *bus;
176ff3e077bSSimon Glass 
177ff3e077bSSimon Glass 	/* Scan all known buses */
178ff3e077bSSimon Glass 	for (uclass_first_device(UCLASS_PCI, &bus);
179ff3e077bSSimon Glass 	     bus;
180ff3e077bSSimon Glass 	     uclass_next_device(&bus)) {
181ff3e077bSSimon Glass 		if (!pci_bus_find_devices(bus, ids, &index, devp))
182ff3e077bSSimon Glass 			return 0;
183ff3e077bSSimon Glass 	}
184ff3e077bSSimon Glass 	*devp = NULL;
185ff3e077bSSimon Glass 
186ff3e077bSSimon Glass 	return -ENODEV;
187ff3e077bSSimon Glass }
188ff3e077bSSimon Glass 
189ff3e077bSSimon Glass int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
190ff3e077bSSimon Glass 			 unsigned long value, enum pci_size_t size)
191ff3e077bSSimon Glass {
192ff3e077bSSimon Glass 	struct dm_pci_ops *ops;
193ff3e077bSSimon Glass 
194ff3e077bSSimon Glass 	ops = pci_get_ops(bus);
195ff3e077bSSimon Glass 	if (!ops->write_config)
196ff3e077bSSimon Glass 		return -ENOSYS;
197ff3e077bSSimon Glass 	return ops->write_config(bus, bdf, offset, value, size);
198ff3e077bSSimon Glass }
199ff3e077bSSimon Glass 
200ff3e077bSSimon Glass int pci_write_config(pci_dev_t bdf, int offset, unsigned long value,
201ff3e077bSSimon Glass 		     enum pci_size_t size)
202ff3e077bSSimon Glass {
203ff3e077bSSimon Glass 	struct udevice *bus;
204ff3e077bSSimon Glass 	int ret;
205ff3e077bSSimon Glass 
206983c6ba2SSimon Glass 	ret = pci_get_bus(PCI_BUS(bdf), &bus);
207ff3e077bSSimon Glass 	if (ret)
208ff3e077bSSimon Glass 		return ret;
209ff3e077bSSimon Glass 
2104d8615cbSBin Meng 	return pci_bus_write_config(bus, bdf, offset, value, size);
211ff3e077bSSimon Glass }
212ff3e077bSSimon Glass 
21366afb4edSSimon Glass int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value,
21466afb4edSSimon Glass 			enum pci_size_t size)
21566afb4edSSimon Glass {
21666afb4edSSimon Glass 	struct udevice *bus;
21766afb4edSSimon Glass 
2181e0f2263SBin Meng 	for (bus = dev; device_is_on_pci_bus(bus);)
21966afb4edSSimon Glass 		bus = bus->parent;
22066afb4edSSimon Glass 	return pci_bus_write_config(bus, pci_get_bdf(dev), offset, value, size);
22166afb4edSSimon Glass }
22266afb4edSSimon Glass 
22366afb4edSSimon Glass 
224ff3e077bSSimon Glass int pci_write_config32(pci_dev_t bdf, int offset, u32 value)
225ff3e077bSSimon Glass {
226ff3e077bSSimon Glass 	return pci_write_config(bdf, offset, value, PCI_SIZE_32);
227ff3e077bSSimon Glass }
228ff3e077bSSimon Glass 
229ff3e077bSSimon Glass int pci_write_config16(pci_dev_t bdf, int offset, u16 value)
230ff3e077bSSimon Glass {
231ff3e077bSSimon Glass 	return pci_write_config(bdf, offset, value, PCI_SIZE_16);
232ff3e077bSSimon Glass }
233ff3e077bSSimon Glass 
234ff3e077bSSimon Glass int pci_write_config8(pci_dev_t bdf, int offset, u8 value)
235ff3e077bSSimon Glass {
236ff3e077bSSimon Glass 	return pci_write_config(bdf, offset, value, PCI_SIZE_8);
237ff3e077bSSimon Glass }
238ff3e077bSSimon Glass 
23966afb4edSSimon Glass int dm_pci_write_config8(struct udevice *dev, int offset, u8 value)
24066afb4edSSimon Glass {
24166afb4edSSimon Glass 	return dm_pci_write_config(dev, offset, value, PCI_SIZE_8);
24266afb4edSSimon Glass }
24366afb4edSSimon Glass 
24466afb4edSSimon Glass int dm_pci_write_config16(struct udevice *dev, int offset, u16 value)
24566afb4edSSimon Glass {
24666afb4edSSimon Glass 	return dm_pci_write_config(dev, offset, value, PCI_SIZE_16);
24766afb4edSSimon Glass }
24866afb4edSSimon Glass 
24966afb4edSSimon Glass int dm_pci_write_config32(struct udevice *dev, int offset, u32 value)
25066afb4edSSimon Glass {
25166afb4edSSimon Glass 	return dm_pci_write_config(dev, offset, value, PCI_SIZE_32);
25266afb4edSSimon Glass }
25366afb4edSSimon Glass 
254ff3e077bSSimon Glass int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset,
255ff3e077bSSimon Glass 			unsigned long *valuep, enum pci_size_t size)
256ff3e077bSSimon Glass {
257ff3e077bSSimon Glass 	struct dm_pci_ops *ops;
258ff3e077bSSimon Glass 
259ff3e077bSSimon Glass 	ops = pci_get_ops(bus);
260ff3e077bSSimon Glass 	if (!ops->read_config)
261ff3e077bSSimon Glass 		return -ENOSYS;
262ff3e077bSSimon Glass 	return ops->read_config(bus, bdf, offset, valuep, size);
263ff3e077bSSimon Glass }
264ff3e077bSSimon Glass 
265ff3e077bSSimon Glass int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep,
266ff3e077bSSimon Glass 		    enum pci_size_t size)
267ff3e077bSSimon Glass {
268ff3e077bSSimon Glass 	struct udevice *bus;
269ff3e077bSSimon Glass 	int ret;
270ff3e077bSSimon Glass 
271983c6ba2SSimon Glass 	ret = pci_get_bus(PCI_BUS(bdf), &bus);
272ff3e077bSSimon Glass 	if (ret)
273ff3e077bSSimon Glass 		return ret;
274ff3e077bSSimon Glass 
2754d8615cbSBin Meng 	return pci_bus_read_config(bus, bdf, offset, valuep, size);
276ff3e077bSSimon Glass }
277ff3e077bSSimon Glass 
27866afb4edSSimon Glass int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep,
27966afb4edSSimon Glass 		       enum pci_size_t size)
28066afb4edSSimon Glass {
28166afb4edSSimon Glass 	struct udevice *bus;
28266afb4edSSimon Glass 
2831e0f2263SBin Meng 	for (bus = dev; device_is_on_pci_bus(bus);)
28466afb4edSSimon Glass 		bus = bus->parent;
28566afb4edSSimon Glass 	return pci_bus_read_config(bus, pci_get_bdf(dev), offset, valuep,
28666afb4edSSimon Glass 				   size);
28766afb4edSSimon Glass }
28866afb4edSSimon Glass 
289ff3e077bSSimon Glass int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep)
290ff3e077bSSimon Glass {
291ff3e077bSSimon Glass 	unsigned long value;
292ff3e077bSSimon Glass 	int ret;
293ff3e077bSSimon Glass 
294ff3e077bSSimon Glass 	ret = pci_read_config(bdf, offset, &value, PCI_SIZE_32);
295ff3e077bSSimon Glass 	if (ret)
296ff3e077bSSimon Glass 		return ret;
297ff3e077bSSimon Glass 	*valuep = value;
298ff3e077bSSimon Glass 
299ff3e077bSSimon Glass 	return 0;
300ff3e077bSSimon Glass }
301ff3e077bSSimon Glass 
302ff3e077bSSimon Glass int pci_read_config16(pci_dev_t bdf, int offset, u16 *valuep)
303ff3e077bSSimon Glass {
304ff3e077bSSimon Glass 	unsigned long value;
305ff3e077bSSimon Glass 	int ret;
306ff3e077bSSimon Glass 
307ff3e077bSSimon Glass 	ret = pci_read_config(bdf, offset, &value, PCI_SIZE_16);
308ff3e077bSSimon Glass 	if (ret)
309ff3e077bSSimon Glass 		return ret;
310ff3e077bSSimon Glass 	*valuep = value;
311ff3e077bSSimon Glass 
312ff3e077bSSimon Glass 	return 0;
313ff3e077bSSimon Glass }
314ff3e077bSSimon Glass 
315ff3e077bSSimon Glass int pci_read_config8(pci_dev_t bdf, int offset, u8 *valuep)
316ff3e077bSSimon Glass {
317ff3e077bSSimon Glass 	unsigned long value;
318ff3e077bSSimon Glass 	int ret;
319ff3e077bSSimon Glass 
320ff3e077bSSimon Glass 	ret = pci_read_config(bdf, offset, &value, PCI_SIZE_8);
321ff3e077bSSimon Glass 	if (ret)
322ff3e077bSSimon Glass 		return ret;
323ff3e077bSSimon Glass 	*valuep = value;
324ff3e077bSSimon Glass 
325ff3e077bSSimon Glass 	return 0;
326ff3e077bSSimon Glass }
327ff3e077bSSimon Glass 
32866afb4edSSimon Glass int dm_pci_read_config8(struct udevice *dev, int offset, u8 *valuep)
32966afb4edSSimon Glass {
33066afb4edSSimon Glass 	unsigned long value;
33166afb4edSSimon Glass 	int ret;
33266afb4edSSimon Glass 
33366afb4edSSimon Glass 	ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_8);
33466afb4edSSimon Glass 	if (ret)
33566afb4edSSimon Glass 		return ret;
33666afb4edSSimon Glass 	*valuep = value;
33766afb4edSSimon Glass 
33866afb4edSSimon Glass 	return 0;
33966afb4edSSimon Glass }
34066afb4edSSimon Glass 
34166afb4edSSimon Glass int dm_pci_read_config16(struct udevice *dev, int offset, u16 *valuep)
34266afb4edSSimon Glass {
34366afb4edSSimon Glass 	unsigned long value;
34466afb4edSSimon Glass 	int ret;
34566afb4edSSimon Glass 
34666afb4edSSimon Glass 	ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_16);
34766afb4edSSimon Glass 	if (ret)
34866afb4edSSimon Glass 		return ret;
34966afb4edSSimon Glass 	*valuep = value;
35066afb4edSSimon Glass 
35166afb4edSSimon Glass 	return 0;
35266afb4edSSimon Glass }
35366afb4edSSimon Glass 
35466afb4edSSimon Glass int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep)
35566afb4edSSimon Glass {
35666afb4edSSimon Glass 	unsigned long value;
35766afb4edSSimon Glass 	int ret;
35866afb4edSSimon Glass 
35966afb4edSSimon Glass 	ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_32);
36066afb4edSSimon Glass 	if (ret)
36166afb4edSSimon Glass 		return ret;
36266afb4edSSimon Glass 	*valuep = value;
36366afb4edSSimon Glass 
36466afb4edSSimon Glass 	return 0;
36566afb4edSSimon Glass }
36666afb4edSSimon Glass 
367ff3e077bSSimon Glass int pci_auto_config_devices(struct udevice *bus)
368ff3e077bSSimon Glass {
369ff3e077bSSimon Glass 	struct pci_controller *hose = bus->uclass_priv;
370ff3e077bSSimon Glass 	unsigned int sub_bus;
371ff3e077bSSimon Glass 	struct udevice *dev;
372ff3e077bSSimon Glass 	int ret;
373ff3e077bSSimon Glass 
374ff3e077bSSimon Glass 	sub_bus = bus->seq;
375ff3e077bSSimon Glass 	debug("%s: start\n", __func__);
376ff3e077bSSimon Glass 	pciauto_config_init(hose);
377ff3e077bSSimon Glass 	for (ret = device_find_first_child(bus, &dev);
378ff3e077bSSimon Glass 	     !ret && dev;
379ff3e077bSSimon Glass 	     ret = device_find_next_child(&dev)) {
380ff3e077bSSimon Glass 		unsigned int max_bus;
3814d21455eSSimon Glass 		int ret;
382ff3e077bSSimon Glass 
383ff3e077bSSimon Glass 		debug("%s: device %s\n", __func__, dev->name);
3844d21455eSSimon Glass 		ret = pciauto_config_device(hose, pci_get_bdf(dev));
3854d21455eSSimon Glass 		if (ret < 0)
3864d21455eSSimon Glass 			return ret;
3874d21455eSSimon Glass 		max_bus = ret;
388ff3e077bSSimon Glass 		sub_bus = max(sub_bus, max_bus);
389ff3e077bSSimon Glass 	}
390ff3e077bSSimon Glass 	debug("%s: done\n", __func__);
391ff3e077bSSimon Glass 
392ff3e077bSSimon Glass 	return sub_bus;
393ff3e077bSSimon Glass }
394ff3e077bSSimon Glass 
395ff3e077bSSimon Glass int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf)
396ff3e077bSSimon Glass {
397ff3e077bSSimon Glass 	struct udevice *parent, *bus;
398ff3e077bSSimon Glass 	int sub_bus;
399ff3e077bSSimon Glass 	int ret;
400ff3e077bSSimon Glass 
401ff3e077bSSimon Glass 	debug("%s\n", __func__);
402ff3e077bSSimon Glass 	parent = hose->bus;
403ff3e077bSSimon Glass 
404ff3e077bSSimon Glass 	/* Find the bus within the parent */
4058326f136SBin Meng 	ret = pci_bus_find_devfn(parent, PCI_MASK_BUS(bdf), &bus);
406ff3e077bSSimon Glass 	if (ret) {
407ff3e077bSSimon Glass 		debug("%s: Cannot find device %x on bus %s: %d\n", __func__,
408ff3e077bSSimon Glass 		      bdf, parent->name, ret);
409ff3e077bSSimon Glass 		return ret;
410ff3e077bSSimon Glass 	}
411ff3e077bSSimon Glass 
412ff3e077bSSimon Glass 	sub_bus = pci_get_bus_max() + 1;
413ff3e077bSSimon Glass 	debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name);
4145afeb4bbSSimon Glass 	pciauto_prescan_setup_bridge(hose, bdf, sub_bus);
415ff3e077bSSimon Glass 
416ff3e077bSSimon Glass 	ret = device_probe(bus);
417ff3e077bSSimon Glass 	if (ret) {
4183129ace4SSimon Glass 		debug("%s: Cannot probe bus %s: %d\n", __func__, bus->name,
419ff3e077bSSimon Glass 		      ret);
420ff3e077bSSimon Glass 		return ret;
421ff3e077bSSimon Glass 	}
422ff3e077bSSimon Glass 	if (sub_bus != bus->seq) {
423ff3e077bSSimon Glass 		printf("%s: Internal error, bus '%s' got seq %d, expected %d\n",
424ff3e077bSSimon Glass 		       __func__, bus->name, bus->seq, sub_bus);
425ff3e077bSSimon Glass 		return -EPIPE;
426ff3e077bSSimon Glass 	}
427ff3e077bSSimon Glass 	sub_bus = pci_get_bus_max();
428ff3e077bSSimon Glass 	pciauto_postscan_setup_bridge(hose, bdf, sub_bus);
429ff3e077bSSimon Glass 
430ff3e077bSSimon Glass 	return sub_bus;
431ff3e077bSSimon Glass }
432ff3e077bSSimon Glass 
433aba92962SSimon Glass /**
434aba92962SSimon Glass  * pci_match_one_device - Tell if a PCI device structure has a matching
435aba92962SSimon Glass  *                        PCI device id structure
436aba92962SSimon Glass  * @id: single PCI device id structure to match
437aba92962SSimon Glass  * @dev: the PCI device structure to match against
438aba92962SSimon Glass  *
439aba92962SSimon Glass  * Returns the matching pci_device_id structure or %NULL if there is no match.
440aba92962SSimon Glass  */
441aba92962SSimon Glass static bool pci_match_one_id(const struct pci_device_id *id,
442aba92962SSimon Glass 			     const struct pci_device_id *find)
443aba92962SSimon Glass {
444aba92962SSimon Glass 	if ((id->vendor == PCI_ANY_ID || id->vendor == find->vendor) &&
445aba92962SSimon Glass 	    (id->device == PCI_ANY_ID || id->device == find->device) &&
446aba92962SSimon Glass 	    (id->subvendor == PCI_ANY_ID || id->subvendor == find->subvendor) &&
447aba92962SSimon Glass 	    (id->subdevice == PCI_ANY_ID || id->subdevice == find->subdevice) &&
448aba92962SSimon Glass 	    !((id->class ^ find->class) & id->class_mask))
449aba92962SSimon Glass 		return true;
450aba92962SSimon Glass 
451aba92962SSimon Glass 	return false;
452aba92962SSimon Glass }
453aba92962SSimon Glass 
454aba92962SSimon Glass /**
455aba92962SSimon Glass  * pci_find_and_bind_driver() - Find and bind the right PCI driver
456aba92962SSimon Glass  *
457aba92962SSimon Glass  * This only looks at certain fields in the descriptor.
4585dbcf3a0SSimon Glass  *
4595dbcf3a0SSimon Glass  * @parent:	Parent bus
4605dbcf3a0SSimon Glass  * @find_id:	Specification of the driver to find
4615dbcf3a0SSimon Glass  * @bdf:	Bus/device/function addreess - see PCI_BDF()
4625dbcf3a0SSimon Glass  * @devp:	Returns a pointer to the device created
4635dbcf3a0SSimon Glass  * @return 0 if OK, -EPERM if the device is not needed before relocation and
4645dbcf3a0SSimon Glass  *	   therefore was not created, other -ve value on error
465aba92962SSimon Glass  */
466aba92962SSimon Glass static int pci_find_and_bind_driver(struct udevice *parent,
4675dbcf3a0SSimon Glass 				    struct pci_device_id *find_id,
4685dbcf3a0SSimon Glass 				    pci_dev_t bdf, struct udevice **devp)
469aba92962SSimon Glass {
470aba92962SSimon Glass 	struct pci_driver_entry *start, *entry;
471aba92962SSimon Glass 	const char *drv;
472aba92962SSimon Glass 	int n_ents;
473aba92962SSimon Glass 	int ret;
474aba92962SSimon Glass 	char name[30], *str;
47508fc7b8fSBin Meng 	bool bridge;
476aba92962SSimon Glass 
477aba92962SSimon Glass 	*devp = NULL;
478aba92962SSimon Glass 
479aba92962SSimon Glass 	debug("%s: Searching for driver: vendor=%x, device=%x\n", __func__,
480aba92962SSimon Glass 	      find_id->vendor, find_id->device);
481aba92962SSimon Glass 	start = ll_entry_start(struct pci_driver_entry, pci_driver_entry);
482aba92962SSimon Glass 	n_ents = ll_entry_count(struct pci_driver_entry, pci_driver_entry);
483aba92962SSimon Glass 	for (entry = start; entry != start + n_ents; entry++) {
484aba92962SSimon Glass 		const struct pci_device_id *id;
485aba92962SSimon Glass 		struct udevice *dev;
486aba92962SSimon Glass 		const struct driver *drv;
487aba92962SSimon Glass 
488aba92962SSimon Glass 		for (id = entry->match;
489aba92962SSimon Glass 		     id->vendor || id->subvendor || id->class_mask;
490aba92962SSimon Glass 		     id++) {
491aba92962SSimon Glass 			if (!pci_match_one_id(id, find_id))
492aba92962SSimon Glass 				continue;
493aba92962SSimon Glass 
494aba92962SSimon Glass 			drv = entry->driver;
49508fc7b8fSBin Meng 
49608fc7b8fSBin Meng 			/*
49708fc7b8fSBin Meng 			 * In the pre-relocation phase, we only bind devices
49808fc7b8fSBin Meng 			 * whose driver has the DM_FLAG_PRE_RELOC set, to save
49908fc7b8fSBin Meng 			 * precious memory space as on some platforms as that
50008fc7b8fSBin Meng 			 * space is pretty limited (ie: using Cache As RAM).
50108fc7b8fSBin Meng 			 */
50208fc7b8fSBin Meng 			if (!(gd->flags & GD_FLG_RELOC) &&
50308fc7b8fSBin Meng 			    !(drv->flags & DM_FLAG_PRE_RELOC))
5045dbcf3a0SSimon Glass 				return -EPERM;
50508fc7b8fSBin Meng 
506aba92962SSimon Glass 			/*
507aba92962SSimon Glass 			 * We could pass the descriptor to the driver as
508aba92962SSimon Glass 			 * platdata (instead of NULL) and allow its bind()
509aba92962SSimon Glass 			 * method to return -ENOENT if it doesn't support this
510aba92962SSimon Glass 			 * device. That way we could continue the search to
511aba92962SSimon Glass 			 * find another driver. For now this doesn't seem
512aba92962SSimon Glass 			 * necesssary, so just bind the first match.
513aba92962SSimon Glass 			 */
514aba92962SSimon Glass 			ret = device_bind(parent, drv, drv->name, NULL, -1,
515aba92962SSimon Glass 					  &dev);
516aba92962SSimon Glass 			if (ret)
517aba92962SSimon Glass 				goto error;
518aba92962SSimon Glass 			debug("%s: Match found: %s\n", __func__, drv->name);
519aba92962SSimon Glass 			dev->driver_data = find_id->driver_data;
520aba92962SSimon Glass 			*devp = dev;
521aba92962SSimon Glass 			return 0;
522aba92962SSimon Glass 		}
523aba92962SSimon Glass 	}
524aba92962SSimon Glass 
52508fc7b8fSBin Meng 	bridge = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI;
52608fc7b8fSBin Meng 	/*
52708fc7b8fSBin Meng 	 * In the pre-relocation phase, we only bind bridge devices to save
52808fc7b8fSBin Meng 	 * precious memory space as on some platforms as that space is pretty
52908fc7b8fSBin Meng 	 * limited (ie: using Cache As RAM).
53008fc7b8fSBin Meng 	 */
53108fc7b8fSBin Meng 	if (!(gd->flags & GD_FLG_RELOC) && !bridge)
5325dbcf3a0SSimon Glass 		return -EPERM;
53308fc7b8fSBin Meng 
534aba92962SSimon Glass 	/* Bind a generic driver so that the device can be used */
5354d8615cbSBin Meng 	sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf),
5364d8615cbSBin Meng 		PCI_FUNC(bdf));
537aba92962SSimon Glass 	str = strdup(name);
538aba92962SSimon Glass 	if (!str)
539aba92962SSimon Glass 		return -ENOMEM;
54008fc7b8fSBin Meng 	drv = bridge ? "pci_bridge_drv" : "pci_generic_drv";
54108fc7b8fSBin Meng 
542aba92962SSimon Glass 	ret = device_bind_driver(parent, drv, str, devp);
543aba92962SSimon Glass 	if (ret) {
5443129ace4SSimon Glass 		debug("%s: Failed to bind generic driver: %d\n", __func__, ret);
545aba92962SSimon Glass 		return ret;
546aba92962SSimon Glass 	}
547aba92962SSimon Glass 	debug("%s: No match found: bound generic driver instead\n", __func__);
548aba92962SSimon Glass 
549aba92962SSimon Glass 	return 0;
550aba92962SSimon Glass 
551aba92962SSimon Glass error:
552aba92962SSimon Glass 	debug("%s: No match found: error %d\n", __func__, ret);
553aba92962SSimon Glass 	return ret;
554aba92962SSimon Glass }
555aba92962SSimon Glass 
556ff3e077bSSimon Glass int pci_bind_bus_devices(struct udevice *bus)
557ff3e077bSSimon Glass {
558ff3e077bSSimon Glass 	ulong vendor, device;
559ff3e077bSSimon Glass 	ulong header_type;
5604d8615cbSBin Meng 	pci_dev_t bdf, end;
561ff3e077bSSimon Glass 	bool found_multi;
562ff3e077bSSimon Glass 	int ret;
563ff3e077bSSimon Glass 
564ff3e077bSSimon Glass 	found_multi = false;
5654d8615cbSBin Meng 	end = PCI_BDF(bus->seq, PCI_MAX_PCI_DEVICES - 1,
5664d8615cbSBin Meng 		      PCI_MAX_PCI_FUNCTIONS - 1);
5674d8615cbSBin Meng 	for (bdf = PCI_BDF(bus->seq, 0, 0); bdf < end;
5684d8615cbSBin Meng 	     bdf += PCI_BDF(0, 0, 1)) {
569ff3e077bSSimon Glass 		struct pci_child_platdata *pplat;
570ff3e077bSSimon Glass 		struct udevice *dev;
571ff3e077bSSimon Glass 		ulong class;
572ff3e077bSSimon Glass 
5734d8615cbSBin Meng 		if (PCI_FUNC(bdf) && !found_multi)
574ff3e077bSSimon Glass 			continue;
575ff3e077bSSimon Glass 		/* Check only the first access, we don't expect problems */
5764d8615cbSBin Meng 		ret = pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE,
577ff3e077bSSimon Glass 					  &header_type, PCI_SIZE_8);
578ff3e077bSSimon Glass 		if (ret)
579ff3e077bSSimon Glass 			goto error;
5804d8615cbSBin Meng 		pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor,
581ff3e077bSSimon Glass 				    PCI_SIZE_16);
582ff3e077bSSimon Glass 		if (vendor == 0xffff || vendor == 0x0000)
583ff3e077bSSimon Glass 			continue;
584ff3e077bSSimon Glass 
5854d8615cbSBin Meng 		if (!PCI_FUNC(bdf))
586ff3e077bSSimon Glass 			found_multi = header_type & 0x80;
587ff3e077bSSimon Glass 
588ff3e077bSSimon Glass 		debug("%s: bus %d/%s: found device %x, function %d\n", __func__,
5894d8615cbSBin Meng 		      bus->seq, bus->name, PCI_DEV(bdf), PCI_FUNC(bdf));
5904d8615cbSBin Meng 		pci_bus_read_config(bus, bdf, PCI_DEVICE_ID, &device,
591ff3e077bSSimon Glass 				    PCI_SIZE_16);
5924d8615cbSBin Meng 		pci_bus_read_config(bus, bdf, PCI_CLASS_REVISION, &class,
593aba92962SSimon Glass 				    PCI_SIZE_32);
594aba92962SSimon Glass 		class >>= 8;
595ff3e077bSSimon Glass 
596ff3e077bSSimon Glass 		/* Find this device in the device tree */
5974d8615cbSBin Meng 		ret = pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), &dev);
598ff3e077bSSimon Glass 
599aba92962SSimon Glass 		/* Search for a driver */
600aba92962SSimon Glass 
601ff3e077bSSimon Glass 		/* If nothing in the device tree, bind a generic device */
602ff3e077bSSimon Glass 		if (ret == -ENODEV) {
603aba92962SSimon Glass 			struct pci_device_id find_id;
604aba92962SSimon Glass 			ulong val;
605ff3e077bSSimon Glass 
606aba92962SSimon Glass 			memset(&find_id, '\0', sizeof(find_id));
607aba92962SSimon Glass 			find_id.vendor = vendor;
608aba92962SSimon Glass 			find_id.device = device;
609aba92962SSimon Glass 			find_id.class = class;
610aba92962SSimon Glass 			if ((header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL) {
6114d8615cbSBin Meng 				pci_bus_read_config(bus, bdf,
612aba92962SSimon Glass 						    PCI_SUBSYSTEM_VENDOR_ID,
613aba92962SSimon Glass 						    &val, PCI_SIZE_32);
614aba92962SSimon Glass 				find_id.subvendor = val & 0xffff;
615aba92962SSimon Glass 				find_id.subdevice = val >> 16;
616aba92962SSimon Glass 			}
6174d8615cbSBin Meng 			ret = pci_find_and_bind_driver(bus, &find_id, bdf,
618aba92962SSimon Glass 						       &dev);
619ff3e077bSSimon Glass 		}
6205dbcf3a0SSimon Glass 		if (ret == -EPERM)
6215dbcf3a0SSimon Glass 			continue;
6225dbcf3a0SSimon Glass 		else if (ret)
623ff3e077bSSimon Glass 			return ret;
624ff3e077bSSimon Glass 
625ff3e077bSSimon Glass 		/* Update the platform data */
626ff3e077bSSimon Glass 		pplat = dev_get_parent_platdata(dev);
6274d8615cbSBin Meng 		pplat->devfn = PCI_MASK_BUS(bdf);
628ff3e077bSSimon Glass 		pplat->vendor = vendor;
629ff3e077bSSimon Glass 		pplat->device = device;
630ff3e077bSSimon Glass 		pplat->class = class;
631ff3e077bSSimon Glass 	}
632ff3e077bSSimon Glass 
633ff3e077bSSimon Glass 	return 0;
634ff3e077bSSimon Glass error:
635ff3e077bSSimon Glass 	printf("Cannot read bus configuration: %d\n", ret);
636ff3e077bSSimon Glass 
637ff3e077bSSimon Glass 	return ret;
638ff3e077bSSimon Glass }
639ff3e077bSSimon Glass 
640ff3e077bSSimon Glass static int pci_uclass_post_bind(struct udevice *bus)
641ff3e077bSSimon Glass {
642ff3e077bSSimon Glass 	/*
6431887ed3aSBin Meng 	 * If there is no pci device listed in the device tree,
6441887ed3aSBin Meng 	 * don't bother scanning the device tree.
6451887ed3aSBin Meng 	 */
6461887ed3aSBin Meng 	if (bus->of_offset == -1)
6471887ed3aSBin Meng 		return 0;
6481887ed3aSBin Meng 
6491887ed3aSBin Meng 	/*
650ff3e077bSSimon Glass 	 * Scan the device tree for devices. This does not probe the PCI bus,
651ff3e077bSSimon Glass 	 * as this is not permitted while binding. It just finds devices
652ff3e077bSSimon Glass 	 * mentioned in the device tree.
653ff3e077bSSimon Glass 	 *
654ff3e077bSSimon Glass 	 * Before relocation, only bind devices marked for pre-relocation
655ff3e077bSSimon Glass 	 * use.
656ff3e077bSSimon Glass 	 */
657ff3e077bSSimon Glass 	return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset,
658ff3e077bSSimon Glass 				gd->flags & GD_FLG_RELOC ? false : true);
659ff3e077bSSimon Glass }
660ff3e077bSSimon Glass 
661ff3e077bSSimon Glass static int decode_regions(struct pci_controller *hose, const void *blob,
662ff3e077bSSimon Glass 			  int parent_node, int node)
663ff3e077bSSimon Glass {
664ff3e077bSSimon Glass 	int pci_addr_cells, addr_cells, size_cells;
665ff3e077bSSimon Glass 	int cells_per_record;
666b9da5086SSimon Glass 	phys_addr_t addr;
667ff3e077bSSimon Glass 	const u32 *prop;
668ff3e077bSSimon Glass 	int len;
669ff3e077bSSimon Glass 	int i;
670ff3e077bSSimon Glass 
671ff3e077bSSimon Glass 	prop = fdt_getprop(blob, node, "ranges", &len);
672ff3e077bSSimon Glass 	if (!prop)
673ff3e077bSSimon Glass 		return -EINVAL;
674ff3e077bSSimon Glass 	pci_addr_cells = fdt_address_cells(blob, node);
675ff3e077bSSimon Glass 	addr_cells = fdt_address_cells(blob, parent_node);
676ff3e077bSSimon Glass 	size_cells = fdt_size_cells(blob, node);
677ff3e077bSSimon Glass 
678ff3e077bSSimon Glass 	/* PCI addresses are always 3-cells */
679ff3e077bSSimon Glass 	len /= sizeof(u32);
680ff3e077bSSimon Glass 	cells_per_record = pci_addr_cells + addr_cells + size_cells;
681ff3e077bSSimon Glass 	hose->region_count = 0;
682ff3e077bSSimon Glass 	debug("%s: len=%d, cells_per_record=%d\n", __func__, len,
683ff3e077bSSimon Glass 	      cells_per_record);
684ff3e077bSSimon Glass 	for (i = 0; i < MAX_PCI_REGIONS; i++, len -= cells_per_record) {
685ff3e077bSSimon Glass 		u64 pci_addr, addr, size;
686ff3e077bSSimon Glass 		int space_code;
687ff3e077bSSimon Glass 		u32 flags;
688ff3e077bSSimon Glass 		int type;
689ff3e077bSSimon Glass 
690ff3e077bSSimon Glass 		if (len < cells_per_record)
691ff3e077bSSimon Glass 			break;
692ff3e077bSSimon Glass 		flags = fdt32_to_cpu(prop[0]);
693ff3e077bSSimon Glass 		space_code = (flags >> 24) & 3;
694ff3e077bSSimon Glass 		pci_addr = fdtdec_get_number(prop + 1, 2);
695ff3e077bSSimon Glass 		prop += pci_addr_cells;
696ff3e077bSSimon Glass 		addr = fdtdec_get_number(prop, addr_cells);
697ff3e077bSSimon Glass 		prop += addr_cells;
698ff3e077bSSimon Glass 		size = fdtdec_get_number(prop, size_cells);
699ff3e077bSSimon Glass 		prop += size_cells;
700ff3e077bSSimon Glass 		debug("%s: region %d, pci_addr=%" PRIx64 ", addr=%" PRIx64
701ff3e077bSSimon Glass 		      ", size=%" PRIx64 ", space_code=%d\n", __func__,
702ff3e077bSSimon Glass 		      hose->region_count, pci_addr, addr, size, space_code);
703ff3e077bSSimon Glass 		if (space_code & 2) {
704ff3e077bSSimon Glass 			type = flags & (1U << 30) ? PCI_REGION_PREFETCH :
705ff3e077bSSimon Glass 					PCI_REGION_MEM;
706ff3e077bSSimon Glass 		} else if (space_code & 1) {
707ff3e077bSSimon Glass 			type = PCI_REGION_IO;
708ff3e077bSSimon Glass 		} else {
709ff3e077bSSimon Glass 			continue;
710ff3e077bSSimon Glass 		}
711ff3e077bSSimon Glass 		debug(" - type=%d\n", type);
712ff3e077bSSimon Glass 		pci_set_region(hose->regions + hose->region_count++, pci_addr,
713ff3e077bSSimon Glass 			       addr, size, type);
714ff3e077bSSimon Glass 	}
715ff3e077bSSimon Glass 
716ff3e077bSSimon Glass 	/* Add a region for our local memory */
717b9da5086SSimon Glass 	addr = gd->ram_size;
718b9da5086SSimon Glass 	if (gd->pci_ram_top && gd->pci_ram_top < addr)
719b9da5086SSimon Glass 		addr = gd->pci_ram_top;
720b9da5086SSimon Glass 	pci_set_region(hose->regions + hose->region_count++, 0, 0, addr,
721b9da5086SSimon Glass 		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
722ff3e077bSSimon Glass 
723ff3e077bSSimon Glass 	return 0;
724ff3e077bSSimon Glass }
725ff3e077bSSimon Glass 
726ff3e077bSSimon Glass static int pci_uclass_pre_probe(struct udevice *bus)
727ff3e077bSSimon Glass {
728ff3e077bSSimon Glass 	struct pci_controller *hose;
729ff3e077bSSimon Glass 	int ret;
730ff3e077bSSimon Glass 
731ff3e077bSSimon Glass 	debug("%s, bus=%d/%s, parent=%s\n", __func__, bus->seq, bus->name,
732ff3e077bSSimon Glass 	      bus->parent->name);
733ff3e077bSSimon Glass 	hose = bus->uclass_priv;
734ff3e077bSSimon Glass 
735ff3e077bSSimon Glass 	/* For bridges, use the top-level PCI controller */
736ff3e077bSSimon Glass 	if (device_get_uclass_id(bus->parent) == UCLASS_ROOT) {
737ff3e077bSSimon Glass 		hose->ctlr = bus;
738ff3e077bSSimon Glass 		ret = decode_regions(hose, gd->fdt_blob, bus->parent->of_offset,
739ff3e077bSSimon Glass 				bus->of_offset);
740ff3e077bSSimon Glass 		if (ret) {
741ff3e077bSSimon Glass 			debug("%s: Cannot decode regions\n", __func__);
742ff3e077bSSimon Glass 			return ret;
743ff3e077bSSimon Glass 		}
744ff3e077bSSimon Glass 	} else {
745ff3e077bSSimon Glass 		struct pci_controller *parent_hose;
746ff3e077bSSimon Glass 
747ff3e077bSSimon Glass 		parent_hose = dev_get_uclass_priv(bus->parent);
748ff3e077bSSimon Glass 		hose->ctlr = parent_hose->bus;
749ff3e077bSSimon Glass 	}
750ff3e077bSSimon Glass 	hose->bus = bus;
751ff3e077bSSimon Glass 	hose->first_busno = bus->seq;
752ff3e077bSSimon Glass 	hose->last_busno = bus->seq;
753ff3e077bSSimon Glass 
754ff3e077bSSimon Glass 	return 0;
755ff3e077bSSimon Glass }
756ff3e077bSSimon Glass 
757ff3e077bSSimon Glass static int pci_uclass_post_probe(struct udevice *bus)
758ff3e077bSSimon Glass {
759ff3e077bSSimon Glass 	int ret;
760ff3e077bSSimon Glass 
761ff3e077bSSimon Glass 	debug("%s: probing bus %d\n", __func__, bus->seq);
762ff3e077bSSimon Glass 	ret = pci_bind_bus_devices(bus);
763ff3e077bSSimon Glass 	if (ret)
764ff3e077bSSimon Glass 		return ret;
765ff3e077bSSimon Glass 
766ff3e077bSSimon Glass #ifdef CONFIG_PCI_PNP
767ff3e077bSSimon Glass 	ret = pci_auto_config_devices(bus);
7684d21455eSSimon Glass 	if (ret < 0)
7694d21455eSSimon Glass 		return ret;
770ff3e077bSSimon Glass #endif
771ff3e077bSSimon Glass 
772348b744bSBin Meng #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
773348b744bSBin Meng 	/*
774348b744bSBin Meng 	 * Per Intel FSP specification, we should call FSP notify API to
775348b744bSBin Meng 	 * inform FSP that PCI enumeration has been done so that FSP will
776348b744bSBin Meng 	 * do any necessary initialization as required by the chipset's
777348b744bSBin Meng 	 * BIOS Writer's Guide (BWG).
778348b744bSBin Meng 	 *
779348b744bSBin Meng 	 * Unfortunately we have to put this call here as with driver model,
780348b744bSBin Meng 	 * the enumeration is all done on a lazy basis as needed, so until
781348b744bSBin Meng 	 * something is touched on PCI it won't happen.
782348b744bSBin Meng 	 *
783348b744bSBin Meng 	 * Note we only call this 1) after U-Boot is relocated, and 2)
784348b744bSBin Meng 	 * root bus has finished probing.
785348b744bSBin Meng 	 */
7864d21455eSSimon Glass 	if ((gd->flags & GD_FLG_RELOC) && (bus->seq == 0)) {
787348b744bSBin Meng 		ret = fsp_init_phase_pci();
7884d21455eSSimon Glass 		if (ret)
7894d21455eSSimon Glass 			return ret;
7904d21455eSSimon Glass 	}
791348b744bSBin Meng #endif
792348b744bSBin Meng 
7934d21455eSSimon Glass 	return 0;
794ff3e077bSSimon Glass }
795ff3e077bSSimon Glass 
796ff3e077bSSimon Glass static int pci_uclass_child_post_bind(struct udevice *dev)
797ff3e077bSSimon Glass {
798ff3e077bSSimon Glass 	struct pci_child_platdata *pplat;
799ff3e077bSSimon Glass 	struct fdt_pci_addr addr;
800ff3e077bSSimon Glass 	int ret;
801ff3e077bSSimon Glass 
802ff3e077bSSimon Glass 	if (dev->of_offset == -1)
803ff3e077bSSimon Glass 		return 0;
804ff3e077bSSimon Glass 
805ff3e077bSSimon Glass 	/*
806ff3e077bSSimon Glass 	 * We could read vendor, device, class if available. But for now we
807ff3e077bSSimon Glass 	 * just check the address.
808ff3e077bSSimon Glass 	 */
809ff3e077bSSimon Glass 	pplat = dev_get_parent_platdata(dev);
810ff3e077bSSimon Glass 	ret = fdtdec_get_pci_addr(gd->fdt_blob, dev->of_offset,
811ff3e077bSSimon Glass 				  FDT_PCI_SPACE_CONFIG, "reg", &addr);
812ff3e077bSSimon Glass 
813ff3e077bSSimon Glass 	if (ret) {
814ff3e077bSSimon Glass 		if (ret != -ENOENT)
815ff3e077bSSimon Glass 			return -EINVAL;
816ff3e077bSSimon Glass 	} else {
817dce54dd6SBin Meng 		/* extract the devfn from fdt_pci_addr */
818dce54dd6SBin Meng 		pplat->devfn = addr.phys_hi & 0xff00;
819ff3e077bSSimon Glass 	}
820ff3e077bSSimon Glass 
821ff3e077bSSimon Glass 	return 0;
822ff3e077bSSimon Glass }
823ff3e077bSSimon Glass 
8244d8615cbSBin Meng static int pci_bridge_read_config(struct udevice *bus, pci_dev_t bdf,
8254d8615cbSBin Meng 				  uint offset, ulong *valuep,
8264d8615cbSBin Meng 				  enum pci_size_t size)
827ff3e077bSSimon Glass {
828ff3e077bSSimon Glass 	struct pci_controller *hose = bus->uclass_priv;
829ff3e077bSSimon Glass 
830ff3e077bSSimon Glass 	return pci_bus_read_config(hose->ctlr, bdf, offset, valuep, size);
831ff3e077bSSimon Glass }
832ff3e077bSSimon Glass 
8334d8615cbSBin Meng static int pci_bridge_write_config(struct udevice *bus, pci_dev_t bdf,
8344d8615cbSBin Meng 				   uint offset, ulong value,
8354d8615cbSBin Meng 				   enum pci_size_t size)
836ff3e077bSSimon Glass {
837ff3e077bSSimon Glass 	struct pci_controller *hose = bus->uclass_priv;
838ff3e077bSSimon Glass 
839ff3e077bSSimon Glass 	return pci_bus_write_config(hose->ctlr, bdf, offset, value, size);
840ff3e077bSSimon Glass }
841ff3e077bSSimon Glass 
84276c3fbcdSSimon Glass static int skip_to_next_device(struct udevice *bus, struct udevice **devp)
84376c3fbcdSSimon Glass {
84476c3fbcdSSimon Glass 	struct udevice *dev;
84576c3fbcdSSimon Glass 	int ret = 0;
84676c3fbcdSSimon Glass 
84776c3fbcdSSimon Glass 	/*
84876c3fbcdSSimon Glass 	 * Scan through all the PCI controllers. On x86 there will only be one
84976c3fbcdSSimon Glass 	 * but that is not necessarily true on other hardware.
85076c3fbcdSSimon Glass 	 */
85176c3fbcdSSimon Glass 	do {
85276c3fbcdSSimon Glass 		device_find_first_child(bus, &dev);
85376c3fbcdSSimon Glass 		if (dev) {
85476c3fbcdSSimon Glass 			*devp = dev;
85576c3fbcdSSimon Glass 			return 0;
85676c3fbcdSSimon Glass 		}
85776c3fbcdSSimon Glass 		ret = uclass_next_device(&bus);
85876c3fbcdSSimon Glass 		if (ret)
85976c3fbcdSSimon Glass 			return ret;
86076c3fbcdSSimon Glass 	} while (bus);
86176c3fbcdSSimon Glass 
86276c3fbcdSSimon Glass 	return 0;
86376c3fbcdSSimon Glass }
86476c3fbcdSSimon Glass 
86576c3fbcdSSimon Glass int pci_find_next_device(struct udevice **devp)
86676c3fbcdSSimon Glass {
86776c3fbcdSSimon Glass 	struct udevice *child = *devp;
86876c3fbcdSSimon Glass 	struct udevice *bus = child->parent;
86976c3fbcdSSimon Glass 	int ret;
87076c3fbcdSSimon Glass 
87176c3fbcdSSimon Glass 	/* First try all the siblings */
87276c3fbcdSSimon Glass 	*devp = NULL;
87376c3fbcdSSimon Glass 	while (child) {
87476c3fbcdSSimon Glass 		device_find_next_child(&child);
87576c3fbcdSSimon Glass 		if (child) {
87676c3fbcdSSimon Glass 			*devp = child;
87776c3fbcdSSimon Glass 			return 0;
87876c3fbcdSSimon Glass 		}
87976c3fbcdSSimon Glass 	}
88076c3fbcdSSimon Glass 
88176c3fbcdSSimon Glass 	/* We ran out of siblings. Try the next bus */
88276c3fbcdSSimon Glass 	ret = uclass_next_device(&bus);
88376c3fbcdSSimon Glass 	if (ret)
88476c3fbcdSSimon Glass 		return ret;
88576c3fbcdSSimon Glass 
88676c3fbcdSSimon Glass 	return bus ? skip_to_next_device(bus, devp) : 0;
88776c3fbcdSSimon Glass }
88876c3fbcdSSimon Glass 
88976c3fbcdSSimon Glass int pci_find_first_device(struct udevice **devp)
89076c3fbcdSSimon Glass {
89176c3fbcdSSimon Glass 	struct udevice *bus;
89276c3fbcdSSimon Glass 	int ret;
89376c3fbcdSSimon Glass 
89476c3fbcdSSimon Glass 	*devp = NULL;
89576c3fbcdSSimon Glass 	ret = uclass_first_device(UCLASS_PCI, &bus);
89676c3fbcdSSimon Glass 	if (ret)
89776c3fbcdSSimon Glass 		return ret;
89876c3fbcdSSimon Glass 
89976c3fbcdSSimon Glass 	return skip_to_next_device(bus, devp);
90076c3fbcdSSimon Glass }
90176c3fbcdSSimon Glass 
902ff3e077bSSimon Glass UCLASS_DRIVER(pci) = {
903ff3e077bSSimon Glass 	.id		= UCLASS_PCI,
904ff3e077bSSimon Glass 	.name		= "pci",
9052bb02e4fSSimon Glass 	.flags		= DM_UC_FLAG_SEQ_ALIAS,
906ff3e077bSSimon Glass 	.post_bind	= pci_uclass_post_bind,
907ff3e077bSSimon Glass 	.pre_probe	= pci_uclass_pre_probe,
908ff3e077bSSimon Glass 	.post_probe	= pci_uclass_post_probe,
909ff3e077bSSimon Glass 	.child_post_bind = pci_uclass_child_post_bind,
910ff3e077bSSimon Glass 	.per_device_auto_alloc_size = sizeof(struct pci_controller),
911ff3e077bSSimon Glass 	.per_child_platdata_auto_alloc_size =
912ff3e077bSSimon Glass 			sizeof(struct pci_child_platdata),
913ff3e077bSSimon Glass };
914ff3e077bSSimon Glass 
915ff3e077bSSimon Glass static const struct dm_pci_ops pci_bridge_ops = {
916ff3e077bSSimon Glass 	.read_config	= pci_bridge_read_config,
917ff3e077bSSimon Glass 	.write_config	= pci_bridge_write_config,
918ff3e077bSSimon Glass };
919ff3e077bSSimon Glass 
920ff3e077bSSimon Glass static const struct udevice_id pci_bridge_ids[] = {
921ff3e077bSSimon Glass 	{ .compatible = "pci-bridge" },
922ff3e077bSSimon Glass 	{ }
923ff3e077bSSimon Glass };
924ff3e077bSSimon Glass 
925ff3e077bSSimon Glass U_BOOT_DRIVER(pci_bridge_drv) = {
926ff3e077bSSimon Glass 	.name		= "pci_bridge_drv",
927ff3e077bSSimon Glass 	.id		= UCLASS_PCI,
928ff3e077bSSimon Glass 	.of_match	= pci_bridge_ids,
929ff3e077bSSimon Glass 	.ops		= &pci_bridge_ops,
930ff3e077bSSimon Glass };
931ff3e077bSSimon Glass 
932ff3e077bSSimon Glass UCLASS_DRIVER(pci_generic) = {
933ff3e077bSSimon Glass 	.id		= UCLASS_PCI_GENERIC,
934ff3e077bSSimon Glass 	.name		= "pci_generic",
935ff3e077bSSimon Glass };
936ff3e077bSSimon Glass 
937ff3e077bSSimon Glass static const struct udevice_id pci_generic_ids[] = {
938ff3e077bSSimon Glass 	{ .compatible = "pci-generic" },
939ff3e077bSSimon Glass 	{ }
940ff3e077bSSimon Glass };
941ff3e077bSSimon Glass 
942ff3e077bSSimon Glass U_BOOT_DRIVER(pci_generic_drv) = {
943ff3e077bSSimon Glass 	.name		= "pci_generic_drv",
944ff3e077bSSimon Glass 	.id		= UCLASS_PCI_GENERIC,
945ff3e077bSSimon Glass 	.of_match	= pci_generic_ids,
946ff3e077bSSimon Glass };
947