diff options
Diffstat (limited to 'arch/sparc64/kernel/pci_schizo.c')
| -rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 78 |
1 files changed, 60 insertions, 18 deletions
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 5753175b94e6..6a182bb66281 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <asm/iommu.h> | 15 | #include <asm/iommu.h> |
| 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 | 19 | ||
| 19 | #include "pci_impl.h" | 20 | #include "pci_impl.h" |
| 20 | #include "iommu_common.h" | 21 | #include "iommu_common.h" |
| @@ -326,6 +327,44 @@ static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino) | |||
| 326 | return ret; | 327 | return ret; |
| 327 | } | 328 | } |
| 328 | 329 | ||
| 330 | static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) | ||
| 331 | { | ||
| 332 | unsigned long sync_reg = (unsigned long) _arg2; | ||
| 333 | u64 mask = 1 << (__irq_ino(__irq(bucket)) & IMAP_INO); | ||
| 334 | u64 val; | ||
| 335 | int limit; | ||
| 336 | |||
| 337 | schizo_write(sync_reg, mask); | ||
| 338 | |||
| 339 | limit = 100000; | ||
| 340 | val = 0; | ||
| 341 | while (--limit) { | ||
| 342 | val = schizo_read(sync_reg); | ||
| 343 | if (!(val & mask)) | ||
| 344 | break; | ||
| 345 | } | ||
| 346 | if (limit <= 0) { | ||
| 347 | printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n", | ||
| 348 | val, mask); | ||
| 349 | } | ||
| 350 | |||
| 351 | if (_arg1) { | ||
| 352 | static unsigned char cacheline[64] | ||
| 353 | __attribute__ ((aligned (64))); | ||
| 354 | |||
| 355 | __asm__ __volatile__("rd %%fprs, %0\n\t" | ||
| 356 | "or %0, %4, %1\n\t" | ||
| 357 | "wr %1, 0x0, %%fprs\n\t" | ||
| 358 | "stda %%f0, [%5] %6\n\t" | ||
| 359 | "wr %0, 0x0, %%fprs\n\t" | ||
| 360 | "membar #Sync" | ||
| 361 | : "=&r" (mask), "=&r" (val) | ||
| 362 | : "0" (mask), "1" (val), | ||
| 363 | "i" (FPRS_FEF), "r" (&cacheline[0]), | ||
| 364 | "i" (ASI_BLK_COMMIT_P)); | ||
| 365 | } | ||
| 366 | } | ||
| 367 | |||
| 329 | static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, | 368 | static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, |
| 330 | struct pci_dev *pdev, | 369 | struct pci_dev *pdev, |
| 331 | unsigned int ino) | 370 | unsigned int ino) |
| @@ -369,6 +408,15 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, | |||
| 369 | bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap)); | 408 | bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap)); |
| 370 | bucket->flags |= IBF_PCI; | 409 | bucket->flags |= IBF_PCI; |
| 371 | 410 | ||
| 411 | if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { | ||
| 412 | struct irq_desc *p = bucket->irq_info; | ||
| 413 | |||
| 414 | p->pre_handler = tomatillo_wsync_handler; | ||
| 415 | p->pre_handler_arg1 = ((pbm->chip_version <= 4) ? | ||
| 416 | (void *) 1 : (void *) 0); | ||
| 417 | p->pre_handler_arg2 = (void *) pbm->sync_reg; | ||
| 418 | } | ||
| 419 | |||
| 372 | return __irq(bucket); | 420 | return __irq(bucket); |
| 373 | } | 421 | } |
| 374 | 422 | ||
| @@ -885,6 +933,7 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
| 885 | 933 | ||
| 886 | #define SCHIZO_PCI_CTRL (0x2000UL) | 934 | #define SCHIZO_PCI_CTRL (0x2000UL) |
| 887 | #define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) /* Safari */ | 935 | #define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) /* Safari */ |
| 936 | #define SCHIZO_PCICTRL_DTO_INT (1UL << 61UL) /* Tomatillo */ | ||
| 888 | #define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */ | 937 | #define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */ |
| 889 | #define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) /* Safari */ | 938 | #define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) /* Safari */ |
| 890 | #define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */ | 939 | #define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */ |
| @@ -1887,37 +1936,27 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm) | |||
| 1887 | { | 1936 | { |
| 1888 | u64 tmp; | 1937 | u64 tmp; |
| 1889 | 1938 | ||
| 1890 | /* Set IRQ retry to infinity. */ | 1939 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5); |
| 1891 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, | ||
| 1892 | SCHIZO_IRQ_RETRY_INF); | ||
| 1893 | 1940 | ||
| 1894 | /* Enable arbiter for all PCI slots. Also, disable PCI interval | ||
| 1895 | * timer so that DTO (Discard TimeOuts) are not reported because | ||
| 1896 | * some Schizo revisions report them erroneously. | ||
| 1897 | */ | ||
| 1898 | tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); | 1941 | tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); |
| 1899 | if (pbm->chip_type == PBM_CHIP_TYPE_SCHIZO_PLUS && | ||
| 1900 | pbm->chip_version == 0x5 && | ||
| 1901 | pbm->chip_revision == 0x1) | ||
| 1902 | tmp |= 0x0f; | ||
| 1903 | else | ||
| 1904 | tmp |= 0xff; | ||
| 1905 | 1942 | ||
| 1906 | tmp &= ~SCHIZO_PCICTRL_PTO; | 1943 | /* Enable arbiter for all PCI slots. */ |
| 1944 | tmp |= 0xff; | ||
| 1945 | |||
| 1907 | if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && | 1946 | if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && |
| 1908 | pbm->chip_version >= 0x2) | 1947 | pbm->chip_version >= 0x2) |
| 1909 | tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; | 1948 | tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; |
| 1910 | else | ||
| 1911 | tmp |= 0x1UL << SCHIZO_PCICTRL_PTO_SHIFT; | ||
| 1912 | 1949 | ||
| 1913 | if (!prom_getbool(pbm->prom_node, "no-bus-parking")) | 1950 | if (!prom_getbool(pbm->prom_node, "no-bus-parking")) |
| 1914 | tmp |= SCHIZO_PCICTRL_PARK; | 1951 | tmp |= SCHIZO_PCICTRL_PARK; |
| 1952 | else | ||
| 1953 | tmp &= ~SCHIZO_PCICTRL_PARK; | ||
| 1915 | 1954 | ||
| 1916 | if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && | 1955 | if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && |
| 1917 | pbm->chip_version <= 0x1) | 1956 | pbm->chip_version <= 0x1) |
| 1918 | tmp |= (1UL << 61); | 1957 | tmp |= SCHIZO_PCICTRL_DTO_INT; |
| 1919 | else | 1958 | else |
| 1920 | tmp &= ~(1UL << 61); | 1959 | tmp &= ~SCHIZO_PCICTRL_DTO_INT; |
| 1921 | 1960 | ||
| 1922 | if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) | 1961 | if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) |
| 1923 | tmp |= (SCHIZO_PCICTRL_MRM_PREF | | 1962 | tmp |= (SCHIZO_PCICTRL_MRM_PREF | |
| @@ -2015,6 +2054,9 @@ static void __init schizo_pbm_init(struct pci_controller_info *p, | |||
| 2015 | pbm->pbm_regs = pr_regs[0].phys_addr; | 2054 | pbm->pbm_regs = pr_regs[0].phys_addr; |
| 2016 | pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; | 2055 | pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; |
| 2017 | 2056 | ||
| 2057 | if (chip_type == PBM_CHIP_TYPE_TOMATILLO) | ||
| 2058 | pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL; | ||
| 2059 | |||
| 2018 | sprintf(pbm->name, | 2060 | sprintf(pbm->name, |
| 2019 | (chip_type == PBM_CHIP_TYPE_TOMATILLO ? | 2061 | (chip_type == PBM_CHIP_TYPE_TOMATILLO ? |
| 2020 | "TOMATILLO%d PBM%c" : | 2062 | "TOMATILLO%d PBM%c" : |
