|
@@ -43,6 +43,10 @@ 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;
|
|
|
+module_param_named(mem, mfc_mem_size, charp, 0644);
|
|
|
+MODULE_PARM_DESC(mem, "Preallocated memory size for the firmware and context buffers");
|
|
|
+
|
|
|
/* Helper functions for interrupt processing */
|
|
|
|
|
|
/* Remove from hw execution round robin */
|
|
@@ -1173,6 +1177,8 @@ 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
|
|
@@ -1186,17 +1192,39 @@ static int s5p_mfc_configure_common_memory(struct s5p_mfc_dev *mfc_dev)
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
- mfc_dev->mem_dev[BANK1_CTX] = mfc_dev->mem_dev[BANK2_CTX] = dev;
|
|
|
- ret = s5p_mfc_alloc_firmware(mfc_dev);
|
|
|
- if (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 ret;
|
|
|
+ return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
- mfc_dev->dma_base[BANK1_CTX] = mfc_dev->fw_buf.dma;
|
|
|
- mfc_dev->dma_base[BANK2_CTX] = mfc_dev->fw_buf.dma;
|
|
|
+ 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));
|
|
|
|
|
|
+ dev_info(dev, "preallocated %ld MiB buffer for the firmware and context buffers\n",
|
|
|
+ (mem_size / SZ_1M));
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1205,6 +1233,9 @@ 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);
|
|
|
}
|
|
|
|