From d7134bc783a84ebb1c219ca0e104e9aa53ba8424 Mon Sep 17 00:00:00 2001 From: Ard van Breemen Date: Wed, 22 Mar 2017 16:11:42 +0100 Subject: [PATCH] Revert "Current MFC driver depends on the fact that when IOMMU is available, the DMA-mapping framework and its IOMMU glue will use first-fit allocator. This was true for ARM architecture, but its not for ARM64 arch. However, in case of MFC v6+ hardware and latest firmware, it turned out that there is no strict requirement for ALL buffers to be allocated on higher addresses than the firmware base. This requirement is true only for the device and per-context buffers. All video data buffers can be allocated anywhere for all MFC v6+ versions." This reverts commit 2bf9e9f04adf02ee1e4972827295a3d662eb59f5. --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 47 +++------------ .../media/platform/s5p-mfc/s5p_mfc_common.h | 4 -- drivers/media/platform/s5p-mfc/s5p_mfc_opr.c | 57 +++++++------------ 3 files changed, 27 insertions(+), 81 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 1a87af65c06a..3618e2272f5e 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -43,10 +43,6 @@ int mfc_debug_level; module_param_named(debug, mfc_debug_level, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug level - higher value produces more verbose messages"); -static char *mfc_mem_size = NULL; -module_param_named(mem, mfc_mem_size, charp, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(mem, "Preallocated memory size for the firmware and context buffers"); - /* Helper functions for interrupt processing */ /* Remove from hw execution round robin */ @@ -1182,8 +1178,6 @@ static void s5p_mfc_unconfigure_2port_memory(struct s5p_mfc_dev *mfc_dev) 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 @@ -1197,38 +1191,16 @@ static int s5p_mfc_configure_common_memory(struct s5p_mfc_dev *mfc_dev) if (ret) return ret; - if (mfc_mem_size) - mem_size = memparse(mfc_mem_size, NULL); - - 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); - return -ENOMEM; - } - - mfc_dev->mem_virt = dma_alloc_coherent(dev, mem_size, - &mfc_dev->mem_base, GFP_KERNEL); - if (!mfc_dev->mem_virt) { - 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; - - /* Firmware allocation cannot fail in this case */ - s5p_mfc_alloc_firmware(mfc_dev); - mfc_dev->mem_dev[BANK1_CTX] = mfc_dev->mem_dev[BANK2_CTX] = dev; - vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); + ret = s5p_mfc_alloc_firmware(mfc_dev); + if (ret) { + exynos_unconfigure_iommu(dev); + return ret; + } - dev_info(dev, "preallocated %ld MiB buffer for the firmware and context buffers\n", - (mem_size / SZ_1M)); + mfc_dev->dma_base[BANK1_CTX] = mfc_dev->fw_buf.dma; + mfc_dev->dma_base[BANK2_CTX] = mfc_dev->fw_buf.dma; + vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); return 0; } @@ -1238,9 +1210,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); vb2_dma_contig_clear_max_seg_size(dev); } diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index a209a7a52907..e38a8eec15f9 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -315,10 +315,6 @@ struct s5p_mfc_dev { unsigned int int_err; wait_queue_head_t queue; struct s5p_mfc_priv_buf fw_buf; - size_t mem_size; - dma_addr_t mem_base; - unsigned long *mem_bitmap; - void *mem_virt; dma_addr_t dma_base[BANK_CTX_NUM]; unsigned long hw_lock; struct s5p_mfc_ctx *ctx[MFC_NUM_CONTEXTS]; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c index 34a66189d980..9294ee124661 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c @@ -40,60 +40,41 @@ void s5p_mfc_init_regs(struct s5p_mfc_dev *dev) int s5p_mfc_alloc_priv_buf(struct s5p_mfc_dev *dev, unsigned int mem_ctx, struct s5p_mfc_priv_buf *b) { - unsigned int bits = dev->mem_size >> PAGE_SHIFT; - unsigned int count = b->size >> PAGE_SHIFT; - unsigned int align = (SZ_64K >> PAGE_SHIFT) - 1; - unsigned int start, offset; + struct device *mem_dev = dev->mem_dev[mem_ctx]; + dma_addr_t base = dev->dma_base[mem_ctx]; mfc_debug(3, "Allocating priv: %zu\n", b->size); - if (dev->mem_virt) { - start = bitmap_find_next_zero_area(dev->mem_bitmap, bits, 0, count, align); - if (start > bits) - goto no_mem; + b->ctx = mem_ctx; + b->virt = dma_alloc_coherent(mem_dev, b->size, &b->dma, GFP_KERNEL); - bitmap_set(dev->mem_bitmap, start, count); - offset = start << PAGE_SHIFT; - b->virt = dev->mem_virt + offset; - b->dma = dev->mem_base + offset; - } else { - struct device *mem_dev = dev->mem_dev[mem_ctx]; - dma_addr_t base = dev->dma_base[mem_ctx]; + if (!b->virt) { + mfc_err("Allocating private buffer of size %zu failed\n", + b->size); + return -ENOMEM; + } - b->ctx = mem_ctx; - b->virt = dma_alloc_coherent(mem_dev, b->size, &b->dma, GFP_KERNEL); - if (!b->virt) - goto no_mem; - if (b->dma < base) { - mfc_err("Invalid memory configuration - buffer (%pad) is below base memory address(%pad)\n", - &b->dma, &base); - dma_free_coherent(mem_dev, b->size, b->virt, b->dma); - return -ENOMEM; - } + if (b->dma < base) { + mfc_err("Invalid memory configuration - buffer (%pad) is below base memory address(%pad)\n", + &b->dma, &base); + dma_free_coherent(mem_dev, b->size, b->virt, b->dma); + return -ENOMEM; } mfc_debug(3, "Allocated addr %p %pad\n", b->virt, &b->dma); return 0; -no_mem: - mfc_err("Allocating private buffer of size %zu failed\n", b->size); - return -ENOMEM; } void s5p_mfc_release_priv_buf(struct s5p_mfc_dev *dev, struct s5p_mfc_priv_buf *b) { - if (dev->mem_virt) { - unsigned int start = (b->dma - dev->mem_base) >> PAGE_SHIFT; - unsigned int count = b->size >> PAGE_SHIFT; - - bitmap_clear(dev->mem_bitmap, start, count); - } else { - struct device *mem_dev = dev->mem_dev[b->ctx]; + struct device *mem_dev = dev->mem_dev[b->ctx]; + if (b->virt) { dma_free_coherent(mem_dev, b->size, b->virt, b->dma); + b->virt = NULL; + b->dma = 0; + b->size = 0; } - b->virt = NULL; - b->dma = 0; - b->size = 0; }