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