summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/nvmap
diff options
context:
space:
mode:
authorHiroshi DOYU <hdoyu@nvidia.com>2012-02-22 14:34:08 +0200
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-07-11 06:38:06 -0700
commitdd4018153b7cee324bb2812c74109a4deb1ad796 (patch)
treed56d31a08c9e5c2b7a28fbcd177ca0a044c99961 /drivers/video/tegra/nvmap
parent6cbf4c7465b7b70936cb422b509da0ad0829c306 (diff)
video: tegra: nvmap: Introduce IOMMU backend instead of IOVMM
Introduce IOMMU backend functions which use DMA API familiy internally. Replace tegra_iovmm_*() API with arm_iommu_*iova*() and dma_(un)map_page_(at)(). Change-Id: I0b014926ffedc12bf8f868b163982c6082d050b6 Signed-off-by: Hiroshi DOYU <hdoyu@nvidia.com> Reviewed-on: http://git-master/r/114216 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/nvmap')
-rw-r--r--drivers/video/tegra/nvmap/Makefile1
-rw-r--r--drivers/video/tegra/nvmap/nvmap_iommu.c97
2 files changed, 98 insertions, 0 deletions
diff --git a/drivers/video/tegra/nvmap/Makefile b/drivers/video/tegra/nvmap/Makefile
index 95d7f68836af..3da03af2b1eb 100644
--- a/drivers/video/tegra/nvmap/Makefile
+++ b/drivers/video/tegra/nvmap/Makefile
@@ -4,4 +4,5 @@ obj-y += nvmap_dev.o
obj-y += nvmap_handle.o
obj-y += nvmap_heap.o
obj-y += nvmap_ioctl.o
+obj-${CONFIG_IOMMU_API} += nvmap_iommu.o
obj-${CONFIG_NVMAP_RECLAIM_UNPINNED_VM} += nvmap_mru.o \ No newline at end of file
diff --git a/drivers/video/tegra/nvmap/nvmap_iommu.c b/drivers/video/tegra/nvmap/nvmap_iommu.c
new file mode 100644
index 000000000000..ca868032db3f
--- /dev/null
+++ b/drivers/video/tegra/nvmap/nvmap_iommu.c
@@ -0,0 +1,97 @@
+/*
+ * IOMMU backend support for NVMAP
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/slab.h>
+#include <mach/iomap.h>
+#include <mach/iovmm.h>
+
+#include "nvmap.h"
+
+struct tegra_iovmm_area *tegra_iommu_create_vm(struct device *dev,
+ dma_addr_t req, size_t size, pgprot_t prot)
+{
+ struct tegra_iovmm_area *area;
+ dma_addr_t iova;
+
+ area = kmalloc(sizeof(*area), GFP_KERNEL);
+ if (!area)
+ return NULL;
+
+ if (!req)
+ req = DMA_ANON_ADDR;
+
+ iova = arm_iommu_alloc_iova_at(dev, req, size);
+ if (iova == DMA_ERROR_CODE)
+ goto err_out;
+ area->iovm_start = iova;
+ area->iovm_length = size;
+ area->pgprot = prot;
+ area->dev = dev;
+ return area;
+
+err_out:
+ kfree(area);
+ return NULL;
+}
+
+void tegra_iommu_free_vm(struct tegra_iovmm_area *area)
+{
+ int i;
+ size_t count = area->iovm_length >> PAGE_SHIFT;
+
+ for (i = 0; i < count; i++) {
+ dma_addr_t iova;
+
+ iova = area->iovm_start + i * PAGE_SIZE;
+ dma_unmap_page(area->dev, iova, PAGE_SIZE, DMA_NONE);
+ }
+ kfree(area);
+}
+
+struct tegra_iovmm_client *tegra_iommu_alloc_client(struct device *dev)
+{
+ struct dma_iommu_mapping *map;
+ struct tegra_iovmm_client *client;
+
+ client = kzalloc(sizeof(*client), GFP_KERNEL);
+ if (!client)
+ return NULL;
+
+ map = arm_iommu_create_mapping(&platform_bus_type,
+ TEGRA_IOMMU_BASE, TEGRA_IOMMU_SIZE, 0);
+ if (IS_ERR(map))
+ goto err_map;
+
+ if (arm_iommu_attach_device(dev, map))
+ goto err_attach;
+ client->dev = dev;
+ return client;
+
+err_attach:
+ arm_iommu_release_mapping(map);
+err_map:
+ kfree(client);
+ return NULL;
+}
+
+void tegra_iommu_free_client(struct tegra_iovmm_client *client)
+{
+ arm_iommu_release_mapping(client->dev->archdata.mapping);
+ kfree(client);
+}