diff options
author | Bin Meng | 2018-10-15 04:21:21 -0500 |
---|---|---|
committer | Simon Glass | 2018-11-14 11:16:28 -0600 |
commit | a8c5f8d3d02807f72d048950d72b0c73d55bd7fb (patch) | |
tree | d87519b5395d70034c2c9647f44b1cf70d019f70 /drivers | |
parent | c80c7798cfc6032ce6522aded6048f1d3fe93fce (diff) | |
download | u-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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/pci-uclass.c | 51 |
1 files changed, 36 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 | ||
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 | 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 | ||
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) |
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) | ||
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 | ||
1431 | int dm_pci_find_ext_capability(struct udevice *dev, int cap) | ||
1432 | { | ||
1433 | return dm_pci_find_next_ext_capability(dev, 0, cap); | ||
1434 | } | ||
1435 | |||
1415 | UCLASS_DRIVER(pci) = { | 1436 | UCLASS_DRIVER(pci) = { |
1416 | .id = UCLASS_PCI, | 1437 | .id = UCLASS_PCI, |
1417 | .name = "pci", | 1438 | .name = "pci", |