linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ohad Ben-Cohen <ohad@wizery.com>
To: linux-omap@vger.kernel.org
Cc: Kanigeri Hari <h-kanigeri2@ti.com>,
	Omar Ramirez Luna <omar.ramirez@ti.com>,
	Guzman Lugo Fernando <x0095840@ti.com>,
	Menon Nishanth <nm@ti.com>, Hiroshi Doyu <Hiroshi.DOYU@nokia.com>,
	Ohad Ben-Cohen <ohad@wizery.com>
Subject: [RFC/PATCH 6/6] DSPBRIDGE: add dspbridge API to mark end of DMA
Date: Sat,  1 May 2010 23:44:31 +0300	[thread overview]
Message-ID: <1272746671-13423-7-git-send-email-ohad@wizery.com> (raw)
In-Reply-To: <1272746671-13423-1-git-send-email-ohad@wizery.com>

Standard DMA API is built upon the notion of "buffer ownership".
The buffer is either exclusively owned by the MPU (and therefore
may be accessed by it) or exclusively owned by the DMA device
(in our case, the dsp remote processor).
This patch adds the missing dspbridge API with which the MM
application can mark the end of a DMA transfer (and thus regain
ownership of the buffer).

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
If you want, you can also reach me at <  ohadb at ti dot com  >.

 arch/arm/plat-omap/include/dspbridge/_dcd.h     |    2 +
 arch/arm/plat-omap/include/dspbridge/proc.h     |    4 +
 arch/arm/plat-omap/include/dspbridge/wcdioctl.h |    2 +
 drivers/dsp/bridge/pmgr/wcd.c                   |   27 +++++++
 drivers/dsp/bridge/rmgr/proc.c                  |   87 +++++++++++++++++++++++
 5 files changed, 122 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/include/dspbridge/_dcd.h b/arch/arm/plat-omap/include/dspbridge/_dcd.h
index 0af4a31..adfcf67 100644
--- a/arch/arm/plat-omap/include/dspbridge/_dcd.h
+++ b/arch/arm/plat-omap/include/dspbridge/_dcd.h
@@ -113,6 +113,8 @@ extern u32 procwrap_un_map(union Trapped_Args *args, void *pr_ctxt);
 extern u32 procwrap_begin_dma_to_dsp(union Trapped_Args *args, void *pr_ctxt);
 extern u32 procwrap_stop(union Trapped_Args *args, void *pr_ctxt);
 extern u32 procwrap_begin_dma_from_dsp(union Trapped_Args *args, void *pr_ctxt);
+extern u32 procwrap_end_dma_to_dsp(union Trapped_Args *args, void *pr_ctxt);
+extern u32 procwrap_end_dma_from_dsp(union Trapped_Args *args, void *pr_ctxt);
 
 /* NODE wrapper functions */
 extern u32 nodewrap_allocate(union Trapped_Args *args, void *pr_ctxt);
diff --git a/arch/arm/plat-omap/include/dspbridge/proc.h b/arch/arm/plat-omap/include/dspbridge/proc.h
index f8450a6..7a7b8e8 100644
--- a/arch/arm/plat-omap/include/dspbridge/proc.h
+++ b/arch/arm/plat-omap/include/dspbridge/proc.h
@@ -474,6 +474,8 @@ extern dsp_status proc_stop(void *hprocessor);
  */
 extern dsp_status proc_begin_dma_to_dsp(void *hprocessor,
 				    void *pmpu_addr, u32 ul_size, u32 ul_flags);
+extern dsp_status proc_end_dma_to_dsp(void *hprocessor,
+				    void *pmpu_addr, u32 ul_size, u32 ul_flags);
 
 /*
  *  ======== proc_invalidate_memory ========
@@ -495,6 +497,8 @@ extern dsp_status proc_begin_dma_to_dsp(void *hprocessor,
  */
 extern dsp_status proc_begin_dma_from_dsp(void *hprocessor,
 					 void *pmpu_addr, u32 ul_size);
+extern dsp_status proc_end_dma_from_dsp(void *hprocessor,
+					 void *pmpu_addr, u32 ul_size);
 
 /*
  *  ======== proc_map ========
diff --git a/arch/arm/plat-omap/include/dspbridge/wcdioctl.h b/arch/arm/plat-omap/include/dspbridge/wcdioctl.h
index aba2078..a6debf2 100644
--- a/arch/arm/plat-omap/include/dspbridge/wcdioctl.h
+++ b/arch/arm/plat-omap/include/dspbridge/wcdioctl.h
@@ -455,6 +455,8 @@ union Trapped_Args {
 #define PROC_BEGINDMATODSP	_IOW(DB, DB_IOC(DB_PROC, 14), unsigned long)
 #define PROC_STOP		_IOWR(DB, DB_IOC(DB_PROC, 15), unsigned long)
 #define PROC_BEGINDMAFROMDSP	_IOW(DB, DB_IOC(DB_PROC, 16), unsigned long)
+#define PROC_ENDDMATODSP	_IOW(DB, DB_IOC(DB_PROC, 17), unsigned long)
+#define PROC_ENDDMAFROMDSP	_IOW(DB, DB_IOC(DB_PROC, 18), unsigned long)
 
 /* NODE Module */
 #define NODE_ALLOCATE		_IOWR(DB, DB_IOC(DB_NODE, 0), unsigned long)
diff --git a/drivers/dsp/bridge/pmgr/wcd.c b/drivers/dsp/bridge/pmgr/wcd.c
index 89243f1..ae6e8ab 100644
--- a/drivers/dsp/bridge/pmgr/wcd.c
+++ b/drivers/dsp/bridge/pmgr/wcd.c
@@ -114,6 +114,8 @@ static struct wcd_cmd proc_cmd[] = {
 	{procwrap_begin_dma_to_dsp},	/* PROC_BEGINDMATODSP */
 	{procwrap_stop},	/* PROC_STOP */
 	{procwrap_begin_dma_from_dsp},	/* PROC_BEGINDMAFROMDSP */
+	{procwrap_end_dma_to_dsp},	/* PROC_ENDDMATODSP */
+	{procwrap_end_dma_from_dsp},	/* PROC_ENDDMAFROMDSP */
 };
 
 /* NODE wrapper functions */
@@ -709,6 +711,31 @@ u32 procwrap_begin_dma_from_dsp(union Trapped_Args *args, void *pr_ctxt)
 	return status;
 }
 
+u32 procwrap_end_dma_to_dsp(union Trapped_Args *args, void *pr_ctxt)
+{
+	dsp_status status;
+
+	if (args->args_proc_flushmemory.ul_flags >
+	    PROC_WRITEBACK_INVALIDATE_MEM)
+		return DSP_EINVALIDARG;
+
+	status = proc_end_dma_to_dsp(args->args_proc_flushmemory.hprocessor,
+				   args->args_proc_flushmemory.pmpu_addr,
+				   args->args_proc_flushmemory.ul_size,
+				   args->args_proc_flushmemory.ul_flags);
+	return status;
+}
+
+u32 procwrap_end_dma_from_dsp(union Trapped_Args *args, void *pr_ctxt)
+{
+	dsp_status status;
+
+	status =
+	    proc_end_dma_from_dsp(args->args_proc_invalidatememory.hprocessor,
+				   args->args_proc_invalidatememory.pmpu_addr,
+				   args->args_proc_invalidatememory.ul_size);
+	return status;
+}
 /*
  * ======== procwrap_enum_resources ========
  */
diff --git a/drivers/dsp/bridge/rmgr/proc.c b/drivers/dsp/bridge/rmgr/proc.c
index 8a76681..c185cd1 100644
--- a/drivers/dsp/bridge/rmgr/proc.c
+++ b/drivers/dsp/bridge/rmgr/proc.c
@@ -700,6 +700,36 @@ out:
 	return ret;
 }
 
+static int memory_regain_ownership(struct memory_map_info *map_info,
+		unsigned long start, ssize_t len, enum dma_data_direction dir)
+{
+	int ret = 0;
+	unsigned long first_data_page = start >> PAGE_SHIFT;
+	unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT);
+	/* calculating the number of pages this area spans */
+	unsigned long num_pages = last_data_page - first_data_page + 1;
+	struct bridge_dma_map_info *dma_info = &map_info->dma_info;
+
+	if (!dma_info->sg)
+		goto out;
+
+	if (dma_info->dir != dir || dma_info->num_pages != num_pages) {
+		pr_err("%s: dma info doesn't match given params\n", __func__);
+		return -EINVAL;
+	}
+
+	dma_unmap_sg(bridge, dma_info->sg, num_pages, dma_info->dir);
+
+	pr_debug("%s: dma_map_sg unmapped\n", __func__);
+
+	kfree(dma_info->sg);
+
+	map_info->dma_info.sg = NULL;
+
+out:
+	return ret;
+}
+
 /* Cache operation against kernel address instead of users */
 static int memory_release_ownership(struct memory_map_info *map_info,
 		unsigned long start, ssize_t len, enum dma_data_direction dir)
@@ -798,6 +828,47 @@ err_out:
 	return status;
 }
 
+static dsp_status proc_end_dma(void *hprocessor, void *pmpu_addr,
+				   u32 ul_size, u32 ul_flags,
+				   enum dsp_flushtype ftype)
+{
+	/* Keep STATUS here for future additions to this function */
+	dsp_status status = DSP_SOK;
+	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+	struct memory_map_info *map_info;
+
+	DBC_REQUIRE(refs > 0);
+
+	if (!MEM_IS_VALID_HANDLE(p_proc_object, PROC_SIGNATURE)) {
+		status = DSP_EHANDLE;
+		goto err_out;
+	}
+
+	pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__,
+							(u32)pmpu_addr,
+							ul_size, ftype);
+
+	/* find requested memory are in cached mapping information */
+	map_info = find_containing_mapping(p_proc_object, (u32) pmpu_addr,
+								ul_size);
+	if (!map_info) {
+		pr_err("%s: find_containing_mapping failed\n", __func__);
+		status = DSP_EHANDLE;
+		goto err_out;
+	}
+
+	if (memory_regain_ownership(map_info, (u32) pmpu_addr, ul_size,
+								ftype)) {
+		pr_err("%s: InValid address parameters %p %x\n",
+		       __func__, pmpu_addr, ul_size);
+		status = DSP_EHANDLE;
+		goto err_out;
+	}
+
+err_out:
+	return status;
+}
+
 /*
  *  ======== proc_flush_memory ========
  *  Purpose:
@@ -824,6 +895,22 @@ dsp_status proc_begin_dma_from_dsp(void *hprocessor, void *pmpu_addr,
 	return proc_begin_dma(hprocessor, pmpu_addr, ul_size, 0, dir);
 }
 
+dsp_status proc_end_dma_to_dsp(void *hprocessor, void *pmpu_addr,
+			     u32 ul_size, u32 ul_flags)
+{
+	enum dma_data_direction dir = DMA_BIDIRECTIONAL;
+
+	return proc_end_dma(hprocessor, pmpu_addr, ul_size, ul_flags, dir);
+}
+
+dsp_status proc_end_dma_from_dsp(void *hprocessor, void *pmpu_addr,
+							u32 ul_size)
+{
+	enum dma_data_direction dir = DMA_FROM_DEVICE;
+
+	return proc_end_dma(hprocessor, pmpu_addr, ul_size, 0, dir);
+}
+
 /*
  *  ======== proc_get_resource_info ========
  *  Purpose:
-- 
1.6.3.3


  parent reply	other threads:[~2010-05-01 20:48 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-01 20:44 [RFC/PATCH 0/6] DSPBRIDGE: fix mem+cache API issues Ohad Ben-Cohen
2010-05-01 20:44 ` [RFC/PATCH 1/6] DSPBRIDGE: add memory_map_info to PROC Ohad Ben-Cohen
2010-05-01 20:44 ` [RFC/PATCH 2/6] DSPBRIDGE: remember mapping and page info in proc_map Ohad Ben-Cohen
2010-05-15  8:34   ` Felipe Contreras
2010-05-16 23:00     ` Ohad Ben-Cohen
2010-05-01 20:44 ` [RFC/PATCH 3/6] DSPBRIDGE: remove mapping information in proc_unmap Ohad Ben-Cohen
2010-05-15  8:38   ` Felipe Contreras
2010-05-16 23:02     ` Ohad Ben-Cohen
2010-05-01 20:44 ` [RFC/PATCH 4/6] DSPBRIDGE: do not call follow_page Ohad Ben-Cohen
2010-05-01 20:44 ` [RFC/PATCH 5/6] DSPBRIDGE: do not use low level cache manipulation API Ohad Ben-Cohen
2010-05-02 11:56   ` Ohad Ben-Cohen
2010-05-01 20:44 ` Ohad Ben-Cohen [this message]
2010-05-02 13:17 ` [RFC/PATCH 0/6] DSPBRIDGE: fix mem+cache API issues Felipe Contreras
2010-05-02 17:47   ` Ohad Ben-Cohen
2010-05-14 19:27     ` Felipe Contreras
2010-05-14 19:49       ` Omar Ramirez Luna
2010-05-15  8:26         ` Felipe Contreras
2010-05-15  9:08           ` Felipe Contreras
2010-05-16 16:08             ` Felipe Contreras
2010-05-16 17:35       ` Felipe Contreras
2010-05-16 22:57         ` Ohad Ben-Cohen
2010-05-16 23:51           ` Felipe Contreras
2010-05-18  8:05             ` Ohad Ben-Cohen
2010-05-18 11:02               ` Felipe Contreras
2010-05-18 11:14                 ` Ohad Ben-Cohen
2010-05-18 11:43                   ` Felipe Contreras
2010-05-18 11:57                     ` Ohad Ben-Cohen
2010-05-18 12:24                       ` Felipe Contreras
2010-05-18 12:53                         ` Ohad Ben-Cohen
2010-05-19 16:50                           ` Felipe Contreras
2010-05-20 21:22                             ` Ohad Ben-Cohen
2010-05-20 21:23                               ` Ohad Ben-Cohen
2010-05-21  6:14                               ` Felipe Contreras
2010-05-21  8:22                                 ` Ohad Ben-Cohen
2010-05-21  9:42                                   ` Felipe Contreras
2010-05-24 16:19                                     ` Ohad Ben-Cohen
2010-05-24 19:21                                       ` Felipe Contreras
2010-05-24 19:49                                         ` Ohad Ben-Cohen
2010-05-16 22:35       ` Ohad Ben-Cohen
2010-05-16 23:15         ` Felipe Contreras
2010-05-16 23:21           ` Ohad Ben-Cohen
2010-05-16 23:25           ` Ohad Ben-Cohen
2010-05-17  0:05             ` Felipe Contreras
2010-05-18  6:20               ` Ohad Ben-Cohen
2010-05-20 21:18       ` Ohad Ben-Cohen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1272746671-13423-7-git-send-email-ohad@wizery.com \
    --to=ohad@wizery.com \
    --cc=Hiroshi.DOYU@nokia.com \
    --cc=h-kanigeri2@ti.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=nm@ti.com \
    --cc=omar.ramirez@ti.com \
    --cc=x0095840@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).