diff options
| -rw-r--r-- | Documentation/devicetree/bindings/iommu/allwinner,sun50i-h6-iommu.yaml | 7 | ||||
| -rw-r--r-- | drivers/iommu/sun50i-iommu.c | 15 | 
2 files changed, 19 insertions, 3 deletions
| diff --git a/Documentation/devicetree/bindings/iommu/allwinner,sun50i-h6-iommu.yaml b/Documentation/devicetree/bindings/iommu/allwinner,sun50i-h6-iommu.yaml index e20016f12017..a8409db4a3e3 100644 --- a/Documentation/devicetree/bindings/iommu/allwinner,sun50i-h6-iommu.yaml +++ b/Documentation/devicetree/bindings/iommu/allwinner,sun50i-h6-iommu.yaml @@ -17,7 +17,12 @@ properties:        The content of the cell is the master ID.    compatible: -    const: allwinner,sun50i-h6-iommu +    oneOf: +      - const: allwinner,sun50i-h6-iommu +      - const: allwinner,sun50i-h616-iommu +      - items: +          - const: allwinner,sun55i-a523-iommu +          - const: allwinner,sun50i-h616-iommu    reg:      maxItems: 1 diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c index c519b991749d..8d8f11854676 100644 --- a/drivers/iommu/sun50i-iommu.c +++ b/drivers/iommu/sun50i-iommu.c @@ -452,6 +452,7 @@ static int sun50i_iommu_enable(struct sun50i_iommu *iommu)  		    IOMMU_TLB_PREFETCH_MASTER_ENABLE(3) |  		    IOMMU_TLB_PREFETCH_MASTER_ENABLE(4) |  		    IOMMU_TLB_PREFETCH_MASTER_ENABLE(5)); +	iommu_write(iommu, IOMMU_BYPASS_REG, 0);  	iommu_write(iommu, IOMMU_INT_ENABLE_REG, IOMMU_INT_MASK);  	iommu_write(iommu, IOMMU_DM_AUT_CTRL_REG(SUN50I_IOMMU_ACI_NONE),  		    IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 0) | @@ -601,6 +602,14 @@ static int sun50i_iommu_map(struct iommu_domain *domain, unsigned long iova,  	u32 *page_table, *pte_addr;  	int ret = 0; +	/* the IOMMU can only handle 32-bit addresses, both input and output */ +	if ((uint64_t)paddr >> 32) { +		ret = -EINVAL; +		dev_warn_once(iommu->dev, +			      "attempt to map address beyond 4GB\n"); +		goto out; +	} +  	page_table = sun50i_dte_get_page_table(sun50i_domain, iova, gfp);  	if (IS_ERR(page_table)) {  		ret = PTR_ERR(page_table); @@ -681,7 +690,8 @@ sun50i_iommu_domain_alloc_paging(struct device *dev)  	if (!sun50i_domain)  		return NULL; -	sun50i_domain->dt = iommu_alloc_pages(GFP_KERNEL, get_order(DT_SIZE)); +	sun50i_domain->dt = iommu_alloc_pages(GFP_KERNEL | GFP_DMA32, +					      get_order(DT_SIZE));  	if (!sun50i_domain->dt)  		goto err_free_domain; @@ -996,7 +1006,7 @@ static int sun50i_iommu_probe(struct platform_device *pdev)  	iommu->pt_pool = kmem_cache_create(dev_name(&pdev->dev),  					   PT_SIZE, PT_SIZE, -					   SLAB_HWCACHE_ALIGN, +					   SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA32,  					   NULL);  	if (!iommu->pt_pool)  		return -ENOMEM; @@ -1057,6 +1067,7 @@ err_free_cache:  static const struct of_device_id sun50i_iommu_dt[] = {  	{ .compatible = "allwinner,sun50i-h6-iommu", }, +	{ .compatible = "allwinner,sun50i-h616-iommu", },  	{ /* sentinel */ },  };  MODULE_DEVICE_TABLE(of, sun50i_iommu_dt); |