All of lore.kernel.org
 help / color / mirror / Atom feed
From: Valentine Barshak <vbarshak@ru.mvista.com>
To: linuxppc-dev@ozlabs.org
Subject: [RFC] [PATCH] PowerPC: Add 64-bit phys addr support to 32-bit pci.
Date: Tue, 18 Sep 2007 20:07:54 +0400	[thread overview]
Message-ID: <20070918160754.GA22698@ru.mvista.com> (raw)
In-Reply-To: <DF9456FB-459D-4800-B994-D9B198096069@kernel.crashing.org>

Currently pci_32 doesn't support 64-bit physical addresses, while
PowerPC440 platform has PCI space typically mapped above 4GB range.
The patch adds 64-bit physical address support to 32-bit PCI code
in order to bring-up PCI on 44x platform.

Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
---
 arch/powerpc/kernel/iomap.c  |    4 +--
 arch/powerpc/kernel/pci_32.c |   56 +++++++++++++++++++++++++++++--------------
 2 files changed, 41 insertions(+), 19 deletions(-)

diff -ruN linux-2.6.orig/arch/powerpc/kernel/iomap.c linux-2.6/arch/powerpc/kernel/iomap.c
--- linux-2.6.orig/arch/powerpc/kernel/iomap.c	2007-09-18 15:32:19.000000000 +0400
+++ linux-2.6/arch/powerpc/kernel/iomap.c	2007-09-18 17:26:35.000000000 +0400
@@ -119,8 +119,8 @@
 
 void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
 {
-	unsigned long start = pci_resource_start(dev, bar);
-	unsigned long len = pci_resource_len(dev, bar);
+	resource_size_t start = pci_resource_start(dev, bar);
+	resource_size_t len = pci_resource_len(dev, bar);
 	unsigned long flags = pci_resource_flags(dev, bar);
 
 	if (!len)
diff -ruN linux-2.6.orig/arch/powerpc/kernel/pci_32.c linux-2.6/arch/powerpc/kernel/pci_32.c
--- linux-2.6.orig/arch/powerpc/kernel/pci_32.c	2007-09-18 15:32:19.000000000 +0400
+++ linux-2.6/arch/powerpc/kernel/pci_32.c	2007-09-18 18:17:00.000000000 +0400
@@ -105,7 +105,7 @@
 {
 	struct pci_controller* hose = (struct pci_controller *)dev->sysdata;
 	int i;
-	unsigned long offset;
+	resource_size_t offset;
 
 	if (!hose) {
 		printk(KERN_ERR "No hose for PCI dev %s!\n", pci_name(dev));
@@ -115,7 +115,7 @@
 		struct resource *res = dev->resource + i;
 		if (!res->flags)
 			continue;
-		if (res->end == 0xffffffff) {
+		if (res->end == (resource_size_t) -1) {
 			DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n",
 			    pci_name(dev), i, (u64)res->start, (u64)res->end);
 			res->end -= res->start;
@@ -148,7 +148,7 @@
 void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
 			struct resource *res)
 {
-	unsigned long offset = 0;
+	resource_size_t offset = 0;
 	struct pci_controller *hose = dev->sysdata;
 
 	if (hose && res->flags & IORESOURCE_IO)
@@ -163,7 +163,7 @@
 void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
 			     struct pci_bus_region *region)
 {
-	unsigned long offset = 0;
+	resource_size_t offset = 0;
 	struct pci_controller *hose = dev->sysdata;
 
 	if (hose && res->flags & IORESOURCE_IO)
@@ -439,7 +439,7 @@
 	u8 io_base_lo, io_limit_lo;
 	u16 mem_base, mem_limit;
 	u16 cmd;
-	unsigned long start, end, off;
+	resource_size_t start, end, off;
 	struct pci_controller *hose = dev->sysdata;
 
 	if (!hose) {
@@ -843,16 +843,28 @@
 }
 EXPORT_SYMBOL(pci_device_from_OF_node);
 
+
+static inline u64 pci_get_range64(u32 *r)
+{
+	return (((u64)r[0] << 32) | r[1]);
+}
+
+
 void __init
 pci_process_bridge_OF_ranges(struct pci_controller *hose,
 			   struct device_node *dev, int primary)
 {
 	static unsigned int static_lc_ranges[256] __initdata;
 	const unsigned int *dt_ranges;
-	unsigned int *lc_ranges, *ranges, *prev, size;
+	unsigned int *lc_ranges, *ranges, *prev;
 	int rlen = 0, orig_rlen;
 	int memno = 0;
 	struct resource *res;
+	u32 prev_pci_space, pci_space;
+	u64 prev_pci_addr, pci_addr;
+	u64 prev_size, size;
+	phys_addr_t cpu_phys_addr;
+	
 	int np, na = of_n_addr_cells(dev);
 	np = na + 5;
 
@@ -879,11 +891,18 @@
 	prev = NULL;
 	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
 		if (prev) {
-			if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
-				(prev[2] + prev[na+4]) == ranges[2] &&
-				(prev[na+2] + prev[na+4]) == ranges[na+2]) {
-				prev[na+4] += ranges[na+4];
+			prev_pci_space = prev[0];
+			prev_pci_addr = pci_get_range64(&prev[1]);
+			prev_size = pci_get_range64(&prev[na+3]);
+			pci_space = ranges[0];
+			pci_addr = pci_get_range64(&ranges[1]);
+			if ((prev_pci_space == pci_space) && 
+			    ((prev_pci_addr + prev_size) == pci_addr)) {
+				size = pci_get_range64(&ranges[na+3]);
+				prev_size += size;
 				ranges[0] = 0;
+				prev[na+3] = (u32)((prev_size >> 32) & 0xffffffff);
+				prev[na+4] = (u32)(prev_size & 0xffffffff);
 				ranges += np;
 				continue;
 			}
@@ -904,21 +923,22 @@
 	rlen = orig_rlen;
 	while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
 		res = NULL;
-		size = ranges[na+4];
-		switch ((ranges[0] >> 24) & 0x3) {
+		size = pci_get_range64(&ranges[na+3]);
+		pci_space = ranges[0] >> 24;
+		switch (pci_space & 0x3) {
 		case 1:		/* I/O space */
 			if (ranges[2] != 0)
 				break;
-			hose->io_base_phys = ranges[na+2];
+			hose->io_base_phys = of_translate_address(dev, &ranges[3]);
 			/* limit I/O space to 16MB */
 			if (size > 0x01000000)
 				size = 0x01000000;
-			hose->io_base_virt = ioremap(ranges[na+2], size);
+			hose->io_base_virt = ioremap(hose->io_base_phys, size);
 			if (primary)
 				isa_io_base = (unsigned long) hose->io_base_virt;
 			res = &hose->io_resource;
 			res->flags = IORESOURCE_IO;
-			res->start = ranges[2];
+			res->start = pci_get_range64(&ranges[1]);
 			DBG("PCI: IO 0x%llx -> 0x%llx\n",
 			    (u64)res->start, (u64)res->start + size - 1);
 			break;
@@ -933,14 +953,16 @@
 			}
 			while (memno < 3 && hose->mem_resources[memno].flags)
 				++memno;
+			pci_addr = pci_get_range64(&ranges[1]);
+			cpu_phys_addr = of_translate_address(dev, &ranges[3]);
 			if (memno == 0)
-				hose->pci_mem_offset = ranges[na+2] - ranges[2];
+				hose->pci_mem_offset = (u64)cpu_phys_addr - pci_addr;
 			if (memno < 3) {
 				res = &hose->mem_resources[memno];
 				res->flags = IORESOURCE_MEM;
 				if(ranges[0] & 0x40000000)
 					res->flags |= IORESOURCE_PREFETCH;
-				res->start = ranges[na+2];
+				res->start = cpu_phys_addr;
 				DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno,
 				    (u64)res->start, (u64)res->start + size - 1);
 			}

  reply	other threads:[~2007-09-18 16:09 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-18 14:44 [RFC] [PATCH] PowerPC: Add 64-bit phys addr support to 32-bit pci Valentine Barshak
2007-09-18 14:52 ` Kumar Gala
2007-09-18 15:01   ` Valentine Barshak
2007-09-18 15:13     ` Kumar Gala
2007-09-18 16:07       ` Valentine Barshak [this message]
2007-09-18 18:18         ` Vitaly Bordug
2007-09-18 21:38           ` Benjamin Herrenschmidt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070918160754.GA22698@ru.mvista.com \
    --to=vbarshak@ru.mvista.com \
    --cc=linuxppc-dev@ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.