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> 17ff3e077bSSimon Glass 18ff3e077bSSimon Glass DECLARE_GLOBAL_DATA_PTR; 19ff3e077bSSimon Glass 20ff3e077bSSimon Glass struct pci_controller *pci_bus_to_hose(int busnum) 21ff3e077bSSimon Glass { 22ff3e077bSSimon Glass struct udevice *bus; 23ff3e077bSSimon Glass int ret; 24ff3e077bSSimon Glass 25ff3e077bSSimon Glass ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus); 26ff3e077bSSimon Glass if (ret) { 27ff3e077bSSimon Glass debug("%s: Cannot get bus %d: ret=%d\n", __func__, busnum, ret); 28ff3e077bSSimon Glass return NULL; 29ff3e077bSSimon Glass } 30ff3e077bSSimon Glass return dev_get_uclass_priv(bus); 31ff3e077bSSimon Glass } 32ff3e077bSSimon Glass 334b515e4fSSimon Glass pci_dev_t pci_get_bdf(struct udevice *dev) 344b515e4fSSimon Glass { 354b515e4fSSimon Glass struct pci_child_platdata *pplat = dev_get_parent_platdata(dev); 364b515e4fSSimon Glass struct udevice *bus = dev->parent; 374b515e4fSSimon Glass 384b515e4fSSimon Glass return PCI_ADD_BUS(bus->seq, pplat->devfn); 394b515e4fSSimon Glass } 404b515e4fSSimon Glass 41ff3e077bSSimon Glass /** 42ff3e077bSSimon Glass * pci_get_bus_max() - returns the bus number of the last active bus 43ff3e077bSSimon Glass * 44ff3e077bSSimon Glass * @return last bus number, or -1 if no active buses 45ff3e077bSSimon Glass */ 46ff3e077bSSimon Glass static int pci_get_bus_max(void) 47ff3e077bSSimon Glass { 48ff3e077bSSimon Glass struct udevice *bus; 49ff3e077bSSimon Glass struct uclass *uc; 50ff3e077bSSimon Glass int ret = -1; 51ff3e077bSSimon Glass 52ff3e077bSSimon Glass ret = uclass_get(UCLASS_PCI, &uc); 53ff3e077bSSimon Glass uclass_foreach_dev(bus, uc) { 54ff3e077bSSimon Glass if (bus->seq > ret) 55ff3e077bSSimon Glass ret = bus->seq; 56ff3e077bSSimon Glass } 57ff3e077bSSimon Glass 58ff3e077bSSimon Glass debug("%s: ret=%d\n", __func__, ret); 59ff3e077bSSimon Glass 60ff3e077bSSimon Glass return ret; 61ff3e077bSSimon Glass } 62ff3e077bSSimon Glass 63ff3e077bSSimon Glass int pci_last_busno(void) 64ff3e077bSSimon Glass { 65ff3e077bSSimon Glass struct pci_controller *hose; 66ff3e077bSSimon Glass struct udevice *bus; 67ff3e077bSSimon Glass struct uclass *uc; 68ff3e077bSSimon Glass int ret; 69ff3e077bSSimon Glass 70ff3e077bSSimon Glass debug("pci_last_busno\n"); 71ff3e077bSSimon Glass ret = uclass_get(UCLASS_PCI, &uc); 72ff3e077bSSimon Glass if (ret || list_empty(&uc->dev_head)) 73ff3e077bSSimon Glass return -1; 74ff3e077bSSimon Glass 75ff3e077bSSimon Glass /* Probe the last bus */ 76ff3e077bSSimon Glass bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node); 77ff3e077bSSimon Glass debug("bus = %p, %s\n", bus, bus->name); 78ff3e077bSSimon Glass assert(bus); 79ff3e077bSSimon Glass ret = device_probe(bus); 80ff3e077bSSimon Glass if (ret) 81ff3e077bSSimon Glass return ret; 82ff3e077bSSimon Glass 83ff3e077bSSimon Glass /* If that bus has bridges, we may have new buses now. Get the last */ 84ff3e077bSSimon Glass bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node); 85ff3e077bSSimon Glass hose = dev_get_uclass_priv(bus); 86ff3e077bSSimon Glass debug("bus = %s, hose = %p\n", bus->name, hose); 87ff3e077bSSimon Glass 88ff3e077bSSimon Glass return hose->last_busno; 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 128ff3e077bSSimon Glass ret = uclass_get_device_by_seq(UCLASS_PCI, 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 206ff3e077bSSimon Glass ret = uclass_get_device_by_seq(UCLASS_PCI, 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 21866afb4edSSimon Glass for (bus = dev; device_get_uclass_id(bus->parent) == UCLASS_PCI;) 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 271ff3e077bSSimon Glass ret = uclass_get_device_by_seq(UCLASS_PCI, 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 28366afb4edSSimon Glass for (bus = dev; device_get_uclass_id(bus->parent) == UCLASS_PCI;) 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; 381ff3e077bSSimon Glass 382ff3e077bSSimon Glass debug("%s: device %s\n", __func__, dev->name); 383d11d9ef1SBin Meng max_bus = pciauto_config_device(hose, pci_get_bdf(dev)); 384ff3e077bSSimon Glass sub_bus = max(sub_bus, max_bus); 385ff3e077bSSimon Glass } 386ff3e077bSSimon Glass debug("%s: done\n", __func__); 387ff3e077bSSimon Glass 388ff3e077bSSimon Glass return sub_bus; 389ff3e077bSSimon Glass } 390ff3e077bSSimon Glass 391ff3e077bSSimon Glass int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf) 392ff3e077bSSimon Glass { 393ff3e077bSSimon Glass struct udevice *parent, *bus; 394ff3e077bSSimon Glass int sub_bus; 395ff3e077bSSimon Glass int ret; 396ff3e077bSSimon Glass 397ff3e077bSSimon Glass debug("%s\n", __func__); 398ff3e077bSSimon Glass parent = hose->bus; 399ff3e077bSSimon Glass 400ff3e077bSSimon Glass /* Find the bus within the parent */ 4018326f136SBin Meng ret = pci_bus_find_devfn(parent, PCI_MASK_BUS(bdf), &bus); 402ff3e077bSSimon Glass if (ret) { 403ff3e077bSSimon Glass debug("%s: Cannot find device %x on bus %s: %d\n", __func__, 404ff3e077bSSimon Glass bdf, parent->name, ret); 405ff3e077bSSimon Glass return ret; 406ff3e077bSSimon Glass } 407ff3e077bSSimon Glass 408ff3e077bSSimon Glass sub_bus = pci_get_bus_max() + 1; 409ff3e077bSSimon Glass debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name); 4105afeb4bbSSimon Glass pciauto_prescan_setup_bridge(hose, bdf, sub_bus); 411ff3e077bSSimon Glass 412ff3e077bSSimon Glass ret = device_probe(bus); 413ff3e077bSSimon Glass if (ret) { 414ff3e077bSSimon Glass debug("%s: Cannot probe bus bus %s: %d\n", __func__, bus->name, 415ff3e077bSSimon Glass ret); 416ff3e077bSSimon Glass return ret; 417ff3e077bSSimon Glass } 418ff3e077bSSimon Glass if (sub_bus != bus->seq) { 419ff3e077bSSimon Glass printf("%s: Internal error, bus '%s' got seq %d, expected %d\n", 420ff3e077bSSimon Glass __func__, bus->name, bus->seq, sub_bus); 421ff3e077bSSimon Glass return -EPIPE; 422ff3e077bSSimon Glass } 423ff3e077bSSimon Glass sub_bus = pci_get_bus_max(); 424ff3e077bSSimon Glass pciauto_postscan_setup_bridge(hose, bdf, sub_bus); 425ff3e077bSSimon Glass 426ff3e077bSSimon Glass return sub_bus; 427ff3e077bSSimon Glass } 428ff3e077bSSimon Glass 429aba92962SSimon Glass /** 430aba92962SSimon Glass * pci_match_one_device - Tell if a PCI device structure has a matching 431aba92962SSimon Glass * PCI device id structure 432aba92962SSimon Glass * @id: single PCI device id structure to match 433aba92962SSimon Glass * @dev: the PCI device structure to match against 434aba92962SSimon Glass * 435aba92962SSimon Glass * Returns the matching pci_device_id structure or %NULL if there is no match. 436aba92962SSimon Glass */ 437aba92962SSimon Glass static bool pci_match_one_id(const struct pci_device_id *id, 438aba92962SSimon Glass const struct pci_device_id *find) 439aba92962SSimon Glass { 440aba92962SSimon Glass if ((id->vendor == PCI_ANY_ID || id->vendor == find->vendor) && 441aba92962SSimon Glass (id->device == PCI_ANY_ID || id->device == find->device) && 442aba92962SSimon Glass (id->subvendor == PCI_ANY_ID || id->subvendor == find->subvendor) && 443aba92962SSimon Glass (id->subdevice == PCI_ANY_ID || id->subdevice == find->subdevice) && 444aba92962SSimon Glass !((id->class ^ find->class) & id->class_mask)) 445aba92962SSimon Glass return true; 446aba92962SSimon Glass 447aba92962SSimon Glass return false; 448aba92962SSimon Glass } 449aba92962SSimon Glass 450aba92962SSimon Glass /** 451aba92962SSimon Glass * pci_find_and_bind_driver() - Find and bind the right PCI driver 452aba92962SSimon Glass * 453aba92962SSimon Glass * This only looks at certain fields in the descriptor. 454aba92962SSimon Glass */ 455aba92962SSimon Glass static int pci_find_and_bind_driver(struct udevice *parent, 4564d8615cbSBin Meng struct pci_device_id *find_id, pci_dev_t bdf, 457aba92962SSimon Glass struct udevice **devp) 458aba92962SSimon Glass { 459aba92962SSimon Glass struct pci_driver_entry *start, *entry; 460aba92962SSimon Glass const char *drv; 461aba92962SSimon Glass int n_ents; 462aba92962SSimon Glass int ret; 463aba92962SSimon Glass char name[30], *str; 464aba92962SSimon Glass 465aba92962SSimon Glass *devp = NULL; 466aba92962SSimon Glass 467aba92962SSimon Glass debug("%s: Searching for driver: vendor=%x, device=%x\n", __func__, 468aba92962SSimon Glass find_id->vendor, find_id->device); 469aba92962SSimon Glass start = ll_entry_start(struct pci_driver_entry, pci_driver_entry); 470aba92962SSimon Glass n_ents = ll_entry_count(struct pci_driver_entry, pci_driver_entry); 471aba92962SSimon Glass for (entry = start; entry != start + n_ents; entry++) { 472aba92962SSimon Glass const struct pci_device_id *id; 473aba92962SSimon Glass struct udevice *dev; 474aba92962SSimon Glass const struct driver *drv; 475aba92962SSimon Glass 476aba92962SSimon Glass for (id = entry->match; 477aba92962SSimon Glass id->vendor || id->subvendor || id->class_mask; 478aba92962SSimon Glass id++) { 479aba92962SSimon Glass if (!pci_match_one_id(id, find_id)) 480aba92962SSimon Glass continue; 481aba92962SSimon Glass 482aba92962SSimon Glass drv = entry->driver; 483aba92962SSimon Glass /* 484aba92962SSimon Glass * We could pass the descriptor to the driver as 485aba92962SSimon Glass * platdata (instead of NULL) and allow its bind() 486aba92962SSimon Glass * method to return -ENOENT if it doesn't support this 487aba92962SSimon Glass * device. That way we could continue the search to 488aba92962SSimon Glass * find another driver. For now this doesn't seem 489aba92962SSimon Glass * necesssary, so just bind the first match. 490aba92962SSimon Glass */ 491aba92962SSimon Glass ret = device_bind(parent, drv, drv->name, NULL, -1, 492aba92962SSimon Glass &dev); 493aba92962SSimon Glass if (ret) 494aba92962SSimon Glass goto error; 495aba92962SSimon Glass debug("%s: Match found: %s\n", __func__, drv->name); 496aba92962SSimon Glass dev->driver_data = find_id->driver_data; 497aba92962SSimon Glass *devp = dev; 498aba92962SSimon Glass return 0; 499aba92962SSimon Glass } 500aba92962SSimon Glass } 501aba92962SSimon Glass 502aba92962SSimon Glass /* Bind a generic driver so that the device can be used */ 5034d8615cbSBin Meng sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf), 5044d8615cbSBin Meng PCI_FUNC(bdf)); 505aba92962SSimon Glass str = strdup(name); 506aba92962SSimon Glass if (!str) 507aba92962SSimon Glass return -ENOMEM; 508aba92962SSimon Glass drv = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI ? "pci_bridge_drv" : 509aba92962SSimon Glass "pci_generic_drv"; 510aba92962SSimon Glass ret = device_bind_driver(parent, drv, str, devp); 511aba92962SSimon Glass if (ret) { 512aba92962SSimon Glass debug("%s: Failed to bind generic driver: %d", __func__, ret); 513aba92962SSimon Glass return ret; 514aba92962SSimon Glass } 515aba92962SSimon Glass debug("%s: No match found: bound generic driver instead\n", __func__); 516aba92962SSimon Glass 517aba92962SSimon Glass return 0; 518aba92962SSimon Glass 519aba92962SSimon Glass error: 520aba92962SSimon Glass debug("%s: No match found: error %d\n", __func__, ret); 521aba92962SSimon Glass return ret; 522aba92962SSimon Glass } 523aba92962SSimon Glass 524ff3e077bSSimon Glass int pci_bind_bus_devices(struct udevice *bus) 525ff3e077bSSimon Glass { 526ff3e077bSSimon Glass ulong vendor, device; 527ff3e077bSSimon Glass ulong header_type; 5284d8615cbSBin Meng pci_dev_t bdf, end; 529ff3e077bSSimon Glass bool found_multi; 530ff3e077bSSimon Glass int ret; 531ff3e077bSSimon Glass 532ff3e077bSSimon Glass found_multi = false; 5334d8615cbSBin Meng end = PCI_BDF(bus->seq, PCI_MAX_PCI_DEVICES - 1, 5344d8615cbSBin Meng PCI_MAX_PCI_FUNCTIONS - 1); 5354d8615cbSBin Meng for (bdf = PCI_BDF(bus->seq, 0, 0); bdf < end; 5364d8615cbSBin Meng bdf += PCI_BDF(0, 0, 1)) { 537ff3e077bSSimon Glass struct pci_child_platdata *pplat; 538ff3e077bSSimon Glass struct udevice *dev; 539ff3e077bSSimon Glass ulong class; 540ff3e077bSSimon Glass 5414d8615cbSBin Meng if (PCI_FUNC(bdf) && !found_multi) 542ff3e077bSSimon Glass continue; 543ff3e077bSSimon Glass /* Check only the first access, we don't expect problems */ 5444d8615cbSBin Meng ret = pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE, 545ff3e077bSSimon Glass &header_type, PCI_SIZE_8); 546ff3e077bSSimon Glass if (ret) 547ff3e077bSSimon Glass goto error; 5484d8615cbSBin Meng pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor, 549ff3e077bSSimon Glass PCI_SIZE_16); 550ff3e077bSSimon Glass if (vendor == 0xffff || vendor == 0x0000) 551ff3e077bSSimon Glass continue; 552ff3e077bSSimon Glass 5534d8615cbSBin Meng if (!PCI_FUNC(bdf)) 554ff3e077bSSimon Glass found_multi = header_type & 0x80; 555ff3e077bSSimon Glass 556ff3e077bSSimon Glass debug("%s: bus %d/%s: found device %x, function %d\n", __func__, 5574d8615cbSBin Meng bus->seq, bus->name, PCI_DEV(bdf), PCI_FUNC(bdf)); 5584d8615cbSBin Meng pci_bus_read_config(bus, bdf, PCI_DEVICE_ID, &device, 559ff3e077bSSimon Glass PCI_SIZE_16); 5604d8615cbSBin Meng pci_bus_read_config(bus, bdf, PCI_CLASS_REVISION, &class, 561aba92962SSimon Glass PCI_SIZE_32); 562aba92962SSimon Glass class >>= 8; 563ff3e077bSSimon Glass 564ff3e077bSSimon Glass /* Find this device in the device tree */ 5654d8615cbSBin Meng ret = pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), &dev); 566ff3e077bSSimon Glass 567aba92962SSimon Glass /* Search for a driver */ 568aba92962SSimon Glass 569ff3e077bSSimon Glass /* If nothing in the device tree, bind a generic device */ 570ff3e077bSSimon Glass if (ret == -ENODEV) { 571aba92962SSimon Glass struct pci_device_id find_id; 572aba92962SSimon Glass ulong val; 573ff3e077bSSimon Glass 574aba92962SSimon Glass memset(&find_id, '\0', sizeof(find_id)); 575aba92962SSimon Glass find_id.vendor = vendor; 576aba92962SSimon Glass find_id.device = device; 577aba92962SSimon Glass find_id.class = class; 578aba92962SSimon Glass if ((header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL) { 5794d8615cbSBin Meng pci_bus_read_config(bus, bdf, 580aba92962SSimon Glass PCI_SUBSYSTEM_VENDOR_ID, 581aba92962SSimon Glass &val, PCI_SIZE_32); 582aba92962SSimon Glass find_id.subvendor = val & 0xffff; 583aba92962SSimon Glass find_id.subdevice = val >> 16; 584aba92962SSimon Glass } 5854d8615cbSBin Meng ret = pci_find_and_bind_driver(bus, &find_id, bdf, 586aba92962SSimon Glass &dev); 587ff3e077bSSimon Glass } 588ff3e077bSSimon Glass if (ret) 589ff3e077bSSimon Glass return ret; 590ff3e077bSSimon Glass 591ff3e077bSSimon Glass /* Update the platform data */ 592ff3e077bSSimon Glass pplat = dev_get_parent_platdata(dev); 5934d8615cbSBin Meng pplat->devfn = PCI_MASK_BUS(bdf); 594ff3e077bSSimon Glass pplat->vendor = vendor; 595ff3e077bSSimon Glass pplat->device = device; 596ff3e077bSSimon Glass pplat->class = class; 597ff3e077bSSimon Glass } 598ff3e077bSSimon Glass 599ff3e077bSSimon Glass return 0; 600ff3e077bSSimon Glass error: 601ff3e077bSSimon Glass printf("Cannot read bus configuration: %d\n", ret); 602ff3e077bSSimon Glass 603ff3e077bSSimon Glass return ret; 604ff3e077bSSimon Glass } 605ff3e077bSSimon Glass 606ff3e077bSSimon Glass static int pci_uclass_post_bind(struct udevice *bus) 607ff3e077bSSimon Glass { 608ff3e077bSSimon Glass /* 609ff3e077bSSimon Glass * Scan the device tree for devices. This does not probe the PCI bus, 610ff3e077bSSimon Glass * as this is not permitted while binding. It just finds devices 611ff3e077bSSimon Glass * mentioned in the device tree. 612ff3e077bSSimon Glass * 613ff3e077bSSimon Glass * Before relocation, only bind devices marked for pre-relocation 614ff3e077bSSimon Glass * use. 615ff3e077bSSimon Glass */ 616ff3e077bSSimon Glass return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset, 617ff3e077bSSimon Glass gd->flags & GD_FLG_RELOC ? false : true); 618ff3e077bSSimon Glass } 619ff3e077bSSimon Glass 620ff3e077bSSimon Glass static int decode_regions(struct pci_controller *hose, const void *blob, 621ff3e077bSSimon Glass int parent_node, int node) 622ff3e077bSSimon Glass { 623ff3e077bSSimon Glass int pci_addr_cells, addr_cells, size_cells; 624ff3e077bSSimon Glass int cells_per_record; 625b9da5086SSimon Glass phys_addr_t addr; 626ff3e077bSSimon Glass const u32 *prop; 627ff3e077bSSimon Glass int len; 628ff3e077bSSimon Glass int i; 629ff3e077bSSimon Glass 630ff3e077bSSimon Glass prop = fdt_getprop(blob, node, "ranges", &len); 631ff3e077bSSimon Glass if (!prop) 632ff3e077bSSimon Glass return -EINVAL; 633ff3e077bSSimon Glass pci_addr_cells = fdt_address_cells(blob, node); 634ff3e077bSSimon Glass addr_cells = fdt_address_cells(blob, parent_node); 635ff3e077bSSimon Glass size_cells = fdt_size_cells(blob, node); 636ff3e077bSSimon Glass 637ff3e077bSSimon Glass /* PCI addresses are always 3-cells */ 638ff3e077bSSimon Glass len /= sizeof(u32); 639ff3e077bSSimon Glass cells_per_record = pci_addr_cells + addr_cells + size_cells; 640ff3e077bSSimon Glass hose->region_count = 0; 641ff3e077bSSimon Glass debug("%s: len=%d, cells_per_record=%d\n", __func__, len, 642ff3e077bSSimon Glass cells_per_record); 643ff3e077bSSimon Glass for (i = 0; i < MAX_PCI_REGIONS; i++, len -= cells_per_record) { 644ff3e077bSSimon Glass u64 pci_addr, addr, size; 645ff3e077bSSimon Glass int space_code; 646ff3e077bSSimon Glass u32 flags; 647ff3e077bSSimon Glass int type; 648ff3e077bSSimon Glass 649ff3e077bSSimon Glass if (len < cells_per_record) 650ff3e077bSSimon Glass break; 651ff3e077bSSimon Glass flags = fdt32_to_cpu(prop[0]); 652ff3e077bSSimon Glass space_code = (flags >> 24) & 3; 653ff3e077bSSimon Glass pci_addr = fdtdec_get_number(prop + 1, 2); 654ff3e077bSSimon Glass prop += pci_addr_cells; 655ff3e077bSSimon Glass addr = fdtdec_get_number(prop, addr_cells); 656ff3e077bSSimon Glass prop += addr_cells; 657ff3e077bSSimon Glass size = fdtdec_get_number(prop, size_cells); 658ff3e077bSSimon Glass prop += size_cells; 659ff3e077bSSimon Glass debug("%s: region %d, pci_addr=%" PRIx64 ", addr=%" PRIx64 660ff3e077bSSimon Glass ", size=%" PRIx64 ", space_code=%d\n", __func__, 661ff3e077bSSimon Glass hose->region_count, pci_addr, addr, size, space_code); 662ff3e077bSSimon Glass if (space_code & 2) { 663ff3e077bSSimon Glass type = flags & (1U << 30) ? PCI_REGION_PREFETCH : 664ff3e077bSSimon Glass PCI_REGION_MEM; 665ff3e077bSSimon Glass } else if (space_code & 1) { 666ff3e077bSSimon Glass type = PCI_REGION_IO; 667ff3e077bSSimon Glass } else { 668ff3e077bSSimon Glass continue; 669ff3e077bSSimon Glass } 670ff3e077bSSimon Glass debug(" - type=%d\n", type); 671ff3e077bSSimon Glass pci_set_region(hose->regions + hose->region_count++, pci_addr, 672ff3e077bSSimon Glass addr, size, type); 673ff3e077bSSimon Glass } 674ff3e077bSSimon Glass 675ff3e077bSSimon Glass /* Add a region for our local memory */ 676b9da5086SSimon Glass addr = gd->ram_size; 677b9da5086SSimon Glass if (gd->pci_ram_top && gd->pci_ram_top < addr) 678b9da5086SSimon Glass addr = gd->pci_ram_top; 679b9da5086SSimon Glass pci_set_region(hose->regions + hose->region_count++, 0, 0, addr, 680b9da5086SSimon Glass PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); 681ff3e077bSSimon Glass 682ff3e077bSSimon Glass return 0; 683ff3e077bSSimon Glass } 684ff3e077bSSimon Glass 685ff3e077bSSimon Glass static int pci_uclass_pre_probe(struct udevice *bus) 686ff3e077bSSimon Glass { 687ff3e077bSSimon Glass struct pci_controller *hose; 688ff3e077bSSimon Glass int ret; 689ff3e077bSSimon Glass 690ff3e077bSSimon Glass debug("%s, bus=%d/%s, parent=%s\n", __func__, bus->seq, bus->name, 691ff3e077bSSimon Glass bus->parent->name); 692ff3e077bSSimon Glass hose = bus->uclass_priv; 693ff3e077bSSimon Glass 694ff3e077bSSimon Glass /* For bridges, use the top-level PCI controller */ 695ff3e077bSSimon Glass if (device_get_uclass_id(bus->parent) == UCLASS_ROOT) { 696ff3e077bSSimon Glass hose->ctlr = bus; 697ff3e077bSSimon Glass ret = decode_regions(hose, gd->fdt_blob, bus->parent->of_offset, 698ff3e077bSSimon Glass bus->of_offset); 699ff3e077bSSimon Glass if (ret) { 700ff3e077bSSimon Glass debug("%s: Cannot decode regions\n", __func__); 701ff3e077bSSimon Glass return ret; 702ff3e077bSSimon Glass } 703ff3e077bSSimon Glass } else { 704ff3e077bSSimon Glass struct pci_controller *parent_hose; 705ff3e077bSSimon Glass 706ff3e077bSSimon Glass parent_hose = dev_get_uclass_priv(bus->parent); 707ff3e077bSSimon Glass hose->ctlr = parent_hose->bus; 708ff3e077bSSimon Glass } 709ff3e077bSSimon Glass hose->bus = bus; 710ff3e077bSSimon Glass hose->first_busno = bus->seq; 711ff3e077bSSimon Glass hose->last_busno = bus->seq; 712ff3e077bSSimon Glass 713ff3e077bSSimon Glass return 0; 714ff3e077bSSimon Glass } 715ff3e077bSSimon Glass 716ff3e077bSSimon Glass static int pci_uclass_post_probe(struct udevice *bus) 717ff3e077bSSimon Glass { 718ff3e077bSSimon Glass int ret; 719ff3e077bSSimon Glass 720ff3e077bSSimon Glass debug("%s: probing bus %d\n", __func__, bus->seq); 721ff3e077bSSimon Glass ret = pci_bind_bus_devices(bus); 722ff3e077bSSimon Glass if (ret) 723ff3e077bSSimon Glass return ret; 724ff3e077bSSimon Glass 725ff3e077bSSimon Glass #ifdef CONFIG_PCI_PNP 726ff3e077bSSimon Glass ret = pci_auto_config_devices(bus); 727ff3e077bSSimon Glass #endif 728ff3e077bSSimon Glass 729ff3e077bSSimon Glass return ret < 0 ? ret : 0; 730ff3e077bSSimon Glass } 731ff3e077bSSimon Glass 732ff3e077bSSimon Glass static int pci_uclass_child_post_bind(struct udevice *dev) 733ff3e077bSSimon Glass { 734ff3e077bSSimon Glass struct pci_child_platdata *pplat; 735ff3e077bSSimon Glass struct fdt_pci_addr addr; 736ff3e077bSSimon Glass int ret; 737ff3e077bSSimon Glass 738ff3e077bSSimon Glass if (dev->of_offset == -1) 739ff3e077bSSimon Glass return 0; 740ff3e077bSSimon Glass 741ff3e077bSSimon Glass /* 742ff3e077bSSimon Glass * We could read vendor, device, class if available. But for now we 743ff3e077bSSimon Glass * just check the address. 744ff3e077bSSimon Glass */ 745ff3e077bSSimon Glass pplat = dev_get_parent_platdata(dev); 746ff3e077bSSimon Glass ret = fdtdec_get_pci_addr(gd->fdt_blob, dev->of_offset, 747ff3e077bSSimon Glass FDT_PCI_SPACE_CONFIG, "reg", &addr); 748ff3e077bSSimon Glass 749ff3e077bSSimon Glass if (ret) { 750ff3e077bSSimon Glass if (ret != -ENOENT) 751ff3e077bSSimon Glass return -EINVAL; 752ff3e077bSSimon Glass } else { 753ff3e077bSSimon Glass /* extract the bdf from fdt_pci_addr */ 754ff3e077bSSimon Glass pplat->devfn = addr.phys_hi & 0xffff00; 755ff3e077bSSimon Glass } 756ff3e077bSSimon Glass 757ff3e077bSSimon Glass return 0; 758ff3e077bSSimon Glass } 759ff3e077bSSimon Glass 7604d8615cbSBin Meng static int pci_bridge_read_config(struct udevice *bus, pci_dev_t bdf, 7614d8615cbSBin Meng uint offset, ulong *valuep, 7624d8615cbSBin Meng enum pci_size_t size) 763ff3e077bSSimon Glass { 764ff3e077bSSimon Glass struct pci_controller *hose = bus->uclass_priv; 765ff3e077bSSimon Glass 766ff3e077bSSimon Glass return pci_bus_read_config(hose->ctlr, bdf, offset, valuep, size); 767ff3e077bSSimon Glass } 768ff3e077bSSimon Glass 7694d8615cbSBin Meng static int pci_bridge_write_config(struct udevice *bus, pci_dev_t bdf, 7704d8615cbSBin Meng uint offset, ulong value, 7714d8615cbSBin Meng enum pci_size_t size) 772ff3e077bSSimon Glass { 773ff3e077bSSimon Glass struct pci_controller *hose = bus->uclass_priv; 774ff3e077bSSimon Glass 775ff3e077bSSimon Glass return pci_bus_write_config(hose->ctlr, bdf, offset, value, size); 776ff3e077bSSimon Glass } 777ff3e077bSSimon Glass 778*76c3fbcdSSimon Glass static int skip_to_next_device(struct udevice *bus, struct udevice **devp) 779*76c3fbcdSSimon Glass { 780*76c3fbcdSSimon Glass struct udevice *dev; 781*76c3fbcdSSimon Glass int ret = 0; 782*76c3fbcdSSimon Glass 783*76c3fbcdSSimon Glass /* 784*76c3fbcdSSimon Glass * Scan through all the PCI controllers. On x86 there will only be one 785*76c3fbcdSSimon Glass * but that is not necessarily true on other hardware. 786*76c3fbcdSSimon Glass */ 787*76c3fbcdSSimon Glass do { 788*76c3fbcdSSimon Glass device_find_first_child(bus, &dev); 789*76c3fbcdSSimon Glass if (dev) { 790*76c3fbcdSSimon Glass *devp = dev; 791*76c3fbcdSSimon Glass return 0; 792*76c3fbcdSSimon Glass } 793*76c3fbcdSSimon Glass ret = uclass_next_device(&bus); 794*76c3fbcdSSimon Glass if (ret) 795*76c3fbcdSSimon Glass return ret; 796*76c3fbcdSSimon Glass } while (bus); 797*76c3fbcdSSimon Glass 798*76c3fbcdSSimon Glass return 0; 799*76c3fbcdSSimon Glass } 800*76c3fbcdSSimon Glass 801*76c3fbcdSSimon Glass int pci_find_next_device(struct udevice **devp) 802*76c3fbcdSSimon Glass { 803*76c3fbcdSSimon Glass struct udevice *child = *devp; 804*76c3fbcdSSimon Glass struct udevice *bus = child->parent; 805*76c3fbcdSSimon Glass int ret; 806*76c3fbcdSSimon Glass 807*76c3fbcdSSimon Glass /* First try all the siblings */ 808*76c3fbcdSSimon Glass *devp = NULL; 809*76c3fbcdSSimon Glass while (child) { 810*76c3fbcdSSimon Glass device_find_next_child(&child); 811*76c3fbcdSSimon Glass if (child) { 812*76c3fbcdSSimon Glass *devp = child; 813*76c3fbcdSSimon Glass return 0; 814*76c3fbcdSSimon Glass } 815*76c3fbcdSSimon Glass } 816*76c3fbcdSSimon Glass 817*76c3fbcdSSimon Glass /* We ran out of siblings. Try the next bus */ 818*76c3fbcdSSimon Glass ret = uclass_next_device(&bus); 819*76c3fbcdSSimon Glass if (ret) 820*76c3fbcdSSimon Glass return ret; 821*76c3fbcdSSimon Glass 822*76c3fbcdSSimon Glass return bus ? skip_to_next_device(bus, devp) : 0; 823*76c3fbcdSSimon Glass } 824*76c3fbcdSSimon Glass 825*76c3fbcdSSimon Glass int pci_find_first_device(struct udevice **devp) 826*76c3fbcdSSimon Glass { 827*76c3fbcdSSimon Glass struct udevice *bus; 828*76c3fbcdSSimon Glass int ret; 829*76c3fbcdSSimon Glass 830*76c3fbcdSSimon Glass *devp = NULL; 831*76c3fbcdSSimon Glass ret = uclass_first_device(UCLASS_PCI, &bus); 832*76c3fbcdSSimon Glass if (ret) 833*76c3fbcdSSimon Glass return ret; 834*76c3fbcdSSimon Glass 835*76c3fbcdSSimon Glass return skip_to_next_device(bus, devp); 836*76c3fbcdSSimon Glass } 837*76c3fbcdSSimon Glass 838ff3e077bSSimon Glass UCLASS_DRIVER(pci) = { 839ff3e077bSSimon Glass .id = UCLASS_PCI, 840ff3e077bSSimon Glass .name = "pci", 8412bb02e4fSSimon Glass .flags = DM_UC_FLAG_SEQ_ALIAS, 842ff3e077bSSimon Glass .post_bind = pci_uclass_post_bind, 843ff3e077bSSimon Glass .pre_probe = pci_uclass_pre_probe, 844ff3e077bSSimon Glass .post_probe = pci_uclass_post_probe, 845ff3e077bSSimon Glass .child_post_bind = pci_uclass_child_post_bind, 846ff3e077bSSimon Glass .per_device_auto_alloc_size = sizeof(struct pci_controller), 847ff3e077bSSimon Glass .per_child_platdata_auto_alloc_size = 848ff3e077bSSimon Glass sizeof(struct pci_child_platdata), 849ff3e077bSSimon Glass }; 850ff3e077bSSimon Glass 851ff3e077bSSimon Glass static const struct dm_pci_ops pci_bridge_ops = { 852ff3e077bSSimon Glass .read_config = pci_bridge_read_config, 853ff3e077bSSimon Glass .write_config = pci_bridge_write_config, 854ff3e077bSSimon Glass }; 855ff3e077bSSimon Glass 856ff3e077bSSimon Glass static const struct udevice_id pci_bridge_ids[] = { 857ff3e077bSSimon Glass { .compatible = "pci-bridge" }, 858ff3e077bSSimon Glass { } 859ff3e077bSSimon Glass }; 860ff3e077bSSimon Glass 861ff3e077bSSimon Glass U_BOOT_DRIVER(pci_bridge_drv) = { 862ff3e077bSSimon Glass .name = "pci_bridge_drv", 863ff3e077bSSimon Glass .id = UCLASS_PCI, 864ff3e077bSSimon Glass .of_match = pci_bridge_ids, 865ff3e077bSSimon Glass .ops = &pci_bridge_ops, 866ff3e077bSSimon Glass }; 867ff3e077bSSimon Glass 868ff3e077bSSimon Glass UCLASS_DRIVER(pci_generic) = { 869ff3e077bSSimon Glass .id = UCLASS_PCI_GENERIC, 870ff3e077bSSimon Glass .name = "pci_generic", 871ff3e077bSSimon Glass }; 872ff3e077bSSimon Glass 873ff3e077bSSimon Glass static const struct udevice_id pci_generic_ids[] = { 874ff3e077bSSimon Glass { .compatible = "pci-generic" }, 875ff3e077bSSimon Glass { } 876ff3e077bSSimon Glass }; 877ff3e077bSSimon Glass 878ff3e077bSSimon Glass U_BOOT_DRIVER(pci_generic_drv) = { 879ff3e077bSSimon Glass .name = "pci_generic_drv", 880ff3e077bSSimon Glass .id = UCLASS_PCI_GENERIC, 881ff3e077bSSimon Glass .of_match = pci_generic_ids, 882ff3e077bSSimon Glass }; 883