diff options
| -rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 51 | ||||
| -rw-r--r-- | include/asm-sparc64/pbm.h | 3 |
2 files changed, 54 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 5753175b94e6..68b1a63a178c 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 | ||
| @@ -2015,6 +2063,9 @@ static void __init schizo_pbm_init(struct pci_controller_info *p, | |||
| 2015 | pbm->pbm_regs = pr_regs[0].phys_addr; | 2063 | pbm->pbm_regs = pr_regs[0].phys_addr; |
| 2016 | pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; | 2064 | pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; |
| 2017 | 2065 | ||
| 2066 | if (chip_type == PBM_CHIP_TYPE_TOMATILLO) | ||
| 2067 | pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL; | ||
| 2068 | |||
| 2018 | sprintf(pbm->name, | 2069 | sprintf(pbm->name, |
| 2019 | (chip_type == PBM_CHIP_TYPE_TOMATILLO ? | 2070 | (chip_type == PBM_CHIP_TYPE_TOMATILLO ? |
| 2020 | "TOMATILLO%d PBM%c" : | 2071 | "TOMATILLO%d PBM%c" : |
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h index 4c15610a2bac..38bbbccb4068 100644 --- a/include/asm-sparc64/pbm.h +++ b/include/asm-sparc64/pbm.h | |||
| @@ -145,6 +145,9 @@ struct pci_pbm_info { | |||
| 145 | /* Physical address base of PBM registers. */ | 145 | /* Physical address base of PBM registers. */ |
| 146 | unsigned long pbm_regs; | 146 | unsigned long pbm_regs; |
| 147 | 147 | ||
| 148 | /* Physical address of DMA sync register, if any. */ | ||
| 149 | unsigned long sync_reg; | ||
| 150 | |||
| 148 | /* Opaque 32-bit system bus Port ID. */ | 151 | /* Opaque 32-bit system bus Port ID. */ |
| 149 | u32 portid; | 152 | u32 portid; |
| 150 | 153 | ||
