Skip to content

Commit 373f565

Browse files
shangwozbenh
authored andcommitted
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 <[email protected]> Signed-off-by: Benjamin Herrenschmidt <[email protected]>
1 parent 4cce955 commit 373f565

File tree

1 file changed

+93
-6
lines changed

1 file changed

+93
-6
lines changed

arch/powerpc/platforms/powernv/pci-ioda.c

Lines changed: 93 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -600,9 +600,8 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
600600
*/
601601
tbl->it_busno = 0;
602602
tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8);
603-
tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE;
604-
if (phb->type == PNV_PHB_IODA1)
605-
tbl->it_type |= TCE_PCI_SWINV_PAIR;
603+
tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE |
604+
TCE_PCI_SWINV_PAIR;
606605
}
607606
iommu_init_table(tbl, phb->hose->node);
608607

@@ -620,6 +619,81 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
620619
__free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs));
621620
}
622621

622+
static 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;
690+
fail:
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+
623697
static void pnv_ioda_setup_dma(struct pnv_phb *phb)
624698
{
625699
struct pci_controller *hose = phb->hose;
@@ -662,9 +736,22 @@ static void pnv_ioda_setup_dma(struct pnv_phb *phb)
662736
if (segs > remaining)
663737
segs = remaining;
664738
}
665-
pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n",
666-
pe->dma_weight, segs);
667-
pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs);
739+
740+
/*
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+
668755
remaining -= segs;
669756
base += segs;
670757
}

0 commit comments

Comments
 (0)