diff options
Diffstat (limited to 'arch/powerpc/platforms/powernv/pci-ioda.c')
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 46 | 
1 files changed, 37 insertions, 9 deletions
| diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 3f9c69d7623a..5bd0eb6681bc 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1976,9 +1976,10 @@ static void pnv_pci_p7ioc_tce_invalidate(struct iommu_table *tbl,          mb(); /* Ensure above stores are visible */          while (start <= end) {  		if (rm) -			__raw_rm_writeq(cpu_to_be64(start), invalidate); +			__raw_rm_writeq_be(start, invalidate);  		else -			__raw_writeq(cpu_to_be64(start), invalidate); +			__raw_writeq_be(start, invalidate); +                  start += inc;          } @@ -2055,9 +2056,9 @@ static void pnv_pci_phb3_tce_invalidate_entire(struct pnv_phb *phb, bool rm)  	mb(); /* Ensure previous TCE table stores are visible */  	if (rm) -		__raw_rm_writeq(cpu_to_be64(val), invalidate); +		__raw_rm_writeq_be(val, invalidate);  	else -		__raw_writeq(cpu_to_be64(val), invalidate); +		__raw_writeq_be(val, invalidate);  }  static inline void pnv_pci_phb3_tce_invalidate_pe(struct pnv_ioda_pe *pe) @@ -2067,7 +2068,7 @@ static inline void pnv_pci_phb3_tce_invalidate_pe(struct pnv_ioda_pe *pe)  	unsigned long val = PHB3_TCE_KILL_INVAL_PE | (pe->pe_number & 0xFF);  	mb(); /* Ensure above stores are visible */ -	__raw_writeq(cpu_to_be64(val), invalidate); +	__raw_writeq_be(val, invalidate);  }  static void pnv_pci_phb3_tce_invalidate(struct pnv_ioda_pe *pe, bool rm, @@ -2090,9 +2091,9 @@ static void pnv_pci_phb3_tce_invalidate(struct pnv_ioda_pe *pe, bool rm,  	while (start <= end) {  		if (rm) -			__raw_rm_writeq(cpu_to_be64(start), invalidate); +			__raw_rm_writeq_be(start, invalidate);  		else -			__raw_writeq(cpu_to_be64(start), invalidate); +			__raw_writeq_be(start, invalidate);  		start += inc;  	}  } @@ -2910,6 +2911,34 @@ static void pnv_pci_ioda2_table_free_pages(struct iommu_table *tbl)  			tbl->it_indirect_levels);  } +static unsigned long pnv_ioda_parse_tce_sizes(struct pnv_phb *phb) +{ +	struct pci_controller *hose = phb->hose; +	struct device_node *dn = hose->dn; +	unsigned long mask = 0; +	int i, rc, count; +	u32 val; + +	count = of_property_count_u32_elems(dn, "ibm,supported-tce-sizes"); +	if (count <= 0) { +		mask = SZ_4K | SZ_64K; +		/* Add 16M for POWER8 by default */ +		if (cpu_has_feature(CPU_FTR_ARCH_207S) && +				!cpu_has_feature(CPU_FTR_ARCH_300)) +			mask |= SZ_16M; +		return mask; +	} + +	for (i = 0; i < count; i++) { +		rc = of_property_read_u32_index(dn, "ibm,supported-tce-sizes", +						i, &val); +		if (rc == 0) +			mask |= 1ULL << val; +	} + +	return mask; +} +  static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,  				       struct pnv_ioda_pe *pe)  { @@ -2934,7 +2963,7 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,  	pe->table_group.max_dynamic_windows_supported =  			IOMMU_TABLE_GROUP_MAX_TABLES;  	pe->table_group.max_levels = POWERNV_IOMMU_MAX_LEVELS; -	pe->table_group.pgsizes = SZ_4K | SZ_64K | SZ_16M; +	pe->table_group.pgsizes = pnv_ioda_parse_tce_sizes(phb);  #ifdef CONFIG_IOMMU_API  	pe->table_group.ops = &pnv_pci_ioda2_ops;  #endif @@ -3642,7 +3671,6 @@ static void pnv_pci_ioda2_release_pe_dma(struct pnv_ioda_pe *pe)  		WARN_ON(pe->table_group.group);  	} -	pnv_pci_ioda2_table_free_pages(tbl);  	iommu_tce_table_put(tbl);  } |