summaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/s5p-mfc/s5p_mfc.c
diff options
context:
space:
mode:
authorMarek Szyprowski2017-02-13 11:47:51 +0100
committerMauro Carvalho Chehab2017-04-05 21:02:26 +0200
commit8e409f1d06686882c4c48ff04babce0469afe1b6 (patch)
tree0d09b41dbd3b72f4001016ab3dd5ef6c52ecd2aa /drivers/media/platform/s5p-mfc/s5p_mfc.c
parent[media] s5p-mfc: Add support for probe-time preallocated block based allocator (diff)
downloadkernel-qcow2-linux-8e409f1d06686882c4c48ff04babce0469afe1b6.tar.gz
kernel-qcow2-linux-8e409f1d06686882c4c48ff04babce0469afe1b6.tar.xz
kernel-qcow2-linux-8e409f1d06686882c4c48ff04babce0469afe1b6.zip
[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.c30
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);