[PATCH 01/13] sparc/PCI: Use correct offset for bus address to resource

2017-04-20 Thread Yinghai Lu
After we added 64bit mmio parsing, we got some "no compatible bridge window"
warning on anther new model that support 64bit resource.

It turns out that we can not use mem_space.start as 64bit mem space
offset, aka there is mem_space.start != offset.

Use child_phys_addr to calculate exact offset and record offset in
pbm.

After patch we get correct offset.

/pci@305: PCI IO [io  0x2007e-0x2007e0fff] offset 2007e
/pci@305: PCI MEM [mem 0x20010-0x27eff] offset 2
/pci@305: PCI MEM64 [mem 0x20001-0x2000d] offset 2
...
pci_sun4v f02ae7f8: PCI host bridge to bus :00
pci_bus :00: root bus resource [io  0x2007e-0x2007e0fff] (bus 
address [0x-0xfff])
pci_bus :00: root bus resource [mem 0x20010-0x27eff] (bus 
address [0x0010-0x7eff])
pci_bus :00: root bus resource [mem 0x20001-0x2000d] (bus 
address [0x1-0xd])

-v3: put back mem64_offset, as we found T4 has mem_offset != mem64_offset
 check overlapping between mem64_space and mem_space.
-v7: after new pci_mmap_page_range patches.
-v8: remove change in pci_resource_to_user()

Signed-off-by: Yinghai Lu 
Tested-by: Khalid Aziz 
Cc: sparcli...@vger.kernel.org
---
 arch/sparc/kernel/pci.c|  6 +++---
 arch/sparc/kernel/pci_common.c | 32 
 arch/sparc/kernel/pci_impl.h   |  4 
 3 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 7eceaa1..c5cf813 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -663,12 +663,12 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
printk("PCI: Scanning PBM %s\n", node->full_name);
 
pci_add_resource_offset(, >io_space,
-   pbm->io_space.start);
+   pbm->io_offset);
pci_add_resource_offset(, >mem_space,
-   pbm->mem_space.start);
+   pbm->mem_offset);
if (pbm->mem64_space.flags)
pci_add_resource_offset(, >mem64_space,
-   pbm->mem_space.start);
+   pbm->mem64_offset);
pbm->busn.start = pbm->pci_first_busno;
pbm->busn.end   = pbm->pci_last_busno;
pbm->busn.flags = IORESOURCE_BUS;
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 33524c1..76998f8 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -410,13 +410,16 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 
for (i = 0; i < num_pbm_ranges; i++) {
const struct linux_prom_pci_ranges *pr = _ranges[i];
-   unsigned long a, size;
+   unsigned long a, size, region_a;
u32 parent_phys_hi, parent_phys_lo;
+   u32 child_phys_mid, child_phys_lo;
u32 size_hi, size_lo;
int type;
 
parent_phys_hi = pr->parent_phys_hi;
parent_phys_lo = pr->parent_phys_lo;
+   child_phys_mid = pr->child_phys_mid;
+   child_phys_lo = pr->child_phys_lo;
if (tlb_type == hypervisor)
parent_phys_hi &= 0x0fff;
 
@@ -426,6 +429,8 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
type = (pr->child_phys_hi >> 24) & 0x3;
a = (((unsigned long)parent_phys_hi << 32UL) |
 ((unsigned long)parent_phys_lo  <<  0UL));
+   region_a = (((unsigned long)child_phys_mid << 32UL) |
+((unsigned long)child_phys_lo  <<  0UL));
size = (((unsigned long)size_hi << 32UL) |
((unsigned long)size_lo  <<  0UL));
 
@@ -440,6 +445,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
pbm->io_space.start = a;
pbm->io_space.end = a + size - 1UL;
pbm->io_space.flags = IORESOURCE_IO;
+   pbm->io_offset = a - region_a;
saw_io = 1;
break;
 
@@ -448,6 +454,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
pbm->mem_space.start = a;
pbm->mem_space.end = a + size - 1UL;
pbm->mem_space.flags = IORESOURCE_MEM;
+   pbm->mem_offset = a - region_a;
saw_mem = 1;
break;
 
@@ -456,6 +463,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
pbm->mem64_space.start = a;
pbm->mem64_space.end = a + size - 1UL;
pbm->mem64_space.flags = IORESOURCE_MEM;
+   

[PATCH 01/13] sparc/PCI: Use correct offset for bus address to resource

2017-04-20 Thread Yinghai Lu
After we added 64bit mmio parsing, we got some "no compatible bridge window"
warning on anther new model that support 64bit resource.

It turns out that we can not use mem_space.start as 64bit mem space
offset, aka there is mem_space.start != offset.

Use child_phys_addr to calculate exact offset and record offset in
pbm.

After patch we get correct offset.

/pci@305: PCI IO [io  0x2007e-0x2007e0fff] offset 2007e
/pci@305: PCI MEM [mem 0x20010-0x27eff] offset 2
/pci@305: PCI MEM64 [mem 0x20001-0x2000d] offset 2
...
pci_sun4v f02ae7f8: PCI host bridge to bus :00
pci_bus :00: root bus resource [io  0x2007e-0x2007e0fff] (bus 
address [0x-0xfff])
pci_bus :00: root bus resource [mem 0x20010-0x27eff] (bus 
address [0x0010-0x7eff])
pci_bus :00: root bus resource [mem 0x20001-0x2000d] (bus 
address [0x1-0xd])

-v3: put back mem64_offset, as we found T4 has mem_offset != mem64_offset
 check overlapping between mem64_space and mem_space.
-v7: after new pci_mmap_page_range patches.
-v8: remove change in pci_resource_to_user()

Signed-off-by: Yinghai Lu 
Tested-by: Khalid Aziz 
Cc: sparcli...@vger.kernel.org
---
 arch/sparc/kernel/pci.c|  6 +++---
 arch/sparc/kernel/pci_common.c | 32 
 arch/sparc/kernel/pci_impl.h   |  4 
 3 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 7eceaa1..c5cf813 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -663,12 +663,12 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
printk("PCI: Scanning PBM %s\n", node->full_name);
 
pci_add_resource_offset(, >io_space,
-   pbm->io_space.start);
+   pbm->io_offset);
pci_add_resource_offset(, >mem_space,
-   pbm->mem_space.start);
+   pbm->mem_offset);
if (pbm->mem64_space.flags)
pci_add_resource_offset(, >mem64_space,
-   pbm->mem_space.start);
+   pbm->mem64_offset);
pbm->busn.start = pbm->pci_first_busno;
pbm->busn.end   = pbm->pci_last_busno;
pbm->busn.flags = IORESOURCE_BUS;
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 33524c1..76998f8 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -410,13 +410,16 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 
for (i = 0; i < num_pbm_ranges; i++) {
const struct linux_prom_pci_ranges *pr = _ranges[i];
-   unsigned long a, size;
+   unsigned long a, size, region_a;
u32 parent_phys_hi, parent_phys_lo;
+   u32 child_phys_mid, child_phys_lo;
u32 size_hi, size_lo;
int type;
 
parent_phys_hi = pr->parent_phys_hi;
parent_phys_lo = pr->parent_phys_lo;
+   child_phys_mid = pr->child_phys_mid;
+   child_phys_lo = pr->child_phys_lo;
if (tlb_type == hypervisor)
parent_phys_hi &= 0x0fff;
 
@@ -426,6 +429,8 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
type = (pr->child_phys_hi >> 24) & 0x3;
a = (((unsigned long)parent_phys_hi << 32UL) |
 ((unsigned long)parent_phys_lo  <<  0UL));
+   region_a = (((unsigned long)child_phys_mid << 32UL) |
+((unsigned long)child_phys_lo  <<  0UL));
size = (((unsigned long)size_hi << 32UL) |
((unsigned long)size_lo  <<  0UL));
 
@@ -440,6 +445,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
pbm->io_space.start = a;
pbm->io_space.end = a + size - 1UL;
pbm->io_space.flags = IORESOURCE_IO;
+   pbm->io_offset = a - region_a;
saw_io = 1;
break;
 
@@ -448,6 +454,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
pbm->mem_space.start = a;
pbm->mem_space.end = a + size - 1UL;
pbm->mem_space.flags = IORESOURCE_MEM;
+   pbm->mem_offset = a - region_a;
saw_mem = 1;
break;
 
@@ -456,6 +463,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
pbm->mem64_space.start = a;
pbm->mem64_space.end = a + size - 1UL;
pbm->mem64_space.flags = IORESOURCE_MEM;
+   pbm->mem64_offset = a - region_a;