aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2013-04-25 15:21:01 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-04-26 02:10:00 -0400
commit373f565741a3636954cd87034d9ebb1dc7bfd716 (patch)
tree6c51ef6736305eb478be626028f8eecb1f95f0cf /arch
parent4cce95508bfeaa1cab74b08558993c81436dcbe0 (diff)
powerpc/powernv: Build DMA space for PE on PHB3
The patch intends to build 32-bits DMA space for individual PEs on PHB3. The TVE# is recognized by the combo of PE# and fixed bits from DMA address, which is zero for 32-bits DMA space. Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c99
1 files changed, 93 insertions, 6 deletions
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 1c7e808a1302..04a37dc06a77 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -600,9 +600,8 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
600 */ 600 */
601 tbl->it_busno = 0; 601 tbl->it_busno = 0;
602 tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); 602 tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8);
603 tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE; 603 tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE |
604 if (phb->type == PNV_PHB_IODA1) 604 TCE_PCI_SWINV_PAIR;
605 tbl->it_type |= TCE_PCI_SWINV_PAIR;
606 } 605 }
607 iommu_init_table(tbl, phb->hose->node); 606 iommu_init_table(tbl, phb->hose->node);
608 607
@@ -620,6 +619,81 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
620 __free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs)); 619 __free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs));
621} 620}
622 621
622static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
623 struct pnv_ioda_pe *pe)
624{
625 struct page *tce_mem = NULL;
626 void *addr;
627 const __be64 *swinvp;
628 struct iommu_table *tbl;
629 unsigned int tce_table_size, end;
630 int64_t rc;
631
632 /* We shouldn't already have a 32-bit DMA associated */
633 if (WARN_ON(pe->tce32_seg >= 0))
634 return;
635
636 /* The PE will reserve all possible 32-bits space */
637 pe->tce32_seg = 0;
638 end = (1 << ilog2(phb->ioda.m32_pci_base));
639 tce_table_size = (end / 0x1000) * 8;
640 pe_info(pe, "Setting up 32-bit TCE table at 0..%08x\n",
641 end);
642
643 /* Allocate TCE table */
644 tce_mem = alloc_pages_node(phb->hose->node, GFP_KERNEL,
645 get_order(tce_table_size));
646 if (!tce_mem) {
647 pe_err(pe, "Failed to allocate a 32-bit TCE memory\n");
648 goto fail;
649 }
650 addr = page_address(tce_mem);
651 memset(addr, 0, tce_table_size);
652
653 /*
654 * Map TCE table through TVT. The TVE index is the PE number
655 * shifted by 1 bit for 32-bits DMA space.
656 */
657 rc = opal_pci_map_pe_dma_window(phb->opal_id, pe->pe_number,
658 pe->pe_number << 1, 1, __pa(addr),
659 tce_table_size, 0x1000);
660 if (rc) {
661 pe_err(pe, "Failed to configure 32-bit TCE table,"
662 " err %ld\n", rc);
663 goto fail;
664 }
665
666 /* Setup linux iommu table */
667 tbl = &pe->tce32_table;
668 pnv_pci_setup_iommu_table(tbl, addr, tce_table_size, 0);
669
670 /* OPAL variant of PHB3 invalidated TCEs */
671 swinvp = of_get_property(phb->hose->dn, "ibm,opal-tce-kill", NULL);
672 if (swinvp) {
673 /* We need a couple more fields -- an address and a data
674 * to or. Since the bus is only printed out on table free
675 * errors, and on the first pass the data will be a relative
676 * bus number, print that out instead.
677 */
678 tbl->it_busno = 0;
679 tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8);
680 tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE;
681 }
682 iommu_init_table(tbl, phb->hose->node);
683
684 if (pe->pdev)
685 set_iommu_table_base(&pe->pdev->dev, tbl);
686 else
687 pnv_ioda_setup_bus_dma(pe, pe->pbus);
688
689 return;
690fail:
691 if (pe->tce32_seg >= 0)
692 pe->tce32_seg = -1;
693 if (tce_mem)
694 __free_pages(tce_mem, get_order(tce_table_size));
695}
696
623static void pnv_ioda_setup_dma(struct pnv_phb *phb) 697static void pnv_ioda_setup_dma(struct pnv_phb *phb)
624{ 698{
625 struct pci_controller *hose = phb->hose; 699 struct pci_controller *hose = phb->hose;
@@ -662,9 +736,22 @@ static void pnv_ioda_setup_dma(struct pnv_phb *phb)
662 if (segs > remaining) 736 if (segs > remaining)
663 segs = remaining; 737 segs = remaining;
664 } 738 }
665 pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n", 739
666 pe->dma_weight, segs); 740 /*
667 pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs); 741 * For IODA2 compliant PHB3, we needn't care about the weight.
742 * The all available 32-bits DMA space will be assigned to
743 * the specific PE.
744 */
745 if (phb->type == PNV_PHB_IODA1) {
746 pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n",
747 pe->dma_weight, segs);
748 pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs);
749 } else {
750 pe_info(pe, "Assign DMA32 space\n");
751 segs = 0;
752 pnv_pci_ioda2_setup_dma_pe(phb, pe);
753 }
754
668 remaining -= segs; 755 remaining -= segs;
669 base += segs; 756 base += segs;
670 } 757 }