Commit a8c5f8d3d02807f72d048950d72b0c73d55bd7fb
Committed by
Simon Glass
1 parent
c80c7798cf
Exists in
smarc_8mq_lf_v2020.04
and in
11 other branches
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) = { |
include/pci.h
... | ... | @@ -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 |