As of today, if a DDW is created and can't map the whole partition, it's
removed and the default DMA window "ibm,dma-window" is used instead.

Usually this DDW is bigger than the default DMA window, so it would be
better to make use of it instead.

Signed-off-by: Leonardo Bras <leobra...@gmail.com>
---
 arch/powerpc/platforms/pseries/iommu.c | 28 +++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/iommu.c 
b/arch/powerpc/platforms/pseries/iommu.c
index 4fcf00016fb1..2d217cda4075 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -685,7 +685,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
        struct iommu_table *tbl;
        struct device_node *dn, *pdn;
        struct pci_dn *ppci;
-       const __be32 *dma_window = NULL;
+       const __be32 *dma_window = NULL, *alt_dma_window = NULL;
 
        dn = pci_bus_to_OF_node(bus);
 
@@ -699,8 +699,13 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus 
*bus)
                        break;
        }
 
+       /* If there is a DDW available, use it instead */
+       alt_dma_window = of_get_property(pdn, DIRECT64_PROPNAME, NULL);
+       if (alt_dma_window)
+               dma_window = alt_dma_window;
+
        if (dma_window == NULL) {
-               pr_debug("  no ibm,dma-window property !\n");
+               pr_debug("  no ibm,dma-window nor 
linux,direct64-ddr-window-info property !\n");
                return;
        }
 
@@ -1166,16 +1171,19 @@ static u64 enable_ddw(struct pci_dev *dev, struct 
device_node *pdn)
                          query.page_size);
                goto out_failed;
        }
+
        /* verify the window * number of ptes will map the partition */
-       /* check largest block * page size > max memory hotplug addr */
        max_addr = ddw_memory_hotplug_max();
        if (query.largest_available_block < (max_addr >> page_shift)) {
-               dev_dbg(&dev->dev, "can't map partition max 0x%llx with %llu "
-                         "%llu-sized pages\n", max_addr,  
query.largest_available_block,
-                         1ULL << page_shift);
-               goto out_failed;
+               dev_dbg(&dev->dev, "can't map partition max 0x%llx with %llu 
%llu-sized pages\n",
+                       max_addr, query.largest_available_block,
+                       1ULL << page_shift);
+
+               len = order_base_2(query.largest_available_block << page_shift);
+       } else {
+               len = order_base_2(max_addr);
        }
-       len = order_base_2(max_addr);
+
        win64 = kzalloc(sizeof(struct property), GFP_KERNEL);
        if (!win64) {
                dev_info(&dev->dev,
@@ -1229,7 +1237,9 @@ static u64 enable_ddw(struct pci_dev *dev, struct 
device_node *pdn)
        list_add(&window->list, &direct_window_list);
        spin_unlock(&direct_window_list_lock);
 
-       dma_addr = be64_to_cpu(ddwprop->dma_base);
+       /* Only returns the dma_addr if DDW maps the whole partition */
+       if (len == order_base_2(max_addr))
+               dma_addr = be64_to_cpu(ddwprop->dma_base);
        goto out_unlock;
 
 out_free_window:
-- 
2.25.4

Reply via email to