diff options
-rw-r--r-- | arch/powerpc/sysdev/fsl_msi.c | 9 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_pci.c | 52 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_pci.h | 1 |
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 | ||
28 | LIST_HEAD(msi_head); | 29 | LIST_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 | ||
37 | static int fsl_pcie_bus_fixup; | 37 | static int fsl_pcie_bus_fixup, is_mpc83xx_pci; |
38 | 38 | ||
39 | static void __init quirk_fsl_pcie_header(struct pci_dev *dev) | 39 | static 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 | ||
433 | struct 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 | ||
441 | static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn) | 450 | static 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 | |||
698 | u64 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 { | |||
88 | extern int fsl_add_bridge(struct device_node *dev, int is_primary); | 88 | extern int fsl_add_bridge(struct device_node *dev, int is_primary); |
89 | extern void fsl_pcibios_fixup_bus(struct pci_bus *bus); | 89 | extern void fsl_pcibios_fixup_bus(struct pci_bus *bus); |
90 | extern int mpc83xx_add_bridge(struct device_node *dev); | 90 | extern int mpc83xx_add_bridge(struct device_node *dev); |
91 | u64 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__ */ |