Patchwork powerpc/5200: Bugfix for PCI mapping of memory and IMMR

login
register
mail settings
Submitter Grant Likely
Date Jan. 27, 2009, 4:34 a.m.
Message ID <20090127043315.26160.43312.stgit@localhost.localdomain>
Download mbox | patch
Permalink /patch/20395/
State Accepted, archived
Delegated to: Grant Likely
Headers show

Comments

Grant Likely - Jan. 27, 2009, 4:34 a.m.
From: Grant Likely <grant.likely@secretlab.ca>

This patch ensures that memory gets properly mapped into the PCI
address space.  Without this patch, the memory window BAR is left
at whatever value happened to be loaded into the BAR when Linux
was booted.  Without this patch, memory could end up getting mapped
at any of the 1G address boundaries instead of at '0' where Linux
expects it.

Similarly, this patch also ensures that the internally memory mapped
registers (IMMR) are mapped to the correct PCI address range.

Without this patch, PCI appears to work correctly until a PCI
device is inserted which DMAs into memory.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

This is a bugfix that I intend to merge into 2.6.29 and once it is
mainlined get it added to the stable queue.  If you have a 5200 system,
please test and make sure it works for you.

Thanks
g.

 arch/powerpc/platforms/52xx/mpc52xx_pci.c |   24 ++++++++++--------------
 1 files changed, 10 insertions(+), 14 deletions(-)
Matt Sealey - Jan. 27, 2009, 5:56 p.m.
On Mon, Jan 26, 2009 at 10:34 PM, Grant Likely
<grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch ensures that memory gets properly mapped into the PCI
> address space.  Without this patch, the memory window BAR is left
> at whatever value happened to be loaded into the BAR when Linux
> was booted.  Without this patch, memory could end up getting mapped
> at any of the 1G address boundaries instead of at '0' where Linux
> expects it.
>
> Similarly, this patch also ensures that the internally memory mapped
> registers (IMMR) are mapped to the correct PCI address range.
>
> Without this patch, PCI appears to work correctly until a PCI
> device is inserted which DMAs into memory.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
> This is a bugfix that I intend to merge into 2.6.29 and once it is
> mainlined get it added to the stable queue.  If you have a 5200 system,
> please test and make sure it works for you.
>
> Thanks
> g.
>
>  arch/powerpc/platforms/52xx/mpc52xx_pci.c |   24 ++++++++++--------------
>  1 files changed, 10 insertions(+), 14 deletions(-)
>

This doesn't affect Efika, right?

What's the expected impact and how come nobody tried a DMA-capable PCI
card in an MPC5200B board before? :)
Grant Likely - Jan. 27, 2009, 6:03 p.m.
On Tue, Jan 27, 2009 at 10:56 AM, Matt Sealey <matt@genesi-usa.com> wrote:
> On Mon, Jan 26, 2009 at 10:34 PM, Grant Likely
> <grant.likely@secretlab.ca> wrote:
>> From: Grant Likely <grant.likely@secretlab.ca>
>>
>> This patch ensures that memory gets properly mapped into the PCI
>> address space.  Without this patch, the memory window BAR is left
>> at whatever value happened to be loaded into the BAR when Linux
>> was booted.  Without this patch, memory could end up getting mapped
>> at any of the 1G address boundaries instead of at '0' where Linux
>> expects it.
>>
>> Similarly, this patch also ensures that the internally memory mapped
>> registers (IMMR) are mapped to the correct PCI address range.
>>
>> Without this patch, PCI appears to work correctly until a PCI
>> device is inserted which DMAs into memory.
>>
>> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
>> ---
>>
>> This is a bugfix that I intend to merge into 2.6.29 and once it is
>> mainlined get it added to the stable queue.  If you have a 5200 system,
>> please test and make sure it works for you.
>>
>> Thanks
>> g.
>>
>>  arch/powerpc/platforms/52xx/mpc52xx_pci.c |   24 ++++++++++--------------
>>  1 files changed, 10 insertions(+), 14 deletions(-)
>>
>
> This doesn't affect Efika, right?

Correct

> What's the expected impact and how come nobody tried a DMA-capable PCI
> card in an MPC5200B board before? :)

Most of the board I have don't hit the bug, but only because on most
boards U-Boot is setting the BAR to a sane value.  I discovered the
bug on a custom board where u-boot didn't do the right thing with PCI.

g.
Wolfram Sang - Jan. 29, 2009, 9:49 p.m.
On Mon, Jan 26, 2009 at 09:34:36PM -0700, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> 
> This patch ensures that memory gets properly mapped into the PCI
> address space.  Without this patch, the memory window BAR is left
> at whatever value happened to be loaded into the BAR when Linux
> was booted.  Without this patch, memory could end up getting mapped
> at any of the 1G address boundaries instead of at '0' where Linux
> expects it.
> 
> Similarly, this patch also ensures that the internally memory mapped
> registers (IMMR) are mapped to the correct PCI address range.
> 
> Without this patch, PCI appears to work correctly until a PCI
> device is inserted which DMAs into memory.
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

No regression with a phyCORE-MPC5200B-tiny. U-Boot did probably the
right thing here...

Tested-by: Wolfram Sang <w.sang@pengutronix.de>

> ---
> 
> This is a bugfix that I intend to merge into 2.6.29 and once it is
> mainlined get it added to the stable queue.  If you have a 5200 system,
> please test and make sure it works for you.
> 
> Thanks
> g.
> 
>  arch/powerpc/platforms/52xx/mpc52xx_pci.c |   24 ++++++++++--------------
>  1 files changed, 10 insertions(+), 14 deletions(-)
> 
> 
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
> index c3f2c21..87ff522 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
> @@ -20,14 +20,6 @@
>  
>  
>  /* ======================================================================== */
> -/* PCI windows config                                                       */
> -/* ======================================================================== */
> -
> -#define MPC52xx_PCI_TARGET_IO	0xf0000000
> -#define MPC52xx_PCI_TARGET_MEM	0x00000000
> -
> -
> -/* ======================================================================== */
>  /* Structures mapping & Defines for PCI Unit                                */
>  /* ======================================================================== */
>  
> @@ -244,7 +236,7 @@ static struct pci_ops mpc52xx_pci_ops = {
>  
>  static void __init
>  mpc52xx_pci_setup(struct pci_controller *hose,
> -                  struct mpc52xx_pci __iomem *pci_regs)
> +                  struct mpc52xx_pci __iomem *pci_regs, phys_addr_t pci_phys)
>  {
>  	struct resource *res;
>  	u32 tmp;
> @@ -314,10 +306,14 @@ mpc52xx_pci_setup(struct pci_controller *hose,
>  	/* Set all the IWCR fields at once; they're in the same reg */
>  	out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2));
>  
> -	out_be32(&pci_regs->tbatr0,
> -		MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
> -	out_be32(&pci_regs->tbatr1,
> -		MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
> +	/* Map IMMR onto PCI bus */
> +	pci_phys &= 0xfffc0000; /* bar0 has only 14 significant bits */
> +	out_be32(&pci_regs->tbatr0, MPC52xx_PCI_TBATR_ENABLE | pci_phys);
> +	out_be32(&pci_regs->bar0, PCI_BASE_ADDRESS_MEM_PREFETCH | pci_phys);
> +
> +	/* Map memory onto PCI bus */
> +	out_be32(&pci_regs->tbatr1, MPC52xx_PCI_TBATR_ENABLE);
> +	out_be32(&pci_regs->bar1, PCI_BASE_ADDRESS_MEM_PREFETCH);
>  
>  	out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD | MPC52xx_PCI_TCR_WCT8);
>  
> @@ -414,7 +410,7 @@ mpc52xx_add_bridge(struct device_node *node)
>  
>  	/* Finish setting up PCI using values obtained by
>  	 * pci_proces_bridge_OF_ranges */
> -	mpc52xx_pci_setup(hose, pci_regs);
> +	mpc52xx_pci_setup(hose, pci_regs, rsrc.start);
>  
>  	return 0;
>  }
>
Andre Schwarz - Jan. 30, 2009, 8:33 a.m.
Matt Sealey wrote:
> On Mon, Jan 26, 2009 at 10:34 PM, Grant Likely
> <grant.likely@secretlab.ca> wrote:
>   
>> From: Grant Likely <grant.likely@secretlab.ca>
>>
>> This patch ensures that memory gets properly mapped into the PCI
>> address space.  Without this patch, the memory window BAR is left
>> at whatever value happened to be loaded into the BAR when Linux
>> was booted.  Without this patch, memory could end up getting mapped
>> at any of the 1G address boundaries instead of at '0' where Linux
>> expects it.
>>
>> Similarly, this patch also ensures that the internally memory mapped
>> registers (IMMR) are mapped to the correct PCI address range.
>>
>> Without this patch, PCI appears to work correctly until a PCI
>> device is inserted which DMAs into memory.
>>
>> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
>> ---
>>
>> This is a bugfix that I intend to merge into 2.6.29 and once it is
>> mainlined get it added to the stable queue.  If you have a 5200 system,
>> please test and make sure it works for you.
>>
>> Thanks
>> g.
>>
>>  arch/powerpc/platforms/52xx/mpc52xx_pci.c |   24 ++++++++++--------------
>>  1 files changed, 10 insertions(+), 14 deletions(-)
>>
>>     
>
> This doesn't affect Efika, right?
>
> What's the expected impact and how come nobody tried a DMA-capable PCI
> card in an MPC5200B board before? :)
>
>   
We're running a MPC5200B based board with an external FPGA pumping as 
much data into the CPU's memory as possible using scatter-gather DMA. No 
problems so far ... besides the lousy PCI target performance of the 
5200, of course. Of course we've been always running latest u-boot.

regards,
Andre


MATRIX VISION GmbH, Talstraße 16, DE-71570 Oppenweiler
Registergericht: Amtsgericht Stuttgart, HRB 271090
Geschäftsführer: Gerhard Thullner, Werner Armingeon, Uwe Furtner, Hans-Joachim Reich

Patch

diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index c3f2c21..87ff522 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -20,14 +20,6 @@ 
 
 
 /* ======================================================================== */
-/* PCI windows config                                                       */
-/* ======================================================================== */
-
-#define MPC52xx_PCI_TARGET_IO	0xf0000000
-#define MPC52xx_PCI_TARGET_MEM	0x00000000
-
-
-/* ======================================================================== */
 /* Structures mapping & Defines for PCI Unit                                */
 /* ======================================================================== */
 
@@ -244,7 +236,7 @@  static struct pci_ops mpc52xx_pci_ops = {
 
 static void __init
 mpc52xx_pci_setup(struct pci_controller *hose,
-                  struct mpc52xx_pci __iomem *pci_regs)
+                  struct mpc52xx_pci __iomem *pci_regs, phys_addr_t pci_phys)
 {
 	struct resource *res;
 	u32 tmp;
@@ -314,10 +306,14 @@  mpc52xx_pci_setup(struct pci_controller *hose,
 	/* Set all the IWCR fields at once; they're in the same reg */
 	out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2));
 
-	out_be32(&pci_regs->tbatr0,
-		MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
-	out_be32(&pci_regs->tbatr1,
-		MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
+	/* Map IMMR onto PCI bus */
+	pci_phys &= 0xfffc0000; /* bar0 has only 14 significant bits */
+	out_be32(&pci_regs->tbatr0, MPC52xx_PCI_TBATR_ENABLE | pci_phys);
+	out_be32(&pci_regs->bar0, PCI_BASE_ADDRESS_MEM_PREFETCH | pci_phys);
+
+	/* Map memory onto PCI bus */
+	out_be32(&pci_regs->tbatr1, MPC52xx_PCI_TBATR_ENABLE);
+	out_be32(&pci_regs->bar1, PCI_BASE_ADDRESS_MEM_PREFETCH);
 
 	out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD | MPC52xx_PCI_TCR_WCT8);
 
@@ -414,7 +410,7 @@  mpc52xx_add_bridge(struct device_node *node)
 
 	/* Finish setting up PCI using values obtained by
 	 * pci_proces_bridge_OF_ranges */
-	mpc52xx_pci_setup(hose, pci_regs);
+	mpc52xx_pci_setup(hose, pci_regs, rsrc.start);
 
 	return 0;
 }