From f0092d3a09803c60e1f047b2673204221ce54fad Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Wed, 1 Jun 2016 17:12:58 +0800 Subject: [PATCH] CHROMIUM: [media] rockchip-vpu: add dma-iommu support on arm64 Change-Id: Ieeaed0320202a6d056b6c248d5b72df2419bf29c Signed-off-by: Jeffy Chen Signed-off-by: Yakir Yang --- .../platform/rockchip-vpu/rk3288_vpu_common.h | 2 + .../platform/rockchip-vpu/rk3288_vpu_hw.c | 52 ++++++++++++------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/rockchip-vpu/rk3288_vpu_common.h b/drivers/media/platform/rockchip-vpu/rk3288_vpu_common.h index 5bafbc12b943..3ff5c69992b6 100644 --- a/drivers/media/platform/rockchip-vpu/rk3288_vpu_common.h +++ b/drivers/media/platform/rockchip-vpu/rk3288_vpu_common.h @@ -147,6 +147,7 @@ enum rk3288_vpu_state { * @enc_base: Mapped address of VPU encoder register for convenience. * @dec_base: Mapped address of VPU decoder register for convenience. * @mapping: DMA IOMMU mapping. + * @domain: DMA IOMMU domain. * @vpu_mutex: Mutex to synchronize V4L2 calls. * @irqlock: Spinlock to synchronize access to data structures * shared with interrupt handlers. @@ -176,6 +177,7 @@ struct rk3288_vpu_dev { void __iomem *enc_base; void __iomem *dec_base; struct dma_iommu_mapping *mapping; + struct iommu_domain *domain; struct mutex vpu_mutex; /* video_device lock */ spinlock_t irqlock; diff --git a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c b/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c index 8ca8b9abd548..531fc523647d 100644 --- a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c +++ b/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include "rk3288_vpu_regs.h" @@ -203,45 +203,57 @@ static int rk3288_vpu_iommu_init(struct rk3288_vpu_dev *vpu) { int ret; - vpu->mapping = arm_iommu_create_mapping(&platform_bus_type, - 0x10000000, SZ_2G); - if (IS_ERR(vpu->mapping)) { - ret = PTR_ERR(vpu->mapping); - return ret; - } - vpu->dev->dma_parms = devm_kzalloc(vpu->dev, - sizeof(*vpu->dev->dma_parms), GFP_KERNEL); + sizeof(*vpu->dev->dma_parms), + GFP_KERNEL); if (!vpu->dev->dma_parms) - goto err_release_mapping; + return -ENOMEM; - dma_set_max_seg_size(vpu->dev, 0xffffffffu); + vpu->domain = iommu_domain_alloc(vpu->dev->bus); + if (!vpu->domain) + goto err_free_parms; - ret = arm_iommu_attach_device(vpu->dev, vpu->mapping); + ret = iommu_get_dma_cookie(vpu->domain); if (ret) - goto err_release_mapping; + goto err_free_domain; - return 0; + ret = dma_set_coherent_mask(vpu->dev, DMA_BIT_MASK(32)); + if (ret) + goto err_put_cookie; -err_release_mapping: - arm_iommu_release_mapping(vpu->mapping); + dma_set_max_seg_size(vpu->dev, DMA_BIT_MASK(32)); + + ret = iommu_attach_device(vpu->domain, vpu->dev); + if (ret) + goto err_put_cookie; + + common_iommu_setup_dma_ops(vpu->dev, 0x10000000, SZ_2G, + vpu->domain->ops); + + return 0; +err_put_cookie: + iommu_put_dma_cookie(vpu->domain); +err_free_domain: + iommu_domain_free(vpu->domain); +err_free_parms: return ret; } static void rk3288_vpu_iommu_cleanup(struct rk3288_vpu_dev *vpu) { - arm_iommu_detach_device(vpu->dev); - arm_iommu_release_mapping(vpu->mapping); + iommu_detach_device(vpu->domain, vpu->dev); + iommu_put_dma_cookie(vpu->domain); + iommu_domain_free(vpu->domain); } -#else +#else /* CONFIG_ROCKCHIP_IOMMU */ static inline int rk3288_vpu_iommu_init(struct rk3288_vpu_dev *vpu) { return 0; } static inline void rk3288_vpu_iommu_cleanup(struct rk3288_vpu_dev *vpu) { } -#endif +#endif /* CONFIG_ROCKCHIP_IOMMU */ int rk3288_vpu_hw_probe(struct rk3288_vpu_dev *vpu) { -- 2.34.1