diff options
Diffstat (limited to 'arch/powerpc/sysdev/fsl_pci.c')
-rw-r--r-- | arch/powerpc/sysdev/fsl_pci.c | 157 |
1 files changed, 97 insertions, 60 deletions
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index c37f46136321..ffb93ae9379b 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
@@ -38,15 +38,15 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci; | |||
38 | 38 | ||
39 | static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev) | 39 | static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev) |
40 | { | 40 | { |
41 | u8 progif; | 41 | u8 hdr_type; |
42 | 42 | ||
43 | /* if we aren't a PCIe don't bother */ | 43 | /* if we aren't a PCIe don't bother */ |
44 | if (!pci_find_capability(dev, PCI_CAP_ID_EXP)) | 44 | if (!pci_find_capability(dev, PCI_CAP_ID_EXP)) |
45 | return; | 45 | return; |
46 | 46 | ||
47 | /* if we aren't in host mode don't bother */ | 47 | /* if we aren't in host mode don't bother */ |
48 | pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); | 48 | pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type); |
49 | if (progif & 0x1) | 49 | if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) |
50 | return; | 50 | return; |
51 | 51 | ||
52 | dev->class = PCI_CLASS_BRIDGE_PCI << 8; | 52 | dev->class = PCI_CLASS_BRIDGE_PCI << 8; |
@@ -143,18 +143,20 @@ static void __init setup_pci_atmu(struct pci_controller *hose, | |||
143 | pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", | 143 | pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", |
144 | (u64)rsrc->start, (u64)resource_size(rsrc)); | 144 | (u64)rsrc->start, (u64)resource_size(rsrc)); |
145 | 145 | ||
146 | if (of_device_is_compatible(hose->dn, "fsl,qoriq-pcie-v2.2")) { | ||
147 | win_idx = 2; | ||
148 | start_idx = 0; | ||
149 | end_idx = 3; | ||
150 | } | ||
151 | |||
152 | pci = ioremap(rsrc->start, resource_size(rsrc)); | 146 | pci = ioremap(rsrc->start, resource_size(rsrc)); |
153 | if (!pci) { | 147 | if (!pci) { |
154 | dev_err(hose->parent, "Unable to map ATMU registers\n"); | 148 | dev_err(hose->parent, "Unable to map ATMU registers\n"); |
155 | return; | 149 | return; |
156 | } | 150 | } |
157 | 151 | ||
152 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { | ||
153 | if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) { | ||
154 | win_idx = 2; | ||
155 | start_idx = 0; | ||
156 | end_idx = 3; | ||
157 | } | ||
158 | } | ||
159 | |||
158 | /* Disable all windows (except powar0 since it's ignored) */ | 160 | /* Disable all windows (except powar0 since it's ignored) */ |
159 | for(i = 1; i < 5; i++) | 161 | for(i = 1; i < 5; i++) |
160 | out_be32(&pci->pow[i].powar, 0); | 162 | out_be32(&pci->pow[i].powar, 0); |
@@ -425,7 +427,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary) | |||
425 | struct pci_controller *hose; | 427 | struct pci_controller *hose; |
426 | struct resource rsrc; | 428 | struct resource rsrc; |
427 | const int *bus_range; | 429 | const int *bus_range; |
428 | u8 progif; | 430 | u8 hdr_type, progif; |
429 | 431 | ||
430 | if (!of_device_is_available(dev)) { | 432 | if (!of_device_is_available(dev)) { |
431 | pr_warning("%s: disabled\n", dev->full_name); | 433 | pr_warning("%s: disabled\n", dev->full_name); |
@@ -457,15 +459,17 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary) | |||
457 | setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, | 459 | setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, |
458 | PPC_INDIRECT_TYPE_BIG_ENDIAN); | 460 | PPC_INDIRECT_TYPE_BIG_ENDIAN); |
459 | 461 | ||
460 | early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif); | 462 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { |
461 | if ((progif & 1) == 1) { | 463 | /* For PCIE read HEADER_TYPE to identify controler mode */ |
462 | /* unmap cfg_data & cfg_addr separately if not on same page */ | 464 | early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type); |
463 | if (((unsigned long)hose->cfg_data & PAGE_MASK) != | 465 | if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) |
464 | ((unsigned long)hose->cfg_addr & PAGE_MASK)) | 466 | goto no_bridge; |
465 | iounmap(hose->cfg_data); | 467 | |
466 | iounmap(hose->cfg_addr); | 468 | } else { |
467 | pcibios_free_controller(hose); | 469 | /* For PCI read PROG to identify controller mode */ |
468 | return -ENODEV; | 470 | early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif); |
471 | if ((progif & 1) == 1) | ||
472 | goto no_bridge; | ||
469 | } | 473 | } |
470 | 474 | ||
471 | setup_pci_cmd(hose); | 475 | setup_pci_cmd(hose); |
@@ -494,6 +498,15 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary) | |||
494 | setup_pci_atmu(hose, &rsrc); | 498 | setup_pci_atmu(hose, &rsrc); |
495 | 499 | ||
496 | return 0; | 500 | return 0; |
501 | |||
502 | no_bridge: | ||
503 | /* unmap cfg_data & cfg_addr separately if not on same page */ | ||
504 | if (((unsigned long)hose->cfg_data & PAGE_MASK) != | ||
505 | ((unsigned long)hose->cfg_addr & PAGE_MASK)) | ||
506 | iounmap(hose->cfg_data); | ||
507 | iounmap(hose->cfg_addr); | ||
508 | pcibios_free_controller(hose); | ||
509 | return -ENODEV; | ||
497 | } | 510 | } |
498 | #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */ | 511 | #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */ |
499 | 512 | ||
@@ -818,6 +831,7 @@ static const struct of_device_id pci_ids[] = { | |||
818 | { .compatible = "fsl,p1010-pcie", }, | 831 | { .compatible = "fsl,p1010-pcie", }, |
819 | { .compatible = "fsl,p1023-pcie", }, | 832 | { .compatible = "fsl,p1023-pcie", }, |
820 | { .compatible = "fsl,p4080-pcie", }, | 833 | { .compatible = "fsl,p4080-pcie", }, |
834 | { .compatible = "fsl,qoriq-pcie-v2.4", }, | ||
821 | { .compatible = "fsl,qoriq-pcie-v2.3", }, | 835 | { .compatible = "fsl,qoriq-pcie-v2.3", }, |
822 | { .compatible = "fsl,qoriq-pcie-v2.2", }, | 836 | { .compatible = "fsl,qoriq-pcie-v2.2", }, |
823 | {}, | 837 | {}, |
@@ -825,57 +839,80 @@ static const struct of_device_id pci_ids[] = { | |||
825 | 839 | ||
826 | struct device_node *fsl_pci_primary; | 840 | struct device_node *fsl_pci_primary; |
827 | 841 | ||
828 | void __devinit fsl_pci_init(void) | 842 | void fsl_pci_assign_primary(void) |
829 | { | 843 | { |
830 | int ret; | 844 | struct device_node *np; |
831 | struct device_node *node; | ||
832 | struct pci_controller *hose; | ||
833 | dma_addr_t max = 0xffffffff; | ||
834 | 845 | ||
835 | /* Callers can specify the primary bus using other means. */ | 846 | /* Callers can specify the primary bus using other means. */ |
836 | if (!fsl_pci_primary) { | 847 | if (fsl_pci_primary) |
837 | /* If a PCI host bridge contains an ISA node, it's primary. */ | 848 | return; |
838 | node = of_find_node_by_type(NULL, "isa"); | 849 | |
839 | while ((fsl_pci_primary = of_get_parent(node))) { | 850 | /* If a PCI host bridge contains an ISA node, it's primary. */ |
840 | of_node_put(node); | 851 | np = of_find_node_by_type(NULL, "isa"); |
841 | node = fsl_pci_primary; | 852 | while ((fsl_pci_primary = of_get_parent(np))) { |
842 | 853 | of_node_put(np); | |
843 | if (of_match_node(pci_ids, node)) | 854 | np = fsl_pci_primary; |
844 | break; | 855 | |
845 | } | 856 | if (of_match_node(pci_ids, np) && of_device_is_available(np)) |
857 | return; | ||
846 | } | 858 | } |
847 | 859 | ||
848 | node = NULL; | 860 | /* |
849 | for_each_node_by_type(node, "pci") { | 861 | * If there's no PCI host bridge with ISA, arbitrarily |
850 | if (of_match_node(pci_ids, node)) { | 862 | * designate one as primary. This can go away once |
851 | /* | 863 | * various bugs with primary-less systems are fixed. |
852 | * If there's no PCI host bridge with ISA, arbitrarily | 864 | */ |
853 | * designate one as primary. This can go away once | 865 | for_each_matching_node(np, pci_ids) { |
854 | * various bugs with primary-less systems are fixed. | 866 | if (of_device_is_available(np)) { |
855 | */ | 867 | fsl_pci_primary = np; |
856 | if (!fsl_pci_primary) | 868 | of_node_put(np); |
857 | fsl_pci_primary = node; | 869 | return; |
858 | |||
859 | ret = fsl_add_bridge(node, fsl_pci_primary == node); | ||
860 | if (ret == 0) { | ||
861 | hose = pci_find_hose_for_OF_device(node); | ||
862 | max = min(max, hose->dma_window_base_cur + | ||
863 | hose->dma_window_size); | ||
864 | } | ||
865 | } | 870 | } |
866 | } | 871 | } |
872 | } | ||
867 | 873 | ||
874 | static int __devinit fsl_pci_probe(struct platform_device *pdev) | ||
875 | { | ||
876 | int ret; | ||
877 | struct device_node *node; | ||
868 | #ifdef CONFIG_SWIOTLB | 878 | #ifdef CONFIG_SWIOTLB |
869 | /* | 879 | struct pci_controller *hose; |
870 | * if we couldn't map all of DRAM via the dma windows | 880 | #endif |
871 | * we need SWIOTLB to handle buffers located outside of | 881 | |
872 | * dma capable memory region | 882 | node = pdev->dev.of_node; |
873 | */ | 883 | ret = fsl_add_bridge(node, fsl_pci_primary == node); |
874 | if (memblock_end_of_DRAM() - 1 > max) { | 884 | |
875 | ppc_swiotlb_enable = 1; | 885 | #ifdef CONFIG_SWIOTLB |
876 | set_pci_dma_ops(&swiotlb_dma_ops); | 886 | if (ret == 0) { |
877 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | 887 | hose = pci_find_hose_for_OF_device(pdev->dev.of_node); |
888 | |||
889 | /* | ||
890 | * if we couldn't map all of DRAM via the dma windows | ||
891 | * we need SWIOTLB to handle buffers located outside of | ||
892 | * dma capable memory region | ||
893 | */ | ||
894 | if (memblock_end_of_DRAM() - 1 > hose->dma_window_base_cur + | ||
895 | hose->dma_window_size) | ||
896 | ppc_swiotlb_enable = 1; | ||
878 | } | 897 | } |
879 | #endif | 898 | #endif |
899 | |||
900 | mpc85xx_pci_err_probe(pdev); | ||
901 | |||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | static struct platform_driver fsl_pci_driver = { | ||
906 | .driver = { | ||
907 | .name = "fsl-pci", | ||
908 | .of_match_table = pci_ids, | ||
909 | }, | ||
910 | .probe = fsl_pci_probe, | ||
911 | }; | ||
912 | |||
913 | static int __init fsl_pci_init(void) | ||
914 | { | ||
915 | return platform_driver_register(&fsl_pci_driver); | ||
880 | } | 916 | } |
917 | arch_initcall(fsl_pci_init); | ||
881 | #endif | 918 | #endif |