Lines Matching +full:pci +full:- +full:iommu
1 // SPDX-License-Identifier: GPL-2.0
2 /* pci_psycho.c: PSYCHO/U2P specific PCI controller support.
11 #include <linux/pci.h>
20 #include <asm/iommu.h>
33 /* Misc. PSYCHO PCI controller register offsets and definitions. */
49 #define PSYCHO_PCICTRL_SPEED 0x0000000200000000UL /* PCI speed (1 is U2P clock) */
51 #define PSYCHO_PCICTRL_ARB_PARK 0x0000000000200000UL /* PCI arbitration parking */
55 #define PSYCHO_PCICTRL_EEN 0x0000000000000100UL /* PCI Error Interrupt Enable */
57 #define PSYCHO_PCICTRL_AEN 0x000000000000003fUL /* PCI DVMA Arbitration Enable */
61 /* Helper function of IOMMU error checking, which checks out
62 * the state of the streaming buffers. The IOMMU lock is
65 * For the PCI error case we know which PBM (and thus which
89 /* When an Uncorrectable Error or a PCI Error happens, we
90 * interrogate the IOMMU state to see if it is the cause.
99 #define PSYCHO_IOMMU_TSBSZ_1K 0x0000000000000000UL /* TSB Table 1024 8-byte entries */
100 #define PSYCHO_IOMMU_TSBSZ_2K 0x0000000000010000UL /* TSB Table 2048 8-byte entries */
101 #define PSYCHO_IOMMU_TSBSZ_4K 0x0000000000020000UL /* TSB Table 4096 8-byte entries */
102 #define PSYCHO_IOMMU_TSBSZ_8K 0x0000000000030000UL /* TSB Table 8192 8-byte entries */
103 #define PSYCHO_IOMMU_TSBSZ_16K 0x0000000000040000UL /* TSB Table 16k 8-byte entries */
104 #define PSYCHO_IOMMU_TSBSZ_32K 0x0000000000050000UL /* TSB Table 32k 8-byte entries */
105 #define PSYCHO_IOMMU_TSBSZ_64K 0x0000000000060000UL /* TSB Table 64k 8-byte entries */
106 #define PSYCHO_IOMMU_TSBSZ_128K 0x0000000000070000UL /* TSB Table 128k 8-byte entries */
110 #define PSYCHO_IOMMU_CTRL_ENAB 0x0000000000000001UL /* IOMMU Enable */
138 unsigned long afsr_reg = pbm->controller_regs + PSYCHO_UE_AFSR; in psycho_ue_intr()
139 unsigned long afar_reg = pbm->controller_regs + PSYCHO_UE_AFAR; in psycho_ue_intr()
157 pbm->name, in psycho_ue_intr()
165 pbm->name, in psycho_ue_intr()
170 printk("%s: UE AFAR [%016lx]\n", pbm->name, afar); in psycho_ue_intr()
171 printk("%s: UE Secondary errors [", pbm->name); in psycho_ue_intr()
191 if (pbm->sibling) in psycho_ue_intr()
192 psycho_check_iommu_error(pbm->sibling, afsr, afar, UE_ERR); in psycho_ue_intr()
217 unsigned long afsr_reg = pbm->controller_regs + PSYCHO_CE_AFSR; in psycho_ce_intr()
218 unsigned long afar_reg = pbm->controller_regs + PSYCHO_CE_AFAR; in psycho_ce_intr()
236 pbm->name, in psycho_ce_intr()
245 * XXX UDB CE trap handler does... -DaveM in psycho_ce_intr()
249 pbm->name, in psycho_ce_intr()
255 printk("%s: CE AFAR [%016lx]\n", pbm->name, afar); in psycho_ce_intr()
256 printk("%s: CE Secondary errors [", pbm->name); in psycho_ce_intr()
277 /* PCI Errors. They are signalled by the PCI bus module since they
285 /* XXX What about PowerFail/PowerManagement??? -DaveM */
292 struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node); in psycho_register_error_handlers()
293 unsigned long base = pbm->controller_regs; in psycho_register_error_handlers()
309 if (op->archdata.num_irqs < 6) in psycho_register_error_handlers()
313 * PCI controller share the same interrupt numbers and in psycho_register_error_handlers()
314 * drive the same front-end hardware. in psycho_register_error_handlers()
316 err = request_irq(op->archdata.irqs[1], psycho_ue_intr, IRQF_SHARED, in psycho_register_error_handlers()
318 err = request_irq(op->archdata.irqs[2], psycho_ce_intr, IRQF_SHARED, in psycho_register_error_handlers()
325 err = request_irq(op->archdata.irqs[0], psycho_pcierr_intr, IRQF_SHARED, in psycho_register_error_handlers()
329 "err=%d\n", pbm->name, err); in psycho_register_error_handlers()
336 /* Enable PCI Error interrupts and clear error in psycho_register_error_handlers()
359 /* Set cache-line size to 64 bytes, this is actually in pbm_config_busmastering()
362 addr = psycho_pci_config_mkaddr(pbm, pbm->pci_first_busno, in pbm_config_busmastering()
366 /* Set PBM latency timer to 64 PCI clocks. */ in pbm_config_busmastering()
367 addr = psycho_pci_config_mkaddr(pbm, pbm->pci_first_busno, in pbm_config_busmastering()
376 pbm->is_66mhz_capable = 0; in psycho_scan_bus()
377 pbm->pci_bus = pci_scan_one_pbm(pbm, parent); in psycho_scan_bus()
379 /* After the PCI bus scan is complete, we can register in psycho_scan_bus()
401 upa_writeq(5, pbm->controller_regs + PSYCHO_IRQ_RETRY); in psycho_controller_hwinit()
403 /* Enable arbiter for all PCI slots. */ in psycho_controller_hwinit()
404 tmp = upa_readq(pbm->controller_regs + PSYCHO_PCIA_CTRL); in psycho_controller_hwinit()
406 upa_writeq(tmp, pbm->controller_regs + PSYCHO_PCIA_CTRL); in psycho_controller_hwinit()
408 tmp = upa_readq(pbm->controller_regs + PSYCHO_PCIB_CTRL); in psycho_controller_hwinit()
410 upa_writeq(tmp, pbm->controller_regs + PSYCHO_PCIB_CTRL); in psycho_controller_hwinit()
413 * both PCI bus segments. in psycho_controller_hwinit()
416 tmp = upa_readq(pbm->controller_regs + PSYCHO_PCIA_DIAG); in psycho_controller_hwinit()
418 upa_writeq(tmp, pbm->controller_regs + PSYCHO_PCIA_DIAG); in psycho_controller_hwinit()
420 tmp = upa_readq(pbm->controller_regs + PSYCHO_PCIB_DIAG); in psycho_controller_hwinit()
422 upa_writeq(tmp, pbm->controller_regs + PSYCHO_PCIB_DIAG); in psycho_controller_hwinit()
428 unsigned long base = pbm->controller_regs; in psycho_pbm_strbuf_init()
432 pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_A; in psycho_pbm_strbuf_init()
433 pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_A; in psycho_pbm_strbuf_init()
434 pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_A; in psycho_pbm_strbuf_init()
435 pbm->stc.strbuf_err_stat = base + PSYCHO_STC_ERR_A; in psycho_pbm_strbuf_init()
436 pbm->stc.strbuf_tag_diag = base + PSYCHO_STC_TAG_A; in psycho_pbm_strbuf_init()
437 pbm->stc.strbuf_line_diag= base + PSYCHO_STC_LINE_A; in psycho_pbm_strbuf_init()
439 pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_B; in psycho_pbm_strbuf_init()
440 pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_B; in psycho_pbm_strbuf_init()
441 pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_B; in psycho_pbm_strbuf_init()
442 pbm->stc.strbuf_err_stat = base + PSYCHO_STC_ERR_B; in psycho_pbm_strbuf_init()
443 pbm->stc.strbuf_tag_diag = base + PSYCHO_STC_TAG_B; in psycho_pbm_strbuf_init()
444 pbm->stc.strbuf_line_diag= base + PSYCHO_STC_LINE_B; in psycho_pbm_strbuf_init()
447 pbm->stc.strbuf_ctxflush = 0; in psycho_pbm_strbuf_init()
448 pbm->stc.strbuf_ctxmatch_base = 0; in psycho_pbm_strbuf_init()
450 pbm->stc.strbuf_flushflag = (volatile unsigned long *) in psycho_pbm_strbuf_init()
451 ((((unsigned long)&pbm->stc.__flushflag_buf[0]) in psycho_pbm_strbuf_init()
454 pbm->stc.strbuf_flushflag_pa = (unsigned long) in psycho_pbm_strbuf_init()
455 __pa(pbm->stc.strbuf_flushflag); in psycho_pbm_strbuf_init()
467 control = upa_readq(pbm->stc.strbuf_control); in psycho_pbm_strbuf_init()
477 upa_writeq(control, pbm->stc.strbuf_control); in psycho_pbm_strbuf_init()
479 pbm->stc.strbuf_enabled = 1; in psycho_pbm_strbuf_init()
494 psycho_scan_bus(pbm, &op->dev); in psycho_pbm_init()
501 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { in psycho_find_sibling()
502 if (pbm->portid == upa_portid) in psycho_find_sibling()
513 struct device_node *dp = op->dev.of_node; in psycho_probe()
515 struct iommu *iommu; in psycho_probe() local
519 upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); in psycho_probe()
521 err = -ENOMEM; in psycho_probe()
528 pbm->sibling = psycho_find_sibling(upa_portid); in psycho_probe()
529 if (pbm->sibling) { in psycho_probe()
530 iommu = pbm->sibling->iommu; in psycho_probe()
532 iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); in psycho_probe()
533 if (!iommu) { in psycho_probe()
534 printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); in psycho_probe()
539 pbm->iommu = iommu; in psycho_probe()
540 pbm->portid = upa_portid; in psycho_probe()
543 err = -ENODEV; in psycho_probe()
551 pbm->controller_regs = pr_regs[2].phys_addr; in psycho_probe()
552 pbm->config_space = (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); in psycho_probe()
555 pbm->pci_afsr = pbm->controller_regs + PSYCHO_PCI_AFSR_A; in psycho_probe()
556 pbm->pci_afar = pbm->controller_regs + PSYCHO_PCI_AFAR_A; in psycho_probe()
557 pbm->pci_csr = pbm->controller_regs + PSYCHO_PCIA_CTRL; in psycho_probe()
559 pbm->pci_afsr = pbm->controller_regs + PSYCHO_PCI_AFSR_B; in psycho_probe()
560 pbm->pci_afar = pbm->controller_regs + PSYCHO_PCI_AFAR_B; in psycho_probe()
561 pbm->pci_csr = pbm->controller_regs + PSYCHO_PCIB_CTRL; in psycho_probe()
565 if (!pbm->sibling) { in psycho_probe()
573 starfire_hookup(pbm->portid); in psycho_probe()
578 pbm->next = pci_pbm_root; in psycho_probe()
581 if (pbm->sibling) in psycho_probe()
582 pbm->sibling->sibling = pbm; in psycho_probe()
584 dev_set_drvdata(&op->dev, pbm); in psycho_probe()
589 if (!pbm->sibling) in psycho_probe()
590 kfree(pbm->iommu); in psycho_probe()
601 .name = "pci",