Commit a8c5f8d3d02807f72d048950d72b0c73d55bd7fb

Authored by Bin Meng
Committed by Simon Glass
1 parent c80c7798cf

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>

Showing 2 changed files with 84 additions and 15 deletions Side-by-side Diff

drivers/pci/pci-uclass.c
... ... @@ -1344,26 +1344,14 @@
1344 1344 return dm_pci_bus_to_virt(dev, pci_bus_addr, flags, 0, MAP_NOCACHE);
1345 1345 }
1346 1346  
1347   -int dm_pci_find_capability(struct udevice *dev, int cap)
  1347 +static int _dm_pci_find_next_capability(struct udevice *dev, u8 pos, int cap)
1348 1348 {
1349   - u16 status;
1350   - u8 header_type;
1351 1349 int ttl = PCI_FIND_CAP_TTL;
1352 1350 u8 id;
1353 1351 u16 ent;
1354   - u8 pos;
1355 1352  
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   -
1366 1353 dm_pci_read_config8(dev, pos, &pos);
  1354 +
1367 1355 while (ttl--) {
1368 1356 if (pos < PCI_STD_HEADER_SIZEOF)
1369 1357 break;
1370 1358  
... ... @@ -1381,8 +1369,33 @@
1381 1369 return 0;
1382 1370 }
1383 1371  
1384   -int dm_pci_find_ext_capability(struct udevice *dev, int cap)
  1372 +int dm_pci_find_next_capability(struct udevice *dev, u8 start, int cap)
1385 1373 {
  1374 + return _dm_pci_find_next_capability(dev, start + PCI_CAP_LIST_NEXT,
  1375 + cap);
  1376 +}
  1377 +
  1378 +int 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 +
  1397 +int dm_pci_find_next_ext_capability(struct udevice *dev, int start, int cap)
  1398 +{
1386 1399 u32 header;
1387 1400 int ttl;
1388 1401 int pos = PCI_CFG_SPACE_SIZE;
... ... @@ -1390,6 +1403,9 @@
1390 1403 /* minimum 8 bytes per capability */
1391 1404 ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
1392 1405  
  1406 + if (start)
  1407 + pos = start;
  1408 +
1393 1409 dm_pci_read_config32(dev, pos, &header);
1394 1410 /*
1395 1411 * If we have no capabilities, this is indicated by cap ID,
... ... @@ -1410,6 +1426,11 @@
1410 1426 }
1411 1427  
1412 1428 return 0;
  1429 +}
  1430 +
  1431 +int dm_pci_find_ext_capability(struct udevice *dev, int cap)
  1432 +{
  1433 + return dm_pci_find_next_ext_capability(dev, 0, cap);
1413 1434 }
1414 1435  
1415 1436 UCLASS_DRIVER(pci) = {
... ... @@ -1313,6 +1313,29 @@
1313 1313 void *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 + */
  1336 +int dm_pci_find_next_capability(struct udevice *dev, u8 start, int cap);
  1337 +
  1338 +/**
1316 1339 * dm_pci_find_capability() - find a capability
1317 1340 *
1318 1341 * Tell if a device supports a given PCI capability. Returns the
... ... @@ -1333,6 +1356,31 @@
1333 1356 * @return: capability address or 0 if not supported
1334 1357 */
1335 1358 int dm_pci_find_capability(struct udevice *dev, int cap);
  1359 +
  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 + */
  1383 +int dm_pci_find_next_ext_capability(struct udevice *dev, int start, int cap);
1336 1384  
1337 1385 /**
1338 1386 * dm_pci_find_ext_capability() - find an extended capability