aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBin Meng2018-10-15 04:21:21 -0500
committerSimon Glass2018-11-14 11:16:28 -0600
commita8c5f8d3d02807f72d048950d72b0c73d55bd7fb (patch)
treed87519b5395d70034c2c9647f44b1cf70d019f70
parentc80c7798cfc6032ce6522aded6048f1d3fe93fce (diff)
downloadu-boot-a8c5f8d3d02807f72d048950d72b0c73d55bd7fb.tar.gz
u-boot-a8c5f8d3d02807f72d048950d72b0c73d55bd7fb.tar.xz
u-boot-a8c5f8d3d02807f72d048950d72b0c73d55bd7fb.zip
dm: pci: Add APIs to find next capability and extended capability
This introduces two new APIs dm_pci_find_next_capability() and dm_pci_find_next_ext_capability() to get PCI capability address and PCI express extended capability address for a given PCI device starting from a given offset. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
-rw-r--r--drivers/pci/pci-uclass.c51
-rw-r--r--include/pci.h48
2 files changed, 84 insertions, 15 deletions
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index da49c96ed5..0c52337f33 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -1344,26 +1344,14 @@ void *dm_pci_map_bar(struct udevice *dev, int bar, int flags)
1344 return dm_pci_bus_to_virt(dev, pci_bus_addr, flags, 0, MAP_NOCACHE); 1344 return dm_pci_bus_to_virt(dev, pci_bus_addr, flags, 0, MAP_NOCACHE);
1345} 1345}
1346 1346
1347int dm_pci_find_capability(struct udevice *dev, int cap) 1347static int _dm_pci_find_next_capability(struct udevice *dev, u8 pos, int cap)
1348{ 1348{
1349 u16 status;
1350 u8 header_type;
1351 int ttl = PCI_FIND_CAP_TTL; 1349 int ttl = PCI_FIND_CAP_TTL;
1352 u8 id; 1350 u8 id;
1353 u16 ent; 1351 u16 ent;
1354 u8 pos;
1355
1356 dm_pci_read_config16(dev, PCI_STATUS, &status);
1357 if (!(status & PCI_STATUS_CAP_LIST))
1358 return 0;
1359
1360 dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type);
1361 if ((header_type & 0x7f) == PCI_HEADER_TYPE_CARDBUS)
1362 pos = PCI_CB_CAPABILITY_LIST;
1363 else
1364 pos = PCI_CAPABILITY_LIST;
1365 1352
1366 dm_pci_read_config8(dev, pos, &pos); 1353 dm_pci_read_config8(dev, pos, &pos);
1354
1367 while (ttl--) { 1355 while (ttl--) {
1368 if (pos < PCI_STD_HEADER_SIZEOF) 1356 if (pos < PCI_STD_HEADER_SIZEOF)
1369 break; 1357 break;
@@ -1381,7 +1369,32 @@ int dm_pci_find_capability(struct udevice *dev, int cap)
1381 return 0; 1369 return 0;
1382} 1370}
1383 1371
1384int dm_pci_find_ext_capability(struct udevice *dev, int cap) 1372int dm_pci_find_next_capability(struct udevice *dev, u8 start, int cap)
1373{
1374 return _dm_pci_find_next_capability(dev, start + PCI_CAP_LIST_NEXT,
1375 cap);
1376}
1377
1378int dm_pci_find_capability(struct udevice *dev, int cap)
1379{
1380 u16 status;
1381 u8 header_type;
1382 u8 pos;
1383
1384 dm_pci_read_config16(dev, PCI_STATUS, &status);
1385 if (!(status & PCI_STATUS_CAP_LIST))
1386 return 0;
1387
1388 dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type);
1389 if ((header_type & 0x7f) == PCI_HEADER_TYPE_CARDBUS)
1390 pos = PCI_CB_CAPABILITY_LIST;
1391 else
1392 pos = PCI_CAPABILITY_LIST;
1393
1394 return _dm_pci_find_next_capability(dev, pos, cap);
1395}
1396
1397int dm_pci_find_next_ext_capability(struct udevice *dev, int start, int cap)
1385{ 1398{
1386 u32 header; 1399 u32 header;
1387 int ttl; 1400 int ttl;
@@ -1390,6 +1403,9 @@ int dm_pci_find_ext_capability(struct udevice *dev, int cap)
1390 /* minimum 8 bytes per capability */ 1403 /* minimum 8 bytes per capability */
1391 ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; 1404 ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
1392 1405
1406 if (start)
1407 pos = start;
1408
1393 dm_pci_read_config32(dev, pos, &header); 1409 dm_pci_read_config32(dev, pos, &header);
1394 /* 1410 /*
1395 * If we have no capabilities, this is indicated by cap ID, 1411 * If we have no capabilities, this is indicated by cap ID,
@@ -1412,6 +1428,11 @@ int dm_pci_find_ext_capability(struct udevice *dev, int cap)
1412 return 0; 1428 return 0;
1413} 1429}
1414 1430
1431int dm_pci_find_ext_capability(struct udevice *dev, int cap)
1432{
1433 return dm_pci_find_next_ext_capability(dev, 0, cap);
1434}
1435
1415UCLASS_DRIVER(pci) = { 1436UCLASS_DRIVER(pci) = {
1416 .id = UCLASS_PCI, 1437 .id = UCLASS_PCI,
1417 .name = "pci", 1438 .name = "pci",
diff --git a/include/pci.h b/include/pci.h
index 938a8390cb..785d7d28b7 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -1313,6 +1313,29 @@ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr,
1313void *dm_pci_map_bar(struct udevice *dev, int bar, int flags); 1313void *dm_pci_map_bar(struct udevice *dev, int bar, int flags);
1314 1314
1315/** 1315/**
1316 * dm_pci_find_next_capability() - find a capability starting from an offset
1317 *
1318 * Tell if a device supports a given PCI capability. Returns the
1319 * address of the requested capability structure within the device's
1320 * PCI configuration space or 0 in case the device does not support it.
1321 *
1322 * Possible values for @cap:
1323 *
1324 * %PCI_CAP_ID_MSI Message Signalled Interrupts
1325 * %PCI_CAP_ID_PCIX PCI-X
1326 * %PCI_CAP_ID_EXP PCI Express
1327 * %PCI_CAP_ID_MSIX MSI-X
1328 *
1329 * See PCI_CAP_ID_xxx for the complete capability ID codes.
1330 *
1331 * @dev: PCI device to query
1332 * @start: offset to start from
1333 * @cap: capability code
1334 * @return: capability address or 0 if not supported
1335 */
1336int dm_pci_find_next_capability(struct udevice *dev, u8 start, int cap);
1337
1338/**
1316 * dm_pci_find_capability() - find a capability 1339 * dm_pci_find_capability() - find a capability
1317 * 1340 *
1318 * Tell if a device supports a given PCI capability. Returns the 1341 * Tell if a device supports a given PCI capability. Returns the
@@ -1335,6 +1358,31 @@ void *dm_pci_map_bar(struct udevice *dev, int bar, int flags);
1335int dm_pci_find_capability(struct udevice *dev, int cap); 1358int dm_pci_find_capability(struct udevice *dev, int cap);
1336 1359
1337/** 1360/**
1361 * dm_pci_find_next_ext_capability() - find an extended capability
1362 * starting from an offset
1363 *
1364 * Tell if a device supports a given PCI express extended capability.
1365 * Returns the address of the requested extended capability structure
1366 * within the device's PCI configuration space or 0 in case the device
1367 * does not support it.
1368 *
1369 * Possible values for @cap:
1370 *
1371 * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting
1372 * %PCI_EXT_CAP_ID_VC Virtual Channel
1373 * %PCI_EXT_CAP_ID_DSN Device Serial Number
1374 * %PCI_EXT_CAP_ID_PWR Power Budgeting
1375 *
1376 * See PCI_EXT_CAP_ID_xxx for the complete extended capability ID codes.
1377 *
1378 * @dev: PCI device to query
1379 * @start: offset to start from
1380 * @cap: extended capability code
1381 * @return: extended capability address or 0 if not supported
1382 */
1383int dm_pci_find_next_ext_capability(struct udevice *dev, int start, int cap);
1384
1385/**
1338 * dm_pci_find_ext_capability() - find an extended capability 1386 * dm_pci_find_ext_capability() - find an extended capability
1339 * 1387 *
1340 * Tell if a device supports a given PCI express extended capability. 1388 * Tell if a device supports a given PCI express extended capability.