[PATCH] drivers: pci: dwc: dynamically set pci region limit

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



commit 89473aa9ab26 ("PCI: dwc: Add iATU regions size detection procedure")
hardcodes the pci region limit to 4G. This causes regression on
systems with PCI memory region higher than 4G.

Fix this by dynamically setting pci region limit based on maximum
size of memory ranges in the PCI device tree node.

Fixes: 89473aa9ab26 ("PCI: dwc: Add iATU regions size detection procedure")
Signed-off-by: Shyam Saini <shyamsaini@xxxxxxxxxxxxxxxxxxx>
---
 drivers/pci/controller/dwc/pcie-designware.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 250cf7f40b85..9b8975b35dd9 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -783,6 +783,9 @@ static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes)
 void dw_pcie_iatu_detect(struct dw_pcie *pci)
 {
 	int max_region, ob, ib;
+	struct dw_pcie_rp *pp = &pci->pp;
+	struct resource_entry *entry;
+	u64 max_mem_sz = 0;
 	u32 val, min, dir;
 	u64 max;
 
@@ -832,10 +835,25 @@ void dw_pcie_iatu_detect(struct dw_pcie *pci)
 		max = 0;
 	}
 
+	resource_list_for_each_entry(entry, &pp->bridge->windows) {
+		if (resource_type(entry->res) != IORESOURCE_MEM)
+			continue;
+		max_mem_sz = (max_mem_sz < resource_size(entry->res)) ?
+						resource_size(entry->res) : max_mem_sz;
+	}
+
+	if (max_mem_sz <= SZ_4G)
+		pci->region_limit = (max << 32) | (SZ_4G - 1);
+	else if ((max_mem_sz > SZ_4G) && (max_mem_sz <= SZ_8G))
+		pci->region_limit = (max << 32) | (SZ_8G - 1);
+	else if ((max_mem_sz > SZ_8G) && (max_mem_sz <= SZ_16G))
+		pci->region_limit = (max << 32) | (SZ_16G - 1);
+	else
+		pci->region_limit = (max << 32) | (SZ_32G - 1);
+
 	pci->num_ob_windows = ob;
 	pci->num_ib_windows = ib;
 	pci->region_align = 1 << fls(min);
-	pci->region_limit = (max << 32) | (SZ_4G - 1);
 
 	dev_info(pci->dev, "iATU: unroll %s, %u ob, %u ib, align %uK, limit %lluG\n",
 		 dw_pcie_cap_is(pci, IATU_UNROLL) ? "T" : "F",
-- 
2.34.1





[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux