diff options
Diffstat (limited to 'arch/sparc64/kernel/pci_schizo.c')
-rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 171 |
1 files changed, 75 insertions, 96 deletions
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index cc662e915d32..f16449ccd7bc 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <asm/irq.h> | 16 | #include <asm/irq.h> |
17 | #include <asm/upa.h> | 17 | #include <asm/upa.h> |
18 | #include <asm/pstate.h> | 18 | #include <asm/pstate.h> |
19 | #include <asm/prom.h> | ||
19 | 20 | ||
20 | #include "pci_impl.h" | 21 | #include "pci_impl.h" |
21 | #include "iommu_common.h" | 22 | #include "iommu_common.h" |
@@ -1456,10 +1457,12 @@ static void __schizo_scan_bus(struct pci_controller_info *p, | |||
1456 | 1457 | ||
1457 | pbm_config_busmastering(&p->pbm_B); | 1458 | pbm_config_busmastering(&p->pbm_B); |
1458 | p->pbm_B.is_66mhz_capable = | 1459 | p->pbm_B.is_66mhz_capable = |
1459 | prom_getbool(p->pbm_B.prom_node, "66mhz-capable"); | 1460 | (of_find_property(p->pbm_B.prom_node, "66mhz-capable", NULL) |
1461 | != NULL); | ||
1460 | pbm_config_busmastering(&p->pbm_A); | 1462 | pbm_config_busmastering(&p->pbm_A); |
1461 | p->pbm_A.is_66mhz_capable = | 1463 | p->pbm_A.is_66mhz_capable = |
1462 | prom_getbool(p->pbm_A.prom_node, "66mhz-capable"); | 1464 | (of_find_property(p->pbm_A.prom_node, "66mhz-capable", NULL) |
1465 | != NULL); | ||
1463 | pbm_scan_bus(p, &p->pbm_B); | 1466 | pbm_scan_bus(p, &p->pbm_B); |
1464 | pbm_scan_bus(p, &p->pbm_A); | 1467 | pbm_scan_bus(p, &p->pbm_A); |
1465 | 1468 | ||
@@ -1661,13 +1664,18 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
1661 | { | 1664 | { |
1662 | struct pci_iommu *iommu = pbm->iommu; | 1665 | struct pci_iommu *iommu = pbm->iommu; |
1663 | unsigned long i, tagbase, database; | 1666 | unsigned long i, tagbase, database; |
1667 | struct property *prop; | ||
1664 | u32 vdma[2], dma_mask; | 1668 | u32 vdma[2], dma_mask; |
1665 | u64 control; | 1669 | u64 control; |
1666 | int err, tsbsize; | 1670 | int tsbsize; |
1667 | 1671 | ||
1668 | err = prom_getproperty(pbm->prom_node, "virtual-dma", | 1672 | prop = of_find_property(pbm->prom_node, "virtual-dma", NULL); |
1669 | (char *)&vdma[0], sizeof(vdma)); | 1673 | if (prop) { |
1670 | if (err == 0 || err == -1) { | 1674 | u32 *val = prop->value; |
1675 | |||
1676 | vdma[0] = val[0]; | ||
1677 | vdma[1] = val[1]; | ||
1678 | } else { | ||
1671 | /* No property, use default values. */ | 1679 | /* No property, use default values. */ |
1672 | vdma[0] = 0xc0000000; | 1680 | vdma[0] = 0xc0000000; |
1673 | vdma[1] = 0x40000000; | 1681 | vdma[1] = 0x40000000; |
@@ -1778,6 +1786,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
1778 | 1786 | ||
1779 | static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) | 1787 | static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) |
1780 | { | 1788 | { |
1789 | struct property *prop; | ||
1781 | u64 tmp; | 1790 | u64 tmp; |
1782 | 1791 | ||
1783 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5); | 1792 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5); |
@@ -1791,7 +1800,8 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) | |||
1791 | pbm->chip_version >= 0x2) | 1800 | pbm->chip_version >= 0x2) |
1792 | tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; | 1801 | tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; |
1793 | 1802 | ||
1794 | if (!prom_getbool(pbm->prom_node, "no-bus-parking")) | 1803 | prop = of_find_property(pbm->prom_node, "no-bus-parking", NULL); |
1804 | if (!prop) | ||
1795 | tmp |= SCHIZO_PCICTRL_PARK; | 1805 | tmp |= SCHIZO_PCICTRL_PARK; |
1796 | else | 1806 | else |
1797 | tmp &= ~SCHIZO_PCICTRL_PARK; | 1807 | tmp &= ~SCHIZO_PCICTRL_PARK; |
@@ -1831,16 +1841,17 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) | |||
1831 | } | 1841 | } |
1832 | 1842 | ||
1833 | static void schizo_pbm_init(struct pci_controller_info *p, | 1843 | static void schizo_pbm_init(struct pci_controller_info *p, |
1834 | int prom_node, u32 portid, | 1844 | struct device_node *dp, u32 portid, |
1835 | int chip_type) | 1845 | int chip_type) |
1836 | { | 1846 | { |
1837 | struct linux_prom64_registers pr_regs[4]; | 1847 | struct linux_prom64_registers *regs; |
1838 | unsigned int busrange[2]; | 1848 | struct property *prop; |
1849 | unsigned int *busrange; | ||
1839 | struct pci_pbm_info *pbm; | 1850 | struct pci_pbm_info *pbm; |
1840 | const char *chipset_name; | 1851 | const char *chipset_name; |
1841 | u32 ino_bitmap[2]; | 1852 | u32 *ino_bitmap; |
1842 | int is_pbm_a; | 1853 | int is_pbm_a; |
1843 | int err; | 1854 | int len; |
1844 | 1855 | ||
1845 | switch (chip_type) { | 1856 | switch (chip_type) { |
1846 | case PBM_CHIP_TYPE_TOMATILLO: | 1857 | case PBM_CHIP_TYPE_TOMATILLO: |
@@ -1868,16 +1879,10 @@ static void schizo_pbm_init(struct pci_controller_info *p, | |||
1868 | * 3) PBM PCI config space | 1879 | * 3) PBM PCI config space |
1869 | * 4) Ichip regs | 1880 | * 4) Ichip regs |
1870 | */ | 1881 | */ |
1871 | err = prom_getproperty(prom_node, "reg", | 1882 | prop = of_find_property(dp, "reg", NULL); |
1872 | (char *)&pr_regs[0], | 1883 | regs = prop->value; |
1873 | sizeof(pr_regs)); | ||
1874 | if (err == 0 || err == -1) { | ||
1875 | prom_printf("%s: Fatal error, no reg property.\n", | ||
1876 | chipset_name); | ||
1877 | prom_halt(); | ||
1878 | } | ||
1879 | 1884 | ||
1880 | is_pbm_a = ((pr_regs[0].phys_addr & 0x00700000) == 0x00600000); | 1885 | is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000); |
1881 | 1886 | ||
1882 | if (is_pbm_a) | 1887 | if (is_pbm_a) |
1883 | pbm = &p->pbm_A; | 1888 | pbm = &p->pbm_A; |
@@ -1886,92 +1891,62 @@ static void schizo_pbm_init(struct pci_controller_info *p, | |||
1886 | 1891 | ||
1887 | pbm->portid = portid; | 1892 | pbm->portid = portid; |
1888 | pbm->parent = p; | 1893 | pbm->parent = p; |
1889 | pbm->prom_node = prom_node; | 1894 | pbm->prom_node = dp; |
1890 | pbm->pci_first_slot = 1; | 1895 | pbm->pci_first_slot = 1; |
1891 | 1896 | ||
1892 | pbm->chip_type = chip_type; | 1897 | pbm->chip_type = chip_type; |
1893 | pbm->chip_version = | 1898 | pbm->chip_version = 0; |
1894 | prom_getintdefault(prom_node, "version#", 0); | 1899 | prop = of_find_property(dp, "version#", NULL); |
1895 | pbm->chip_revision = | 1900 | if (prop) |
1896 | prom_getintdefault(prom_node, "module-revision#", 0); | 1901 | pbm->chip_version = *(int *) prop->value; |
1897 | 1902 | pbm->chip_revision = 0; | |
1898 | pbm->pbm_regs = pr_regs[0].phys_addr; | 1903 | prop = of_find_property(dp, "module-revision#", NULL); |
1899 | pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; | 1904 | if (prop) |
1905 | pbm->chip_revision = *(int *) prop->value; | ||
1906 | |||
1907 | pbm->pbm_regs = regs[0].phys_addr; | ||
1908 | pbm->controller_regs = regs[1].phys_addr - 0x10000UL; | ||
1900 | 1909 | ||
1901 | if (chip_type == PBM_CHIP_TYPE_TOMATILLO) | 1910 | if (chip_type == PBM_CHIP_TYPE_TOMATILLO) |
1902 | pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL; | 1911 | pbm->sync_reg = regs[3].phys_addr + 0x1a18UL; |
1903 | 1912 | ||
1904 | sprintf(pbm->name, | 1913 | pbm->name = dp->full_name; |
1905 | (chip_type == PBM_CHIP_TYPE_TOMATILLO ? | ||
1906 | "TOMATILLO%d PBM%c" : | ||
1907 | "SCHIZO%d PBM%c"), | ||
1908 | p->index, | ||
1909 | (pbm == &p->pbm_A ? 'A' : 'B')); | ||
1910 | 1914 | ||
1911 | printk("%s: ver[%x:%x], portid %x, " | 1915 | printk("%s: %s PCI Bus Module ver[%x:%x]\n", |
1912 | "cregs[%lx] pregs[%lx]\n", | ||
1913 | pbm->name, | 1916 | pbm->name, |
1914 | pbm->chip_version, pbm->chip_revision, | 1917 | (chip_type == PBM_CHIP_TYPE_TOMATILLO ? |
1915 | pbm->portid, | 1918 | "TOMATILLO" : "SCHIZO"), |
1916 | pbm->controller_regs, | 1919 | pbm->chip_version, pbm->chip_revision); |
1917 | pbm->pbm_regs); | ||
1918 | 1920 | ||
1919 | schizo_pbm_hw_init(pbm); | 1921 | schizo_pbm_hw_init(pbm); |
1920 | 1922 | ||
1921 | prom_getstring(prom_node, "name", | 1923 | prop = of_find_property(dp, "ranges", &len); |
1922 | pbm->prom_name, | 1924 | pbm->pbm_ranges = prop->value; |
1923 | sizeof(pbm->prom_name)); | ||
1924 | |||
1925 | err = prom_getproperty(prom_node, "ranges", | ||
1926 | (char *) pbm->pbm_ranges, | ||
1927 | sizeof(pbm->pbm_ranges)); | ||
1928 | if (err == 0 || err == -1) { | ||
1929 | prom_printf("%s: Fatal error, no ranges property.\n", | ||
1930 | pbm->name); | ||
1931 | prom_halt(); | ||
1932 | } | ||
1933 | |||
1934 | pbm->num_pbm_ranges = | 1925 | pbm->num_pbm_ranges = |
1935 | (err / sizeof(struct linux_prom_pci_ranges)); | 1926 | (len / sizeof(struct linux_prom_pci_ranges)); |
1936 | 1927 | ||
1937 | schizo_determine_mem_io_space(pbm); | 1928 | schizo_determine_mem_io_space(pbm); |
1938 | pbm_register_toplevel_resources(p, pbm); | 1929 | pbm_register_toplevel_resources(p, pbm); |
1939 | 1930 | ||
1940 | err = prom_getproperty(prom_node, "interrupt-map", | 1931 | prop = of_find_property(dp, "interrupt-map", &len); |
1941 | (char *)pbm->pbm_intmap, | 1932 | if (prop) { |
1942 | sizeof(pbm->pbm_intmap)); | 1933 | pbm->pbm_intmap = prop->value; |
1943 | if (err != -1) { | 1934 | pbm->num_pbm_intmap = |
1944 | pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); | 1935 | (len / sizeof(struct linux_prom_pci_intmap)); |
1945 | err = prom_getproperty(prom_node, "interrupt-map-mask", | 1936 | |
1946 | (char *)&pbm->pbm_intmask, | 1937 | prop = of_find_property(dp, "interrupt-map-mask", NULL); |
1947 | sizeof(pbm->pbm_intmask)); | 1938 | pbm->pbm_intmask = prop->value; |
1948 | if (err == -1) { | ||
1949 | prom_printf("%s: Fatal error, no " | ||
1950 | "interrupt-map-mask.\n", pbm->name); | ||
1951 | prom_halt(); | ||
1952 | } | ||
1953 | } else { | 1939 | } else { |
1954 | pbm->num_pbm_intmap = 0; | 1940 | pbm->num_pbm_intmap = 0; |
1955 | memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask)); | ||
1956 | } | 1941 | } |
1957 | 1942 | ||
1958 | err = prom_getproperty(prom_node, "ino-bitmap", | 1943 | prop = of_find_property(dp, "ino-bitmap", NULL); |
1959 | (char *) &ino_bitmap[0], | 1944 | ino_bitmap = prop->value; |
1960 | sizeof(ino_bitmap)); | ||
1961 | if (err == 0 || err == -1) { | ||
1962 | prom_printf("%s: Fatal error, no ino-bitmap.\n", pbm->name); | ||
1963 | prom_halt(); | ||
1964 | } | ||
1965 | pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | | 1945 | pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | |
1966 | ((u64)ino_bitmap[0] << 0UL)); | 1946 | ((u64)ino_bitmap[0] << 0UL)); |
1967 | 1947 | ||
1968 | err = prom_getproperty(prom_node, "bus-range", | 1948 | prop = of_find_property(dp, "bus-range", NULL); |
1969 | (char *)&busrange[0], | 1949 | busrange = prop->value; |
1970 | sizeof(busrange)); | ||
1971 | if (err == 0 || err == -1) { | ||
1972 | prom_printf("%s: Fatal error, no bus-range.\n", pbm->name); | ||
1973 | prom_halt(); | ||
1974 | } | ||
1975 | pbm->pci_first_busno = busrange[0]; | 1950 | pbm->pci_first_busno = busrange[0]; |
1976 | pbm->pci_last_busno = busrange[1]; | 1951 | pbm->pci_last_busno = busrange[1]; |
1977 | 1952 | ||
@@ -1989,16 +1964,20 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) | |||
1989 | return (x == y); | 1964 | return (x == y); |
1990 | } | 1965 | } |
1991 | 1966 | ||
1992 | static void __schizo_init(int node, char *model_name, int chip_type) | 1967 | static void __schizo_init(struct device_node *dp, char *model_name, int chip_type) |
1993 | { | 1968 | { |
1994 | struct pci_controller_info *p; | 1969 | struct pci_controller_info *p; |
1995 | struct pci_iommu *iommu; | 1970 | struct pci_iommu *iommu; |
1971 | struct property *prop; | ||
1996 | int is_pbm_a; | 1972 | int is_pbm_a; |
1997 | u32 portid; | 1973 | u32 portid; |
1998 | 1974 | ||
1999 | portid = prom_getintdefault(node, "portid", 0xff); | 1975 | portid = 0xff; |
1976 | prop = of_find_property(dp, "portid", NULL); | ||
1977 | if (prop) | ||
1978 | portid = *(u32 *) prop->value; | ||
2000 | 1979 | ||
2001 | for(p = pci_controller_root; p; p = p->next) { | 1980 | for (p = pci_controller_root; p; p = p->next) { |
2002 | struct pci_pbm_info *pbm; | 1981 | struct pci_pbm_info *pbm; |
2003 | 1982 | ||
2004 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) | 1983 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) |
@@ -2009,8 +1988,8 @@ static void __schizo_init(int node, char *model_name, int chip_type) | |||
2009 | &p->pbm_B); | 1988 | &p->pbm_B); |
2010 | 1989 | ||
2011 | if (portid_compare(pbm->portid, portid, chip_type)) { | 1990 | if (portid_compare(pbm->portid, portid, chip_type)) { |
2012 | is_pbm_a = (p->pbm_A.prom_node == 0); | 1991 | is_pbm_a = (p->pbm_A.prom_node == NULL); |
2013 | schizo_pbm_init(p, node, portid, chip_type); | 1992 | schizo_pbm_init(p, dp, portid, chip_type); |
2014 | return; | 1993 | return; |
2015 | } | 1994 | } |
2016 | } | 1995 | } |
@@ -2051,20 +2030,20 @@ static void __schizo_init(int node, char *model_name, int chip_type) | |||
2051 | /* Like PSYCHO we have a 2GB aligned area for memory space. */ | 2030 | /* Like PSYCHO we have a 2GB aligned area for memory space. */ |
2052 | pci_memspace_mask = 0x7fffffffUL; | 2031 | pci_memspace_mask = 0x7fffffffUL; |
2053 | 2032 | ||
2054 | schizo_pbm_init(p, node, portid, chip_type); | 2033 | schizo_pbm_init(p, dp, portid, chip_type); |
2055 | } | 2034 | } |
2056 | 2035 | ||
2057 | void schizo_init(int node, char *model_name) | 2036 | void schizo_init(struct device_node *dp, char *model_name) |
2058 | { | 2037 | { |
2059 | __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO); | 2038 | __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO); |
2060 | } | 2039 | } |
2061 | 2040 | ||
2062 | void schizo_plus_init(int node, char *model_name) | 2041 | void schizo_plus_init(struct device_node *dp, char *model_name) |
2063 | { | 2042 | { |
2064 | __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); | 2043 | __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); |
2065 | } | 2044 | } |
2066 | 2045 | ||
2067 | void tomatillo_init(int node, char *model_name) | 2046 | void tomatillo_init(struct device_node *dp, char *model_name) |
2068 | { | 2047 | { |
2069 | __schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO); | 2048 | __schizo_init(dp, model_name, PBM_CHIP_TYPE_TOMATILLO); |
2070 | } | 2049 | } |