diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2017-02-13 13:47:51 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2017-04-05 22:02:26 +0300 |
commit | 8e409f1d06686882c4c48ff04babce0469afe1b6 (patch) | |
tree | 0d09b41dbd3b72f4001016ab3dd5ef6c52ecd2aa /drivers/media/platform/s5p-mfc/s5p_mfc.c | |
parent | 25e73b425c34e32d220fc2b06ba4bf9354850400 (diff) | |
download | linux-8e409f1d06686882c4c48ff04babce0469afe1b6.tar.xz |
[media] s5p-mfc: Remove special configuration of IOMMU domain
The main reason for using special configuration of IOMMU domain was the
problem with MFC firmware, which failed to operate properly when placed
at 0 DMA address. Instead of adding custom code for configuring each
variant of IOMMU domain and architecture specific glue code, simply use
what arch code provides and if the DMA base address equals zero, skip
first 128 KiB to keep required alignment. This patch also make the driver
operational on ARM64 architecture, because it no longer depends on ARM
specific DMA-mapping and IOMMU glue code functions.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Tested-by: Javier Martinez Canillas <javier@osg.samsung.com>
Acked-by: Andrzej Hajda <a.hajda@samsung.com>
Tested-by: Smitha T Murthy <smitha.t@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/platform/s5p-mfc/s5p_mfc.c')
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc.c | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index e3d760516c4c..e6a81aa50c8e 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1179,18 +1179,6 @@ static int s5p_mfc_configure_common_memory(struct s5p_mfc_dev *mfc_dev) struct device *dev = &mfc_dev->plat_dev->dev; unsigned long mem_size = SZ_8M; unsigned int bitmap_size; - /* - * When IOMMU is available, we cannot use the default configuration, - * because of MFC firmware requirements: address space limited to - * 256M and non-zero default start address. - * This is still simplified, not optimal configuration, but for now - * IOMMU core doesn't allow to configure device's IOMMUs channel - * separately. - */ - int ret = exynos_configure_iommu(dev, S5P_MFC_IOMMU_DMA_BASE, - S5P_MFC_IOMMU_DMA_SIZE); - if (ret) - return ret; if (mfc_mem_size) mem_size = memparse(mfc_mem_size, NULL); @@ -1198,10 +1186,8 @@ static int s5p_mfc_configure_common_memory(struct s5p_mfc_dev *mfc_dev) bitmap_size = BITS_TO_LONGS(mem_size >> PAGE_SHIFT) * sizeof(long); mfc_dev->mem_bitmap = kzalloc(bitmap_size, GFP_KERNEL); - if (!mfc_dev->mem_bitmap) { - exynos_unconfigure_iommu(dev); + if (!mfc_dev->mem_bitmap) return -ENOMEM; - } mfc_dev->mem_virt = dma_alloc_coherent(dev, mem_size, &mfc_dev->mem_base, GFP_KERNEL); @@ -1209,13 +1195,24 @@ static int s5p_mfc_configure_common_memory(struct s5p_mfc_dev *mfc_dev) kfree(mfc_dev->mem_bitmap); dev_err(dev, "failed to preallocate %ld MiB for the firmware and context buffers\n", (mem_size / SZ_1M)); - exynos_unconfigure_iommu(dev); return -ENOMEM; } mfc_dev->mem_size = mem_size; mfc_dev->dma_base[BANK1_CTX] = mfc_dev->mem_base; mfc_dev->dma_base[BANK2_CTX] = mfc_dev->mem_base; + /* + * MFC hardware cannot handle 0 as a base address, so mark first 128K + * as used (to keep required base alignment) and adjust base address + */ + if (mfc_dev->mem_base == (dma_addr_t)0) { + unsigned int offset = 1 << MFC_BASE_ALIGN_ORDER; + + bitmap_set(mfc_dev->mem_bitmap, 0, offset >> PAGE_SHIFT); + mfc_dev->dma_base[BANK1_CTX] += offset; + mfc_dev->dma_base[BANK2_CTX] += offset; + } + /* Firmware allocation cannot fail in this case */ s5p_mfc_alloc_firmware(mfc_dev); @@ -1232,7 +1229,6 @@ static void s5p_mfc_unconfigure_common_memory(struct s5p_mfc_dev *mfc_dev) { struct device *dev = &mfc_dev->plat_dev->dev; - exynos_unconfigure_iommu(dev); dma_free_coherent(dev, mfc_dev->mem_size, mfc_dev->mem_virt, mfc_dev->mem_base); kfree(mfc_dev->mem_bitmap); |