aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c9
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c52
-rw-r--r--arch/powerpc/sysdev/fsl_pci.h1
3 files changed, 55 insertions, 7 deletions
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 87991d3abba..20cdcd2b0ee 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -24,6 +24,7 @@
24#include <asm/ppc-pci.h> 24#include <asm/ppc-pci.h>
25#include <asm/mpic.h> 25#include <asm/mpic.h>
26#include "fsl_msi.h" 26#include "fsl_msi.h"
27#include "fsl_pci.h"
27 28
28LIST_HEAD(msi_head); 29LIST_HEAD(msi_head);
29 30
@@ -125,13 +126,11 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
125{ 126{
126 struct fsl_msi *msi_data = fsl_msi_data; 127 struct fsl_msi *msi_data = fsl_msi_data;
127 struct pci_controller *hose = pci_bus_to_host(pdev->bus); 128 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
128 u32 base = 0; 129 u64 base = fsl_pci_immrbar_base(hose);
129 130
130 pci_bus_read_config_dword(hose->bus, 131 msg->address_lo = msi_data->msi_addr_lo + lower_32_bits(base);
131 PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base); 132 msg->address_hi = msi_data->msi_addr_hi + upper_32_bits(base);
132 133
133 msg->address_lo = msi_data->msi_addr_lo + base;
134 msg->address_hi = msi_data->msi_addr_hi;
135 msg->data = hwirq; 134 msg->data = hwirq;
136 135
137 pr_debug("%s: allocated srs: %d, ibs: %d\n", 136 pr_debug("%s: allocated srs: %d, ibs: %d\n",
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 4ae93322525..505c8f0ece9 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * MPC83xx/85xx/86xx PCI/PCIE support routing. 2 * MPC83xx/85xx/86xx PCI/PCIE support routing.
3 * 3 *
4 * Copyright 2007-2009 Freescale Semiconductor, Inc. 4 * Copyright 2007-2010 Freescale Semiconductor, Inc.
5 * Copyright 2008-2009 MontaVista Software, Inc. 5 * Copyright 2008-2009 MontaVista Software, Inc.
6 * 6 *
7 * Initial author: Xianghua Xiao <x.xiao@freescale.com> 7 * Initial author: Xianghua Xiao <x.xiao@freescale.com>
@@ -34,7 +34,7 @@
34#include <sysdev/fsl_soc.h> 34#include <sysdev/fsl_soc.h>
35#include <sysdev/fsl_pci.h> 35#include <sysdev/fsl_pci.h>
36 36
37static int fsl_pcie_bus_fixup; 37static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
38 38
39static void __init quirk_fsl_pcie_header(struct pci_dev *dev) 39static void __init quirk_fsl_pcie_header(struct pci_dev *dev)
40{ 40{
@@ -430,6 +430,13 @@ struct mpc83xx_pcie_priv {
430 u32 dev_base; 430 u32 dev_base;
431}; 431};
432 432
433struct pex_inbound_window {
434 u32 ar;
435 u32 tar;
436 u32 barl;
437 u32 barh;
438};
439
433/* 440/*
434 * With the convention of u-boot, the PCIE outbound window 0 serves 441 * With the convention of u-boot, the PCIE outbound window 0 serves
435 * as configuration transactions outbound. 442 * as configuration transactions outbound.
@@ -437,6 +444,8 @@ struct mpc83xx_pcie_priv {
437#define PEX_OUTWIN0_BAR 0xCA4 444#define PEX_OUTWIN0_BAR 0xCA4
438#define PEX_OUTWIN0_TAL 0xCA8 445#define PEX_OUTWIN0_TAL 0xCA8
439#define PEX_OUTWIN0_TAH 0xCAC 446#define PEX_OUTWIN0_TAH 0xCAC
447#define PEX_RC_INWIN_BASE 0xE60
448#define PEX_RCIWARn_EN 0x1
440 449
441static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn) 450static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn)
442{ 451{
@@ -604,6 +613,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
604 const int *bus_range; 613 const int *bus_range;
605 int primary; 614 int primary;
606 615
616 is_mpc83xx_pci = 1;
617
607 if (!of_device_is_available(dev)) { 618 if (!of_device_is_available(dev)) {
608 pr_warning("%s: disabled by the firmware.\n", 619 pr_warning("%s: disabled by the firmware.\n",
609 dev->full_name); 620 dev->full_name);
@@ -683,3 +694,40 @@ err0:
683 return ret; 694 return ret;
684} 695}
685#endif /* CONFIG_PPC_83xx */ 696#endif /* CONFIG_PPC_83xx */
697
698u64 fsl_pci_immrbar_base(struct pci_controller *hose)
699{
700#ifdef CONFIG_PPC_83xx
701 if (is_mpc83xx_pci) {
702 struct mpc83xx_pcie_priv *pcie = hose->dn->data;
703 struct pex_inbound_window *in;
704 int i;
705
706 /* Walk the Root Complex Inbound windows to match IMMR base */
707 in = pcie->cfg_type0 + PEX_RC_INWIN_BASE;
708 for (i = 0; i < 4; i++) {
709 /* not enabled, skip */
710 if (!in_le32(&in[i].ar) & PEX_RCIWARn_EN)
711 continue;
712
713 if (get_immrbase() == in_le32(&in[i].tar))
714 return (u64)in_le32(&in[i].barh) << 32 |
715 in_le32(&in[i].barl);
716 }
717
718 printk(KERN_WARNING "could not find PCI BAR matching IMMR\n");
719 }
720#endif
721
722#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
723 if (!is_mpc83xx_pci) {
724 u32 base;
725
726 pci_bus_read_config_dword(hose->bus,
727 PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base);
728 return base;
729 }
730#endif
731
732 return 0;
733}
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index a9d8bbebed8..8ad72a11f77 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -88,6 +88,7 @@ struct ccsr_pci {
88extern int fsl_add_bridge(struct device_node *dev, int is_primary); 88extern int fsl_add_bridge(struct device_node *dev, int is_primary);
89extern void fsl_pcibios_fixup_bus(struct pci_bus *bus); 89extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
90extern int mpc83xx_add_bridge(struct device_node *dev); 90extern int mpc83xx_add_bridge(struct device_node *dev);
91u64 fsl_pci_immrbar_base(struct pci_controller *hose);
91 92
92#endif /* __POWERPC_FSL_PCI_H */ 93#endif /* __POWERPC_FSL_PCI_H */
93#endif /* __KERNEL__ */ 94#endif /* __KERNEL__ */