瀏覽代碼

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

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>
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
Grant Likely 16 年之前
父節點
當前提交
e489a44e24
共有 1 個文件被更改,包括 10 次插入14 次删除
  1. 10 14
      arch/powerpc/platforms/52xx/mpc52xx_pci.c

+ 10 - 14
arch/powerpc/platforms/52xx/mpc52xx_pci.c

@@ -19,14 +19,6 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 
 
 
 
-/* ======================================================================== */
-/* PCI windows config                                                       */
-/* ======================================================================== */
-
-#define MPC52xx_PCI_TARGET_IO	0xf0000000
-#define MPC52xx_PCI_TARGET_MEM	0x00000000
-
-
 /* ======================================================================== */
 /* ======================================================================== */
 /* Structures mapping & Defines for PCI Unit                                */
 /* Structures mapping & Defines for PCI Unit                                */
 /* ======================================================================== */
 /* ======================================================================== */
@@ -244,7 +236,7 @@ static struct pci_ops mpc52xx_pci_ops = {
 
 
 static void __init
 static void __init
 mpc52xx_pci_setup(struct pci_controller *hose,
 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;
 	struct resource *res;
 	u32 tmp;
 	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 */
 	/* 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->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);
 	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
 	/* Finish setting up PCI using values obtained by
 	 * pci_proces_bridge_OF_ranges */
 	 * pci_proces_bridge_OF_ranges */
-	mpc52xx_pci_setup(hose, pci_regs);
+	mpc52xx_pci_setup(hose, pci_regs, rsrc.start);
 
 
 	return 0;
 	return 0;
 }
 }