@@ -600,9 +600,8 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
600
600
*/
601
601
tbl -> it_busno = 0 ;
602
602
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 ;
606
605
}
607
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
619
__free_pages (tce_mem , get_order (TCE32_TABLE_SIZE * segs ));
621
620
}
622
621
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
+
623
697
static void pnv_ioda_setup_dma (struct pnv_phb * phb )
624
698
{
625
699
struct pci_controller * hose = phb -> hose ;
@@ -662,9 +736,22 @@ static void pnv_ioda_setup_dma(struct pnv_phb *phb)
662
736
if (segs > remaining )
663
737
segs = remaining ;
664
738
}
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
+
668
755
remaining -= segs ;
669
756
base += segs ;
670
757
}
0 commit comments