pci: pci-uclass: Add multi entry support for memory regions

Enable PCI memory regions in ranges property to be of multiple entry.
This helps to add support for SoC's like OcteonTX/TX2 where every
peripheral is on PCI bus.

Signed-off-by: Suneel Garapati <sgarapati@marvell.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
Suneel Garapati 2019-10-19 17:10:20 -07:00 committed by Stefan Roese
parent bc30140d20
commit 4cf56ec07f
6 changed files with 43 additions and 5 deletions

View file

@ -666,8 +666,9 @@
bus-range = <0x00 0xff>;
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x02000000 0 0x30000000 0x30000000 0 0x2000
0x01000000 0 0x40000000 0x40000000 0 0x2000>;
ranges = <0x02000000 0 0x30000000 0x30000000 0 0x2000 // MEM0
0x02000000 0 0x31000000 0x31000000 0 0x2000 // MEM1
0x01000000 0 0x40000000 0x40000000 0 0x2000>;
sandbox,dev-info = <0x08 0x00 0x1234 0x5678
0x0c 0x00 0x1234 0x5678
0x10 0x00 0x1234 0x5678>;

View file

@ -181,6 +181,7 @@ CONFIG_NVME=y
CONFIG_PCI=y
CONFIG_DM_PCI=y
CONFIG_DM_PCI_COMPAT=y
CONFIG_PCI_REGION_MULTI_ENTRY=y
CONFIG_PCI_SANDBOX=y
CONFIG_PHY=y
CONFIG_PHY_SANDBOX=y

View file

@ -136,6 +136,7 @@ CONFIG_NVME=y
CONFIG_PCI=y
CONFIG_DM_PCI=y
CONFIG_DM_PCI_COMPAT=y
CONFIG_PCI_REGION_MULTI_ENTRY=y
CONFIG_PCI_SANDBOX=y
CONFIG_PHY=y
CONFIG_PHY_SANDBOX=y

View file

@ -43,6 +43,16 @@ config PCI_PNP
help
Enable PCI memory and I/O space resource allocation and assignment.
config PCI_REGION_MULTI_ENTRY
bool "Enable Multiple entries of region type MEMORY in ranges for PCI"
depends on PCI || DM_PCI
default n
help
Enable PCI memory regions to be of multiple entry. Multiple entry
here refers to allow more than one count of address ranges for MEMORY
region type. This helps to add support for SoC's like OcteonTX/TX2
where every peripheral is on the PCI bus.
config PCIE_ECAM_GENERIC
bool "Generic ECAM-based PCI host controller support"
default n

View file

@ -936,10 +936,13 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node,
}
pos = -1;
for (i = 0; i < hose->region_count; i++) {
if (hose->regions[i].flags == type)
pos = i;
if (!IS_ENABLED(CONFIG_PCI_REGION_MULTI_ENTRY)) {
for (i = 0; i < hose->region_count; i++) {
if (hose->regions[i].flags == type)
pos = i;
}
}
if (pos == -1)
pos = hose->region_count++;
debug(" - type=%d, pos=%d\n", type, pos);

View file

@ -354,3 +354,25 @@ static int dm_test_pci_on_bus(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_pci_on_bus, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
/*
* Test support for multiple memory regions enabled via
* CONFIG_PCI_REGION_MULTI_ENTRY. When this feature is not enabled,
* only the last region of one type is stored. In this test-case,
* we have 2 memory regions, the first at 0x3000.0000 and the 2nd
* at 0x3100.0000. A correct test results now in BAR1 located at
* 0x3000.0000.
*/
static int dm_test_pci_region_multi(struct unit_test_state *uts)
{
struct udevice *dev;
ulong mem_addr;
/* Test memory BAR1 on bus#1 */
ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &dev));
mem_addr = dm_pci_read_bar32(dev, 1);
ut_asserteq(mem_addr, 0x30000000);
return 0;
}
DM_TEST(dm_test_pci_region_multi, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);