1*ff3e077bSSimon Glass /* 2*ff3e077bSSimon Glass * Copyright (c) 2014 Google, Inc 3*ff3e077bSSimon Glass * Written by Simon Glass <sjg@chromium.org> 4*ff3e077bSSimon Glass * 5*ff3e077bSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 6*ff3e077bSSimon Glass */ 7*ff3e077bSSimon Glass 8*ff3e077bSSimon Glass #include <common.h> 9*ff3e077bSSimon Glass #include <dm.h> 10*ff3e077bSSimon Glass #include <errno.h> 11*ff3e077bSSimon Glass #include <fdtdec.h> 12*ff3e077bSSimon Glass #include <inttypes.h> 13*ff3e077bSSimon Glass #include <pci.h> 14*ff3e077bSSimon Glass #include <dm/lists.h> 15*ff3e077bSSimon Glass #include <dm/root.h> 16*ff3e077bSSimon Glass #include <dm/device-internal.h> 17*ff3e077bSSimon Glass 18*ff3e077bSSimon Glass DECLARE_GLOBAL_DATA_PTR; 19*ff3e077bSSimon Glass 20*ff3e077bSSimon Glass struct pci_controller *pci_bus_to_hose(int busnum) 21*ff3e077bSSimon Glass { 22*ff3e077bSSimon Glass struct udevice *bus; 23*ff3e077bSSimon Glass int ret; 24*ff3e077bSSimon Glass 25*ff3e077bSSimon Glass ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus); 26*ff3e077bSSimon Glass if (ret) { 27*ff3e077bSSimon Glass debug("%s: Cannot get bus %d: ret=%d\n", __func__, busnum, ret); 28*ff3e077bSSimon Glass return NULL; 29*ff3e077bSSimon Glass } 30*ff3e077bSSimon Glass return dev_get_uclass_priv(bus); 31*ff3e077bSSimon Glass } 32*ff3e077bSSimon Glass 33*ff3e077bSSimon Glass /** 34*ff3e077bSSimon Glass * pci_get_bus_max() - returns the bus number of the last active bus 35*ff3e077bSSimon Glass * 36*ff3e077bSSimon Glass * @return last bus number, or -1 if no active buses 37*ff3e077bSSimon Glass */ 38*ff3e077bSSimon Glass static int pci_get_bus_max(void) 39*ff3e077bSSimon Glass { 40*ff3e077bSSimon Glass struct udevice *bus; 41*ff3e077bSSimon Glass struct uclass *uc; 42*ff3e077bSSimon Glass int ret = -1; 43*ff3e077bSSimon Glass 44*ff3e077bSSimon Glass ret = uclass_get(UCLASS_PCI, &uc); 45*ff3e077bSSimon Glass uclass_foreach_dev(bus, uc) { 46*ff3e077bSSimon Glass if (bus->seq > ret) 47*ff3e077bSSimon Glass ret = bus->seq; 48*ff3e077bSSimon Glass } 49*ff3e077bSSimon Glass 50*ff3e077bSSimon Glass debug("%s: ret=%d\n", __func__, ret); 51*ff3e077bSSimon Glass 52*ff3e077bSSimon Glass return ret; 53*ff3e077bSSimon Glass } 54*ff3e077bSSimon Glass 55*ff3e077bSSimon Glass int pci_last_busno(void) 56*ff3e077bSSimon Glass { 57*ff3e077bSSimon Glass struct pci_controller *hose; 58*ff3e077bSSimon Glass struct udevice *bus; 59*ff3e077bSSimon Glass struct uclass *uc; 60*ff3e077bSSimon Glass int ret; 61*ff3e077bSSimon Glass 62*ff3e077bSSimon Glass debug("pci_last_busno\n"); 63*ff3e077bSSimon Glass ret = uclass_get(UCLASS_PCI, &uc); 64*ff3e077bSSimon Glass if (ret || list_empty(&uc->dev_head)) 65*ff3e077bSSimon Glass return -1; 66*ff3e077bSSimon Glass 67*ff3e077bSSimon Glass /* Probe the last bus */ 68*ff3e077bSSimon Glass bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node); 69*ff3e077bSSimon Glass debug("bus = %p, %s\n", bus, bus->name); 70*ff3e077bSSimon Glass assert(bus); 71*ff3e077bSSimon Glass ret = device_probe(bus); 72*ff3e077bSSimon Glass if (ret) 73*ff3e077bSSimon Glass return ret; 74*ff3e077bSSimon Glass 75*ff3e077bSSimon Glass /* If that bus has bridges, we may have new buses now. Get the last */ 76*ff3e077bSSimon Glass bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node); 77*ff3e077bSSimon Glass hose = dev_get_uclass_priv(bus); 78*ff3e077bSSimon Glass debug("bus = %s, hose = %p\n", bus->name, hose); 79*ff3e077bSSimon Glass 80*ff3e077bSSimon Glass return hose->last_busno; 81*ff3e077bSSimon Glass } 82*ff3e077bSSimon Glass 83*ff3e077bSSimon Glass int pci_get_ff(enum pci_size_t size) 84*ff3e077bSSimon Glass { 85*ff3e077bSSimon Glass switch (size) { 86*ff3e077bSSimon Glass case PCI_SIZE_8: 87*ff3e077bSSimon Glass return 0xff; 88*ff3e077bSSimon Glass case PCI_SIZE_16: 89*ff3e077bSSimon Glass return 0xffff; 90*ff3e077bSSimon Glass default: 91*ff3e077bSSimon Glass return 0xffffffff; 92*ff3e077bSSimon Glass } 93*ff3e077bSSimon Glass } 94*ff3e077bSSimon Glass 95*ff3e077bSSimon Glass int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn, 96*ff3e077bSSimon Glass struct udevice **devp) 97*ff3e077bSSimon Glass { 98*ff3e077bSSimon Glass struct udevice *dev; 99*ff3e077bSSimon Glass 100*ff3e077bSSimon Glass for (device_find_first_child(bus, &dev); 101*ff3e077bSSimon Glass dev; 102*ff3e077bSSimon Glass device_find_next_child(&dev)) { 103*ff3e077bSSimon Glass struct pci_child_platdata *pplat; 104*ff3e077bSSimon Glass 105*ff3e077bSSimon Glass pplat = dev_get_parent_platdata(dev); 106*ff3e077bSSimon Glass if (pplat && pplat->devfn == find_devfn) { 107*ff3e077bSSimon Glass *devp = dev; 108*ff3e077bSSimon Glass return 0; 109*ff3e077bSSimon Glass } 110*ff3e077bSSimon Glass } 111*ff3e077bSSimon Glass 112*ff3e077bSSimon Glass return -ENODEV; 113*ff3e077bSSimon Glass } 114*ff3e077bSSimon Glass 115*ff3e077bSSimon Glass int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp) 116*ff3e077bSSimon Glass { 117*ff3e077bSSimon Glass struct udevice *bus; 118*ff3e077bSSimon Glass int ret; 119*ff3e077bSSimon Glass 120*ff3e077bSSimon Glass ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus); 121*ff3e077bSSimon Glass if (ret) 122*ff3e077bSSimon Glass return ret; 123*ff3e077bSSimon Glass return pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), devp); 124*ff3e077bSSimon Glass } 125*ff3e077bSSimon Glass 126*ff3e077bSSimon Glass static int pci_device_matches_ids(struct udevice *dev, 127*ff3e077bSSimon Glass struct pci_device_id *ids) 128*ff3e077bSSimon Glass { 129*ff3e077bSSimon Glass struct pci_child_platdata *pplat; 130*ff3e077bSSimon Glass int i; 131*ff3e077bSSimon Glass 132*ff3e077bSSimon Glass pplat = dev_get_parent_platdata(dev); 133*ff3e077bSSimon Glass if (!pplat) 134*ff3e077bSSimon Glass return -EINVAL; 135*ff3e077bSSimon Glass for (i = 0; ids[i].vendor != 0; i++) { 136*ff3e077bSSimon Glass if (pplat->vendor == ids[i].vendor && 137*ff3e077bSSimon Glass pplat->device == ids[i].device) 138*ff3e077bSSimon Glass return i; 139*ff3e077bSSimon Glass } 140*ff3e077bSSimon Glass 141*ff3e077bSSimon Glass return -EINVAL; 142*ff3e077bSSimon Glass } 143*ff3e077bSSimon Glass 144*ff3e077bSSimon Glass int pci_bus_find_devices(struct udevice *bus, struct pci_device_id *ids, 145*ff3e077bSSimon Glass int *indexp, struct udevice **devp) 146*ff3e077bSSimon Glass { 147*ff3e077bSSimon Glass struct udevice *dev; 148*ff3e077bSSimon Glass 149*ff3e077bSSimon Glass /* Scan all devices on this bus */ 150*ff3e077bSSimon Glass for (device_find_first_child(bus, &dev); 151*ff3e077bSSimon Glass dev; 152*ff3e077bSSimon Glass device_find_next_child(&dev)) { 153*ff3e077bSSimon Glass if (pci_device_matches_ids(dev, ids) >= 0) { 154*ff3e077bSSimon Glass if ((*indexp)-- <= 0) { 155*ff3e077bSSimon Glass *devp = dev; 156*ff3e077bSSimon Glass return 0; 157*ff3e077bSSimon Glass } 158*ff3e077bSSimon Glass } 159*ff3e077bSSimon Glass } 160*ff3e077bSSimon Glass 161*ff3e077bSSimon Glass return -ENODEV; 162*ff3e077bSSimon Glass } 163*ff3e077bSSimon Glass 164*ff3e077bSSimon Glass int pci_find_device_id(struct pci_device_id *ids, int index, 165*ff3e077bSSimon Glass struct udevice **devp) 166*ff3e077bSSimon Glass { 167*ff3e077bSSimon Glass struct udevice *bus; 168*ff3e077bSSimon Glass 169*ff3e077bSSimon Glass /* Scan all known buses */ 170*ff3e077bSSimon Glass for (uclass_first_device(UCLASS_PCI, &bus); 171*ff3e077bSSimon Glass bus; 172*ff3e077bSSimon Glass uclass_next_device(&bus)) { 173*ff3e077bSSimon Glass if (!pci_bus_find_devices(bus, ids, &index, devp)) 174*ff3e077bSSimon Glass return 0; 175*ff3e077bSSimon Glass } 176*ff3e077bSSimon Glass *devp = NULL; 177*ff3e077bSSimon Glass 178*ff3e077bSSimon Glass return -ENODEV; 179*ff3e077bSSimon Glass } 180*ff3e077bSSimon Glass 181*ff3e077bSSimon Glass int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset, 182*ff3e077bSSimon Glass unsigned long value, enum pci_size_t size) 183*ff3e077bSSimon Glass { 184*ff3e077bSSimon Glass struct dm_pci_ops *ops; 185*ff3e077bSSimon Glass 186*ff3e077bSSimon Glass ops = pci_get_ops(bus); 187*ff3e077bSSimon Glass if (!ops->write_config) 188*ff3e077bSSimon Glass return -ENOSYS; 189*ff3e077bSSimon Glass return ops->write_config(bus, bdf, offset, value, size); 190*ff3e077bSSimon Glass } 191*ff3e077bSSimon Glass 192*ff3e077bSSimon Glass int pci_write_config(pci_dev_t bdf, int offset, unsigned long value, 193*ff3e077bSSimon Glass enum pci_size_t size) 194*ff3e077bSSimon Glass { 195*ff3e077bSSimon Glass struct udevice *bus; 196*ff3e077bSSimon Glass int ret; 197*ff3e077bSSimon Glass 198*ff3e077bSSimon Glass ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus); 199*ff3e077bSSimon Glass if (ret) 200*ff3e077bSSimon Glass return ret; 201*ff3e077bSSimon Glass 202*ff3e077bSSimon Glass return pci_bus_write_config(bus, PCI_MASK_BUS(bdf), offset, value, 203*ff3e077bSSimon Glass size); 204*ff3e077bSSimon Glass } 205*ff3e077bSSimon Glass 206*ff3e077bSSimon Glass int pci_write_config32(pci_dev_t bdf, int offset, u32 value) 207*ff3e077bSSimon Glass { 208*ff3e077bSSimon Glass return pci_write_config(bdf, offset, value, PCI_SIZE_32); 209*ff3e077bSSimon Glass } 210*ff3e077bSSimon Glass 211*ff3e077bSSimon Glass int pci_write_config16(pci_dev_t bdf, int offset, u16 value) 212*ff3e077bSSimon Glass { 213*ff3e077bSSimon Glass return pci_write_config(bdf, offset, value, PCI_SIZE_16); 214*ff3e077bSSimon Glass } 215*ff3e077bSSimon Glass 216*ff3e077bSSimon Glass int pci_write_config8(pci_dev_t bdf, int offset, u8 value) 217*ff3e077bSSimon Glass { 218*ff3e077bSSimon Glass return pci_write_config(bdf, offset, value, PCI_SIZE_8); 219*ff3e077bSSimon Glass } 220*ff3e077bSSimon Glass 221*ff3e077bSSimon Glass int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset, 222*ff3e077bSSimon Glass unsigned long *valuep, enum pci_size_t size) 223*ff3e077bSSimon Glass { 224*ff3e077bSSimon Glass struct dm_pci_ops *ops; 225*ff3e077bSSimon Glass 226*ff3e077bSSimon Glass ops = pci_get_ops(bus); 227*ff3e077bSSimon Glass if (!ops->read_config) 228*ff3e077bSSimon Glass return -ENOSYS; 229*ff3e077bSSimon Glass return ops->read_config(bus, bdf, offset, valuep, size); 230*ff3e077bSSimon Glass } 231*ff3e077bSSimon Glass 232*ff3e077bSSimon Glass int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep, 233*ff3e077bSSimon Glass enum pci_size_t size) 234*ff3e077bSSimon Glass { 235*ff3e077bSSimon Glass struct udevice *bus; 236*ff3e077bSSimon Glass int ret; 237*ff3e077bSSimon Glass 238*ff3e077bSSimon Glass ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus); 239*ff3e077bSSimon Glass if (ret) 240*ff3e077bSSimon Glass return ret; 241*ff3e077bSSimon Glass 242*ff3e077bSSimon Glass return pci_bus_read_config(bus, PCI_MASK_BUS(bdf), offset, valuep, 243*ff3e077bSSimon Glass size); 244*ff3e077bSSimon Glass } 245*ff3e077bSSimon Glass 246*ff3e077bSSimon Glass int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep) 247*ff3e077bSSimon Glass { 248*ff3e077bSSimon Glass unsigned long value; 249*ff3e077bSSimon Glass int ret; 250*ff3e077bSSimon Glass 251*ff3e077bSSimon Glass ret = pci_read_config(bdf, offset, &value, PCI_SIZE_32); 252*ff3e077bSSimon Glass if (ret) 253*ff3e077bSSimon Glass return ret; 254*ff3e077bSSimon Glass *valuep = value; 255*ff3e077bSSimon Glass 256*ff3e077bSSimon Glass return 0; 257*ff3e077bSSimon Glass } 258*ff3e077bSSimon Glass 259*ff3e077bSSimon Glass int pci_read_config16(pci_dev_t bdf, int offset, u16 *valuep) 260*ff3e077bSSimon Glass { 261*ff3e077bSSimon Glass unsigned long value; 262*ff3e077bSSimon Glass int ret; 263*ff3e077bSSimon Glass 264*ff3e077bSSimon Glass ret = pci_read_config(bdf, offset, &value, PCI_SIZE_16); 265*ff3e077bSSimon Glass if (ret) 266*ff3e077bSSimon Glass return ret; 267*ff3e077bSSimon Glass *valuep = value; 268*ff3e077bSSimon Glass 269*ff3e077bSSimon Glass return 0; 270*ff3e077bSSimon Glass } 271*ff3e077bSSimon Glass 272*ff3e077bSSimon Glass int pci_read_config8(pci_dev_t bdf, int offset, u8 *valuep) 273*ff3e077bSSimon Glass { 274*ff3e077bSSimon Glass unsigned long value; 275*ff3e077bSSimon Glass int ret; 276*ff3e077bSSimon Glass 277*ff3e077bSSimon Glass ret = pci_read_config(bdf, offset, &value, PCI_SIZE_8); 278*ff3e077bSSimon Glass if (ret) 279*ff3e077bSSimon Glass return ret; 280*ff3e077bSSimon Glass *valuep = value; 281*ff3e077bSSimon Glass 282*ff3e077bSSimon Glass return 0; 283*ff3e077bSSimon Glass } 284*ff3e077bSSimon Glass 285*ff3e077bSSimon Glass int pci_auto_config_devices(struct udevice *bus) 286*ff3e077bSSimon Glass { 287*ff3e077bSSimon Glass struct pci_controller *hose = bus->uclass_priv; 288*ff3e077bSSimon Glass unsigned int sub_bus; 289*ff3e077bSSimon Glass struct udevice *dev; 290*ff3e077bSSimon Glass int ret; 291*ff3e077bSSimon Glass 292*ff3e077bSSimon Glass sub_bus = bus->seq; 293*ff3e077bSSimon Glass debug("%s: start\n", __func__); 294*ff3e077bSSimon Glass pciauto_config_init(hose); 295*ff3e077bSSimon Glass for (ret = device_find_first_child(bus, &dev); 296*ff3e077bSSimon Glass !ret && dev; 297*ff3e077bSSimon Glass ret = device_find_next_child(&dev)) { 298*ff3e077bSSimon Glass struct pci_child_platdata *pplat; 299*ff3e077bSSimon Glass 300*ff3e077bSSimon Glass pplat = dev_get_parent_platdata(dev); 301*ff3e077bSSimon Glass unsigned int max_bus; 302*ff3e077bSSimon Glass pci_dev_t bdf; 303*ff3e077bSSimon Glass 304*ff3e077bSSimon Glass bdf = PCI_ADD_BUS(bus->seq, pplat->devfn); 305*ff3e077bSSimon Glass debug("%s: device %s\n", __func__, dev->name); 306*ff3e077bSSimon Glass max_bus = pciauto_config_device(hose, bdf); 307*ff3e077bSSimon Glass sub_bus = max(sub_bus, max_bus); 308*ff3e077bSSimon Glass } 309*ff3e077bSSimon Glass debug("%s: done\n", __func__); 310*ff3e077bSSimon Glass 311*ff3e077bSSimon Glass return sub_bus; 312*ff3e077bSSimon Glass } 313*ff3e077bSSimon Glass 314*ff3e077bSSimon Glass int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf) 315*ff3e077bSSimon Glass { 316*ff3e077bSSimon Glass struct udevice *parent, *bus; 317*ff3e077bSSimon Glass int sub_bus; 318*ff3e077bSSimon Glass int ret; 319*ff3e077bSSimon Glass 320*ff3e077bSSimon Glass debug("%s\n", __func__); 321*ff3e077bSSimon Glass parent = hose->bus; 322*ff3e077bSSimon Glass 323*ff3e077bSSimon Glass /* Find the bus within the parent */ 324*ff3e077bSSimon Glass ret = pci_bus_find_devfn(parent, bdf, &bus); 325*ff3e077bSSimon Glass if (ret) { 326*ff3e077bSSimon Glass debug("%s: Cannot find device %x on bus %s: %d\n", __func__, 327*ff3e077bSSimon Glass bdf, parent->name, ret); 328*ff3e077bSSimon Glass return ret; 329*ff3e077bSSimon Glass } 330*ff3e077bSSimon Glass 331*ff3e077bSSimon Glass sub_bus = pci_get_bus_max() + 1; 332*ff3e077bSSimon Glass debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name); 333*ff3e077bSSimon Glass pciauto_prescan_setup_bridge(hose, bdf, bus->seq); 334*ff3e077bSSimon Glass 335*ff3e077bSSimon Glass ret = device_probe(bus); 336*ff3e077bSSimon Glass if (ret) { 337*ff3e077bSSimon Glass debug("%s: Cannot probe bus bus %s: %d\n", __func__, bus->name, 338*ff3e077bSSimon Glass ret); 339*ff3e077bSSimon Glass return ret; 340*ff3e077bSSimon Glass } 341*ff3e077bSSimon Glass if (sub_bus != bus->seq) { 342*ff3e077bSSimon Glass printf("%s: Internal error, bus '%s' got seq %d, expected %d\n", 343*ff3e077bSSimon Glass __func__, bus->name, bus->seq, sub_bus); 344*ff3e077bSSimon Glass return -EPIPE; 345*ff3e077bSSimon Glass } 346*ff3e077bSSimon Glass sub_bus = pci_get_bus_max(); 347*ff3e077bSSimon Glass pciauto_postscan_setup_bridge(hose, bdf, sub_bus); 348*ff3e077bSSimon Glass 349*ff3e077bSSimon Glass return sub_bus; 350*ff3e077bSSimon Glass } 351*ff3e077bSSimon Glass 352*ff3e077bSSimon Glass int pci_bind_bus_devices(struct udevice *bus) 353*ff3e077bSSimon Glass { 354*ff3e077bSSimon Glass ulong vendor, device; 355*ff3e077bSSimon Glass ulong header_type; 356*ff3e077bSSimon Glass pci_dev_t devfn, end; 357*ff3e077bSSimon Glass bool found_multi; 358*ff3e077bSSimon Glass int ret; 359*ff3e077bSSimon Glass 360*ff3e077bSSimon Glass found_multi = false; 361*ff3e077bSSimon Glass end = PCI_DEVFN(PCI_MAX_PCI_DEVICES - 1, PCI_MAX_PCI_FUNCTIONS - 1); 362*ff3e077bSSimon Glass for (devfn = PCI_DEVFN(0, 0); devfn < end; devfn += PCI_DEVFN(0, 1)) { 363*ff3e077bSSimon Glass struct pci_child_platdata *pplat; 364*ff3e077bSSimon Glass struct udevice *dev; 365*ff3e077bSSimon Glass ulong class; 366*ff3e077bSSimon Glass 367*ff3e077bSSimon Glass if (PCI_FUNC(devfn) && !found_multi) 368*ff3e077bSSimon Glass continue; 369*ff3e077bSSimon Glass /* Check only the first access, we don't expect problems */ 370*ff3e077bSSimon Glass ret = pci_bus_read_config(bus, devfn, PCI_HEADER_TYPE, 371*ff3e077bSSimon Glass &header_type, PCI_SIZE_8); 372*ff3e077bSSimon Glass if (ret) 373*ff3e077bSSimon Glass goto error; 374*ff3e077bSSimon Glass pci_bus_read_config(bus, devfn, PCI_VENDOR_ID, &vendor, 375*ff3e077bSSimon Glass PCI_SIZE_16); 376*ff3e077bSSimon Glass if (vendor == 0xffff || vendor == 0x0000) 377*ff3e077bSSimon Glass continue; 378*ff3e077bSSimon Glass 379*ff3e077bSSimon Glass if (!PCI_FUNC(devfn)) 380*ff3e077bSSimon Glass found_multi = header_type & 0x80; 381*ff3e077bSSimon Glass 382*ff3e077bSSimon Glass debug("%s: bus %d/%s: found device %x, function %d\n", __func__, 383*ff3e077bSSimon Glass bus->seq, bus->name, PCI_DEV(devfn), PCI_FUNC(devfn)); 384*ff3e077bSSimon Glass pci_bus_read_config(bus, devfn, PCI_DEVICE_ID, &device, 385*ff3e077bSSimon Glass PCI_SIZE_16); 386*ff3e077bSSimon Glass pci_bus_read_config(bus, devfn, PCI_CLASS_DEVICE, &class, 387*ff3e077bSSimon Glass PCI_SIZE_16); 388*ff3e077bSSimon Glass 389*ff3e077bSSimon Glass /* Find this device in the device tree */ 390*ff3e077bSSimon Glass ret = pci_bus_find_devfn(bus, devfn, &dev); 391*ff3e077bSSimon Glass 392*ff3e077bSSimon Glass /* If nothing in the device tree, bind a generic device */ 393*ff3e077bSSimon Glass if (ret == -ENODEV) { 394*ff3e077bSSimon Glass char name[30], *str; 395*ff3e077bSSimon Glass const char *drv; 396*ff3e077bSSimon Glass 397*ff3e077bSSimon Glass sprintf(name, "pci_%x:%x.%x", bus->seq, 398*ff3e077bSSimon Glass PCI_DEV(devfn), PCI_FUNC(devfn)); 399*ff3e077bSSimon Glass str = strdup(name); 400*ff3e077bSSimon Glass if (!str) 401*ff3e077bSSimon Glass return -ENOMEM; 402*ff3e077bSSimon Glass drv = class == PCI_CLASS_BRIDGE_PCI ? 403*ff3e077bSSimon Glass "pci_bridge_drv" : "pci_generic_drv"; 404*ff3e077bSSimon Glass ret = device_bind_driver(bus, drv, str, &dev); 405*ff3e077bSSimon Glass } 406*ff3e077bSSimon Glass if (ret) 407*ff3e077bSSimon Glass return ret; 408*ff3e077bSSimon Glass 409*ff3e077bSSimon Glass /* Update the platform data */ 410*ff3e077bSSimon Glass pplat = dev_get_parent_platdata(dev); 411*ff3e077bSSimon Glass pplat->devfn = devfn; 412*ff3e077bSSimon Glass pplat->vendor = vendor; 413*ff3e077bSSimon Glass pplat->device = device; 414*ff3e077bSSimon Glass pplat->class = class; 415*ff3e077bSSimon Glass } 416*ff3e077bSSimon Glass 417*ff3e077bSSimon Glass return 0; 418*ff3e077bSSimon Glass error: 419*ff3e077bSSimon Glass printf("Cannot read bus configuration: %d\n", ret); 420*ff3e077bSSimon Glass 421*ff3e077bSSimon Glass return ret; 422*ff3e077bSSimon Glass } 423*ff3e077bSSimon Glass 424*ff3e077bSSimon Glass static int pci_uclass_post_bind(struct udevice *bus) 425*ff3e077bSSimon Glass { 426*ff3e077bSSimon Glass /* 427*ff3e077bSSimon Glass * Scan the device tree for devices. This does not probe the PCI bus, 428*ff3e077bSSimon Glass * as this is not permitted while binding. It just finds devices 429*ff3e077bSSimon Glass * mentioned in the device tree. 430*ff3e077bSSimon Glass * 431*ff3e077bSSimon Glass * Before relocation, only bind devices marked for pre-relocation 432*ff3e077bSSimon Glass * use. 433*ff3e077bSSimon Glass */ 434*ff3e077bSSimon Glass return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset, 435*ff3e077bSSimon Glass gd->flags & GD_FLG_RELOC ? false : true); 436*ff3e077bSSimon Glass } 437*ff3e077bSSimon Glass 438*ff3e077bSSimon Glass static int decode_regions(struct pci_controller *hose, const void *blob, 439*ff3e077bSSimon Glass int parent_node, int node) 440*ff3e077bSSimon Glass { 441*ff3e077bSSimon Glass int pci_addr_cells, addr_cells, size_cells; 442*ff3e077bSSimon Glass int cells_per_record; 443*ff3e077bSSimon Glass const u32 *prop; 444*ff3e077bSSimon Glass int len; 445*ff3e077bSSimon Glass int i; 446*ff3e077bSSimon Glass 447*ff3e077bSSimon Glass prop = fdt_getprop(blob, node, "ranges", &len); 448*ff3e077bSSimon Glass if (!prop) 449*ff3e077bSSimon Glass return -EINVAL; 450*ff3e077bSSimon Glass pci_addr_cells = fdt_address_cells(blob, node); 451*ff3e077bSSimon Glass addr_cells = fdt_address_cells(blob, parent_node); 452*ff3e077bSSimon Glass size_cells = fdt_size_cells(blob, node); 453*ff3e077bSSimon Glass 454*ff3e077bSSimon Glass /* PCI addresses are always 3-cells */ 455*ff3e077bSSimon Glass len /= sizeof(u32); 456*ff3e077bSSimon Glass cells_per_record = pci_addr_cells + addr_cells + size_cells; 457*ff3e077bSSimon Glass hose->region_count = 0; 458*ff3e077bSSimon Glass debug("%s: len=%d, cells_per_record=%d\n", __func__, len, 459*ff3e077bSSimon Glass cells_per_record); 460*ff3e077bSSimon Glass for (i = 0; i < MAX_PCI_REGIONS; i++, len -= cells_per_record) { 461*ff3e077bSSimon Glass u64 pci_addr, addr, size; 462*ff3e077bSSimon Glass int space_code; 463*ff3e077bSSimon Glass u32 flags; 464*ff3e077bSSimon Glass int type; 465*ff3e077bSSimon Glass 466*ff3e077bSSimon Glass if (len < cells_per_record) 467*ff3e077bSSimon Glass break; 468*ff3e077bSSimon Glass flags = fdt32_to_cpu(prop[0]); 469*ff3e077bSSimon Glass space_code = (flags >> 24) & 3; 470*ff3e077bSSimon Glass pci_addr = fdtdec_get_number(prop + 1, 2); 471*ff3e077bSSimon Glass prop += pci_addr_cells; 472*ff3e077bSSimon Glass addr = fdtdec_get_number(prop, addr_cells); 473*ff3e077bSSimon Glass prop += addr_cells; 474*ff3e077bSSimon Glass size = fdtdec_get_number(prop, size_cells); 475*ff3e077bSSimon Glass prop += size_cells; 476*ff3e077bSSimon Glass debug("%s: region %d, pci_addr=%" PRIx64 ", addr=%" PRIx64 477*ff3e077bSSimon Glass ", size=%" PRIx64 ", space_code=%d\n", __func__, 478*ff3e077bSSimon Glass hose->region_count, pci_addr, addr, size, space_code); 479*ff3e077bSSimon Glass if (space_code & 2) { 480*ff3e077bSSimon Glass type = flags & (1U << 30) ? PCI_REGION_PREFETCH : 481*ff3e077bSSimon Glass PCI_REGION_MEM; 482*ff3e077bSSimon Glass } else if (space_code & 1) { 483*ff3e077bSSimon Glass type = PCI_REGION_IO; 484*ff3e077bSSimon Glass } else { 485*ff3e077bSSimon Glass continue; 486*ff3e077bSSimon Glass } 487*ff3e077bSSimon Glass debug(" - type=%d\n", type); 488*ff3e077bSSimon Glass pci_set_region(hose->regions + hose->region_count++, pci_addr, 489*ff3e077bSSimon Glass addr, size, type); 490*ff3e077bSSimon Glass } 491*ff3e077bSSimon Glass 492*ff3e077bSSimon Glass /* Add a region for our local memory */ 493*ff3e077bSSimon Glass pci_set_region(hose->regions + hose->region_count++, 0, 0, 494*ff3e077bSSimon Glass gd->ram_size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); 495*ff3e077bSSimon Glass 496*ff3e077bSSimon Glass return 0; 497*ff3e077bSSimon Glass } 498*ff3e077bSSimon Glass 499*ff3e077bSSimon Glass static int pci_uclass_pre_probe(struct udevice *bus) 500*ff3e077bSSimon Glass { 501*ff3e077bSSimon Glass struct pci_controller *hose; 502*ff3e077bSSimon Glass int ret; 503*ff3e077bSSimon Glass 504*ff3e077bSSimon Glass debug("%s, bus=%d/%s, parent=%s\n", __func__, bus->seq, bus->name, 505*ff3e077bSSimon Glass bus->parent->name); 506*ff3e077bSSimon Glass hose = bus->uclass_priv; 507*ff3e077bSSimon Glass 508*ff3e077bSSimon Glass /* For bridges, use the top-level PCI controller */ 509*ff3e077bSSimon Glass if (device_get_uclass_id(bus->parent) == UCLASS_ROOT) { 510*ff3e077bSSimon Glass hose->ctlr = bus; 511*ff3e077bSSimon Glass ret = decode_regions(hose, gd->fdt_blob, bus->parent->of_offset, 512*ff3e077bSSimon Glass bus->of_offset); 513*ff3e077bSSimon Glass if (ret) { 514*ff3e077bSSimon Glass debug("%s: Cannot decode regions\n", __func__); 515*ff3e077bSSimon Glass return ret; 516*ff3e077bSSimon Glass } 517*ff3e077bSSimon Glass } else { 518*ff3e077bSSimon Glass struct pci_controller *parent_hose; 519*ff3e077bSSimon Glass 520*ff3e077bSSimon Glass parent_hose = dev_get_uclass_priv(bus->parent); 521*ff3e077bSSimon Glass hose->ctlr = parent_hose->bus; 522*ff3e077bSSimon Glass } 523*ff3e077bSSimon Glass hose->bus = bus; 524*ff3e077bSSimon Glass hose->first_busno = bus->seq; 525*ff3e077bSSimon Glass hose->last_busno = bus->seq; 526*ff3e077bSSimon Glass 527*ff3e077bSSimon Glass return 0; 528*ff3e077bSSimon Glass } 529*ff3e077bSSimon Glass 530*ff3e077bSSimon Glass static int pci_uclass_post_probe(struct udevice *bus) 531*ff3e077bSSimon Glass { 532*ff3e077bSSimon Glass int ret; 533*ff3e077bSSimon Glass 534*ff3e077bSSimon Glass /* Don't scan buses before relocation */ 535*ff3e077bSSimon Glass if (!(gd->flags & GD_FLG_RELOC)) 536*ff3e077bSSimon Glass return 0; 537*ff3e077bSSimon Glass 538*ff3e077bSSimon Glass debug("%s: probing bus %d\n", __func__, bus->seq); 539*ff3e077bSSimon Glass ret = pci_bind_bus_devices(bus); 540*ff3e077bSSimon Glass if (ret) 541*ff3e077bSSimon Glass return ret; 542*ff3e077bSSimon Glass 543*ff3e077bSSimon Glass #ifdef CONFIG_PCI_PNP 544*ff3e077bSSimon Glass ret = pci_auto_config_devices(bus); 545*ff3e077bSSimon Glass #endif 546*ff3e077bSSimon Glass 547*ff3e077bSSimon Glass return ret < 0 ? ret : 0; 548*ff3e077bSSimon Glass } 549*ff3e077bSSimon Glass 550*ff3e077bSSimon Glass static int pci_uclass_child_post_bind(struct udevice *dev) 551*ff3e077bSSimon Glass { 552*ff3e077bSSimon Glass struct pci_child_platdata *pplat; 553*ff3e077bSSimon Glass struct fdt_pci_addr addr; 554*ff3e077bSSimon Glass int ret; 555*ff3e077bSSimon Glass 556*ff3e077bSSimon Glass if (dev->of_offset == -1) 557*ff3e077bSSimon Glass return 0; 558*ff3e077bSSimon Glass 559*ff3e077bSSimon Glass /* 560*ff3e077bSSimon Glass * We could read vendor, device, class if available. But for now we 561*ff3e077bSSimon Glass * just check the address. 562*ff3e077bSSimon Glass */ 563*ff3e077bSSimon Glass pplat = dev_get_parent_platdata(dev); 564*ff3e077bSSimon Glass ret = fdtdec_get_pci_addr(gd->fdt_blob, dev->of_offset, 565*ff3e077bSSimon Glass FDT_PCI_SPACE_CONFIG, "reg", &addr); 566*ff3e077bSSimon Glass 567*ff3e077bSSimon Glass if (ret) { 568*ff3e077bSSimon Glass if (ret != -ENOENT) 569*ff3e077bSSimon Glass return -EINVAL; 570*ff3e077bSSimon Glass } else { 571*ff3e077bSSimon Glass /* extract the bdf from fdt_pci_addr */ 572*ff3e077bSSimon Glass pplat->devfn = addr.phys_hi & 0xffff00; 573*ff3e077bSSimon Glass } 574*ff3e077bSSimon Glass 575*ff3e077bSSimon Glass return 0; 576*ff3e077bSSimon Glass } 577*ff3e077bSSimon Glass 578*ff3e077bSSimon Glass int pci_bridge_read_config(struct udevice *bus, pci_dev_t devfn, uint offset, 579*ff3e077bSSimon Glass ulong *valuep, enum pci_size_t size) 580*ff3e077bSSimon Glass { 581*ff3e077bSSimon Glass struct pci_controller *hose = bus->uclass_priv; 582*ff3e077bSSimon Glass pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn); 583*ff3e077bSSimon Glass 584*ff3e077bSSimon Glass return pci_bus_read_config(hose->ctlr, bdf, offset, valuep, size); 585*ff3e077bSSimon Glass } 586*ff3e077bSSimon Glass 587*ff3e077bSSimon Glass int pci_bridge_write_config(struct udevice *bus, pci_dev_t devfn, uint offset, 588*ff3e077bSSimon Glass ulong value, enum pci_size_t size) 589*ff3e077bSSimon Glass { 590*ff3e077bSSimon Glass struct pci_controller *hose = bus->uclass_priv; 591*ff3e077bSSimon Glass pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn); 592*ff3e077bSSimon Glass 593*ff3e077bSSimon Glass return pci_bus_write_config(hose->ctlr, bdf, offset, value, size); 594*ff3e077bSSimon Glass } 595*ff3e077bSSimon Glass 596*ff3e077bSSimon Glass UCLASS_DRIVER(pci) = { 597*ff3e077bSSimon Glass .id = UCLASS_PCI, 598*ff3e077bSSimon Glass .name = "pci", 599*ff3e077bSSimon Glass .post_bind = pci_uclass_post_bind, 600*ff3e077bSSimon Glass .pre_probe = pci_uclass_pre_probe, 601*ff3e077bSSimon Glass .post_probe = pci_uclass_post_probe, 602*ff3e077bSSimon Glass .child_post_bind = pci_uclass_child_post_bind, 603*ff3e077bSSimon Glass .per_device_auto_alloc_size = sizeof(struct pci_controller), 604*ff3e077bSSimon Glass .per_child_platdata_auto_alloc_size = 605*ff3e077bSSimon Glass sizeof(struct pci_child_platdata), 606*ff3e077bSSimon Glass }; 607*ff3e077bSSimon Glass 608*ff3e077bSSimon Glass static const struct dm_pci_ops pci_bridge_ops = { 609*ff3e077bSSimon Glass .read_config = pci_bridge_read_config, 610*ff3e077bSSimon Glass .write_config = pci_bridge_write_config, 611*ff3e077bSSimon Glass }; 612*ff3e077bSSimon Glass 613*ff3e077bSSimon Glass static const struct udevice_id pci_bridge_ids[] = { 614*ff3e077bSSimon Glass { .compatible = "pci-bridge" }, 615*ff3e077bSSimon Glass { } 616*ff3e077bSSimon Glass }; 617*ff3e077bSSimon Glass 618*ff3e077bSSimon Glass U_BOOT_DRIVER(pci_bridge_drv) = { 619*ff3e077bSSimon Glass .name = "pci_bridge_drv", 620*ff3e077bSSimon Glass .id = UCLASS_PCI, 621*ff3e077bSSimon Glass .of_match = pci_bridge_ids, 622*ff3e077bSSimon Glass .ops = &pci_bridge_ops, 623*ff3e077bSSimon Glass }; 624*ff3e077bSSimon Glass 625*ff3e077bSSimon Glass UCLASS_DRIVER(pci_generic) = { 626*ff3e077bSSimon Glass .id = UCLASS_PCI_GENERIC, 627*ff3e077bSSimon Glass .name = "pci_generic", 628*ff3e077bSSimon Glass }; 629*ff3e077bSSimon Glass 630*ff3e077bSSimon Glass static const struct udevice_id pci_generic_ids[] = { 631*ff3e077bSSimon Glass { .compatible = "pci-generic" }, 632*ff3e077bSSimon Glass { } 633*ff3e077bSSimon Glass }; 634*ff3e077bSSimon Glass 635*ff3e077bSSimon Glass U_BOOT_DRIVER(pci_generic_drv) = { 636*ff3e077bSSimon Glass .name = "pci_generic_drv", 637*ff3e077bSSimon Glass .id = UCLASS_PCI_GENERIC, 638*ff3e077bSSimon Glass .of_match = pci_generic_ids, 639*ff3e077bSSimon Glass }; 640