summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorOhad Ben-Cohen <ohad@wizery.com>2011-10-20 20:25:53 +0200
committerAndy Green <andy.green@linaro.org>2012-04-11 13:05:30 +0800
commitc94b60655fd7e766cc082db2ac10700f6f2110e3 (patch)
tree7e56144ce60d0a0509d38600c45dbfd8e1b4d541 /arch
parent0464f73737382b6a195cbab2927bb37e72a0f928 (diff)
ARM: OMAP: add remoteproc devices for OMAP4
Add an omap-rproc device with which one can start using OMAP4's dual-M3 "Ducati" ipu subsystem. Currently we're adding support only for the first M3 core (hence the name "ipu_c0"); support for the second M3 core, as well as for the DSP subsystem, will be added later on. Bind this device to its dedicated IOMMU device, and assign it a dedicated mailbox instance too. In addition, reserve it a physically contiguous memory region using the upcoming CMA mechanism (this makes this patch impossible to merge at this point). Note: at this point we're using a fixed CMA base address (as defined by OMAP_RPROC_CMA_BASE), but this will go away once the generic iommu-based DMA API will materialize, because at that point we will (almost) not care about the physical location of the CMA memory. Based on (but now quite far from) work done by Fernando Guzman Lugo <fernando.lugo@ti.com>. Designed with Brian Swetland <swetland@google.com>. Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Acked-by: Tony Lindgren <tony@atomide.com> Cc: Brian Swetland <swetland@google.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Grant Likely <grant.likely@secretlab.ca> Cc: Russell King <linux@arm.linux.org.uk> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Greg KH <greg@kroah.com> Cc: Stephen Boyd <sboyd@codeaurora.org> Conflicts: arch/arm/plat-omap/common.c drivers/remoteproc/Kconfig
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/Makefile4
-rw-r--r--arch/arm/mach-omap2/remoteproc.c167
-rw-r--r--arch/arm/plat-omap/common.c3
3 files changed, 173 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 4c198fc5e915..8d9655323036 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -316,3 +316,7 @@ obj-$(CONFIG_EMIF) += emif_omap.o
# Serial ATA support
s-ata-$(CONFIG_SATA_AHCI_PLATFORM) := sata.o
obj-$(CONFIG_ARCH_OMAP5) += $(s-ata-m) $(s-ata-y)
+
+ifneq ($(CONFIG_OMAP_REMOTEPROC),)
+obj-y += remoteproc.o
+endif
diff --git a/arch/arm/mach-omap2/remoteproc.c b/arch/arm/mach-omap2/remoteproc.c
new file mode 100644
index 000000000000..9d75cd91fa41
--- /dev/null
+++ b/arch/arm/mach-omap2/remoteproc.c
@@ -0,0 +1,167 @@
+/*
+ * Remote processor machine-specific module for OMAP4
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/remoteproc.h>
+#include <linux/dma-contiguous.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/omap_device.h>
+#include <plat/omap_hwmod.h>
+#include <plat/remoteproc.h>
+#include <plat/iommu.h>
+
+/*
+ * Temporarily define the CMA base address explicitly.
+ *
+ * This will go away as soon as we have the IOMMU-based generic
+ * DMA API in place.
+ */
+#define OMAP_RPROC_CMA_BASE (0xa9800000)
+
+/*
+ * These data structures define platform-specific information
+ * needed for each supported remote processor.
+ *
+ * At this point we only support the remote dual M3 "Ducati" imaging
+ * subsystem (aka "ipu"), but later on we'll also add support for the
+ * DSP ("Tesla").
+ */
+static struct omap_rproc_pdata omap4_rproc_data[] = {
+ {
+ .name = "ipu_c0",
+ .firmware = "ducati-m3-core0.xem3",
+ .mbox_name = "mailbox-1",
+ .oh_name = "ipu_c0",
+ },
+};
+
+static struct omap_iommu_arch_data omap4_rproc_iommu[] = {
+ { .name = "ducati" },
+};
+
+static struct omap_device_pm_latency omap_rproc_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static struct platform_device omap4_ducati = {
+ .name = "omap-rproc",
+ .id = 1, /* reserve 0 for tesla. we respect. */
+};
+
+static struct platform_device *omap4_rproc_devs[] __initdata = {
+ &omap4_ducati,
+};
+
+void __init omap_rproc_reserve_cma(void)
+{
+ int ret;
+
+ /* reserve CMA memory for OMAP4's M3 "ducati" remote processor */
+ ret = dma_declare_contiguous(&omap4_ducati.dev,
+ CONFIG_OMAP_DUCATI_CMA_SIZE,
+ OMAP_RPROC_CMA_BASE, 0);
+ if (ret)
+ pr_err("dma_declare_contiguous failed %d\n", ret);
+}
+
+static int __init omap_rproc_init(void)
+{
+ struct omap_hwmod *oh[2];
+ struct omap_device *od;
+ int i, ret = 0, oh_count;
+
+ /* names like ipu_cx/dsp_cx might show up on other OMAPs, too */
+ if (!cpu_is_omap44xx())
+ return 0;
+
+ /* build the remote proc devices */
+ for (i = 0; i < ARRAY_SIZE(omap4_rproc_data); i++) {
+ const char *oh_name = omap4_rproc_data[i].oh_name;
+ const char *oh_name_opt = omap4_rproc_data[i].oh_name_opt;
+ struct platform_device *pdev = omap4_rproc_devs[i];
+ oh_count = 0;
+
+ oh[0] = omap_hwmod_lookup(oh_name);
+ if (!oh[0]) {
+ pr_err("could not look up %s\n", oh_name);
+ continue;
+ }
+ oh_count++;
+
+ /*
+ * ipu might have a secondary hwmod entry (for configurations
+ * where we want both M3 cores to be represented by a single
+ * device).
+ */
+ if (oh_name_opt) {
+ oh[1] = omap_hwmod_lookup(oh_name_opt);
+ if (!oh[1]) {
+ pr_err("could not look up %s\n", oh_name_opt);
+ continue;
+ }
+ oh_count++;
+ }
+
+ omap4_rproc_data[i].device_enable = omap_device_enable;
+ omap4_rproc_data[i].device_shutdown = omap_device_shutdown;
+
+ device_initialize(&pdev->dev);
+
+ /* Set dev_name early to allow dev_xxx in omap_device_alloc */
+ dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
+
+ od = omap_device_alloc(pdev, oh, oh_count,
+ omap_rproc_latency,
+ ARRAY_SIZE(omap_rproc_latency));
+ if (!od) {
+ dev_err(&pdev->dev, "omap_device_alloc failed\n");
+ put_device(&pdev->dev);
+ ret = PTR_ERR(od);
+ continue;
+ }
+
+ ret = platform_device_add_data(pdev,
+ &omap4_rproc_data[i],
+ sizeof(struct omap_rproc_pdata));
+ if (ret) {
+ dev_err(&pdev->dev, "can't add pdata\n");
+ omap_device_delete(od);
+ put_device(&pdev->dev);
+ continue;
+ }
+
+ /* attach the remote processor to its iommu device */
+ pdev->dev.archdata.iommu = &omap4_rproc_iommu[i];
+
+ ret = omap_device_register(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "omap_device_register failed\n");
+ omap_device_delete(od);
+ put_device(&pdev->dev);
+ continue;
+ }
+ }
+
+ return ret;
+}
+device_initcall(omap_rproc_init);
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index e027cc7c6c10..92ed43a45076 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -22,8 +22,8 @@
#include <plat/vram.h>
#include <plat/dsp.h>
#include <plat/drm.h>
-
#include <plat/omap-secure.h>
+#include <plat/remoteproc.h>
#define NO_LENGTH_CHECK 0xffffffff
@@ -71,6 +71,7 @@ void __init omap_reserve(void)
omap_dsp_reserve_sdram_memblock();
omap_secure_ram_reserve_memblock();
omap_barrier_reserve_memblock();
+ omap_rproc_reserve_cma();
}
void __init omap_init_consistent_dma_size(void)