diff mbox

ARM: EXYNOS4: Support of memory test driver

Message ID 1322804203-4174-1-git-send-email-subash.ramaswamy@linaro.org
State Deferred
Headers show

Commit Message

subashp Dec. 2, 2011, 5:36 a.m. UTC
This commit adds the basic driver modules to test the memory allocators
i.e., DMA based CMA and IOMMU interfaces.

In this commit, the basic scenario to test CMA is provided.

Signed-off-by: Subash Patel <subash.ramaswamy@linaro.org>
---
 arch/arm/mach-exynos4/mach-smdkv310.c |    6 +
 drivers/media/video/Kconfig           |   34 ++++++
 drivers/media/video/Makefile          |    3 +
 drivers/media/video/cma_test_dev.c    |  198 +++++++++++++++++++++++++++++++++
 4 files changed, 241 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/cma_test_dev.c
diff mbox

Patch

diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
index c21acb5..c6c7ded 100644
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -144,6 +144,11 @@  static struct platform_device smdkv310_smsc911x = {
 	},
 };
 
+static struct platform_device mem_test = {
+	.name		= "cma_test",
+	.id		= -1,
+};
+
 static uint32_t smdkv310_keymap[] __initdata = {
 	/* KEY(row, col, keycode) */
 	KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
@@ -191,6 +196,7 @@  static struct platform_device *smdkv310_devices[] __initdata = {
 	&samsung_asoc_idma,
 	&smdkv310_smsc911x,
 	&exynos4_device_ahci,
+	&mem_test,
 };
 
 static void __init smdkv310_smsc911x_init(void)
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index f574dc0..f8dfbd3 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -70,6 +70,40 @@  config VIDEOBUF2_DMA_SG
 # Multimedia Video device configuration
 #
 
+menuconfig MEMORY_TEST_DRIVERS
+        bool "Memory test drivers"
+        depends on VIDEO_V4L2
+        default y
+        ---help---
+          Say Y here to enable memory test drivers. This driver can be used
+	  to make calls to DMA interface for CMA and IOMMU based allocations.
+	  This driver will also test the buffer object sharing interface.
+
+if MEMORY_TEST_DRIVERS
+config MEMORY_TEST_CMA
+	bool "Enable memory test driver for CMA"
+	default n
+	---help---
+	  Say Y here to enable the memory test driver to test CMA allocator
+	  In doubt, say N
+
+config MEMORY_TEST_IOMMU
+	bool "Enable memory test driver for IOMMU"
+	default n
+	---help---
+	  Say Y here to enable the memory test driver to test allocator using
+	  IOMMU interface.
+	  In doubt, say N
+
+config MEMORY_TEST_BUFOBJ
+	bool "Enable memory test driver for buffer object
+	default n
+	---help---
+	  Say Y here to enable the memory test driver to test the buffer object
+	  sharing interface.
+	  In doubt, say N
+endif
+
 menuconfig VIDEO_CAPTURE_DRIVERS
 	bool "Video capture adapters"
 	depends on VIDEO_V4L2
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 2723900..8b0e5a0 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -22,6 +22,9 @@  endif
 
 obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
 
+# Memory allocator test-suite
+obj-$(CONFIG_MEMORY_TEST_CMA) += cma_test_dev.o
+
 # All i2c modules must come first:
 
 obj-$(CONFIG_VIDEO_TUNER) += tuner.o
diff --git a/drivers/media/video/cma_test_dev.c b/drivers/media/video/cma_test_dev.c
new file mode 100644
index 0000000..5b3301c
--- /dev/null
+++ b/drivers/media/video/cma_test_dev.c
@@ -0,0 +1,198 @@ 
+/*
+ * Copyright 2011. Samsung Electronics
+ *
+ * Author: Subash Patel <subash.rp@samsung.com>
+ *
+ * This module is used to test the DMA-CMA allocator framework.
+ * Covered under GNU-GPL
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/dma-contiguous.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+
+#include <asm/sizes.h>
+
+#define MODULE_NAME	"cma_test_drv"
+#define err(format, arg...) \
+	printk(KERN_ERR "%s: " format, MODULE_NAME, ## arg)
+#define RAM_PHY_BASE	0x51000000
+#define ALLOC_SIZE	SZ_2M
+#define RESERVE_SIZE	SZ_8M
+#define MEM_TEST_MINOR	10
+/* ioctl commands. needs to be synched with test-case */
+#define ALLOCATE	0
+#define DEALLOCATE	1
+
+#define uint32 unsigned int
+#define u64 unsigned long
+
+static u64 mem_dma_mask = DMA_BIT_MASK(32);
+static struct page *page_base;
+static struct platform_device *my_dev;
+
+struct platform_device mem_device = {
+	.name		= "mem_dev",
+	.id		= -1,
+	.dev		= {
+		.dma_mask		= &mem_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	}
+};
+
+void __init reserve_mem(phys_addr_t pbase, uint32 psize)
+{
+	if (!my_dev)
+		printk(KERN_ERR"my_dev is NULL\n");
+	else
+		printk(KERN_ERR"my_dev is not NULL\n");
+
+	printk(KERN_ERR"my_dev->dev=0x%x\n", &my_dev->dev);
+	/*if (dma_declare_contiguous(&mem_device.dev, psize, pbase, 0))*/
+	if (dma_declare_contiguous(&my_dev->dev, psize, pbase, 0))
+		printk(KERN_ERR"Failed to reserve memory for the memory_dev\n");
+	return;
+}
+static int mem_test_open(struct inode *inode, struct file *file)
+{
+	err("inside %s\n", __func__);
+	return 0;
+}
+static ssize_t mem_test_read(struct file *file, char __user *buf,
+					size_t count, loff_t *pos)
+{
+	err("inside %s\n", __func__);
+	return 0;
+}
+static ssize_t mem_test_write(struct file *file, const char __user *buf,
+					size_t count, loff_t *pos)
+{
+	err("inside %s\n", __func__);
+	return 0;
+}
+static int mem_test_close(struct inode *inode, struct file *file)
+{
+	err("inside %s\n", __func__);
+	return 0;
+}
+static long mem_test_ioctl(struct file *file, unsigned int cmd,
+					unsigned long arg)
+{
+	size_t alloc_size = ALLOC_SIZE;
+	unsigned long order = get_order(alloc_size);
+	size_t count = alloc_size >> PAGE_SHIFT;
+	err("inside %s\n", __func__);
+
+	switch (cmd) {
+
+	case ALLOCATE:
+		page_base = dma_alloc_from_contiguous(&my_dev->dev,
+							count, order);
+		if (!page_base) {
+			printk(KERN_ERR"Failed to allocate memory\n");
+			return -1;
+		} else {
+			printk(KERN_ERR"Allocated memory. base=0x%x\n",
+								page_base);
+		}
+		break;
+	case DEALLOCATE:
+		if (page_base) {
+			if (dma_release_from_contiguous(&my_dev->dev,
+							page_base, count))
+				printk(KERN_ERR"Freed the memory\n");
+			else
+				printk(KERN_ERR"Failed to release memory\n");
+		} else {
+			printk(KERN_ERR"No pre-allocated memory exists\n");
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+static int mem_test_mmap(struct file *file, struct vm_area_struct *vm)
+{
+	err("inside %s\n", __func__);
+	return 0;
+}
+
+const struct file_operations mem_test_fops = {
+	.owner		= THIS_MODULE,
+	.open		= mem_test_open,
+	.read		= mem_test_read,
+	.write		= mem_test_write,
+	.release	= mem_test_close,
+	.mmap		= mem_test_mmap,
+	.unlocked_ioctl	= mem_test_ioctl,
+};
+static struct miscdevice mem_test_dev = {
+	MEM_TEST_MINOR,
+	"mem_dev",
+	&mem_test_fops
+};
+static int mem_test_probe(struct platform_device *pdev)
+{
+	int ret = misc_register(&mem_test_dev);
+	my_dev = pdev;
+	printk(KERN_ERR"mem_test_probe: pdev=0x%x\n", pdev);
+	if (ret)
+		return ret;
+	printk(KERN_ERR"Memory test module from Samsung Electronics");
+	return 0;
+}
+static void __devexit mem_test_remove(struct platform_device *pdev)
+{
+	err("inside %s\n", __func__);
+	misc_deregister(&mem_test_dev);
+	return;
+}
+static struct platform_device_id memory_test_ids[] = {
+	{
+		.name		= "cma_test",
+		.driver_data	= (void *)NULL,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(platform, memory_test_ids);
+
+static struct platform_driver memory_test_driver = {
+	.probe		= mem_test_probe,
+	.remove		= __devexit_p(mem_test_remove),
+	.id_table	= memory_test_ids,
+	.driver		= {
+		.name = MODULE_NAME,
+		.owner = THIS_MODULE,
+	}
+};
+
+static int init_mem_test_module()
+{
+	int ret = platform_driver_register(&memory_test_driver);
+	err("inside %s\n", __func__);
+	if (ret)
+		err("%s:platform_driver_register failed:%d", __func__,
+								ret);
+	reserve_mem(RAM_PHY_BASE, RESERVE_SIZE);
+
+	return ret;
+}
+
+static void exit_mem_test_module()
+{
+	err("inside %s\n", __func__);
+	return;
+}
+
+module_init(init_mem_test_module);
+module_exit(exit_mem_test_module);
+
+MODULE_AUTHOR("Subash Patel <subash.rp@samsung.com");
+MODULE_DESCRIPTION("DMA-CMA allocator test device");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");