]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/commitdiff
remoteproc: add an api to do pa to da conversion
authorSubramaniam Chanderashekarapuram <subramaniam.ca@ti.com>
Mon, 18 Aug 2014 22:13:17 +0000 (17:13 -0500)
committerSuman Anna <s-anna@ti.com>
Mon, 18 Aug 2014 22:14:44 +0000 (17:14 -0500)
Added an api to provide memory translation from a
physical address to a device virtual address.
Since, carveouts and mappings are stored separately,
we need to traverse both lists.

Also stored the physical addresses for RSC_DEVMEM entries
to enable pa to da conversion for dev mem address spaces too.

Signed-off-by: Subramaniam C.A <subramaniam.ca@ti.com>
Signed-off-by: Fernando Guzman Lugo <fernando.lugo@ti.com>
Signed-off-by: Suman Anna <s-anna@ti.com>
drivers/remoteproc/remoteproc_core.c
include/linux/remoteproc.h

index 0af76ae3d5443fe997e3d59e78b038b08fcf3836..834c41f8bccba46757ea206c16fd5cf0a60611fb 100644 (file)
@@ -280,6 +280,61 @@ void rproc_free_vring(struct rproc_vring *rvring)
        rsc->vring[idx].notifyid = -1;
 }
 
+/**
+ * rproc_pa_to_da() - lookup the rproc device address for a physical address
+ * @rproc: handle of a remote processor
+ * @pa: physical address of the buffer to translate
+ * @da: device address to return
+ *
+ * Communication clients of remote processors usually would need a means to
+ * convert a host buffer pointer to an equivalent device virtual address pointer
+ * that the code running on the remote processor can operate on. These buffer
+ * pointers can either be from the physically contiguous memory regions (or
+ * "carveouts") or can be some memory-mapped Device IO memory. This function
+ * provides a means to translate a given physical address to its associated
+ * device address.
+ *
+ * The function looks through both the carveouts and the device memory mappings
+ * since both of them are stored in separate lists.
+ *
+ * Returns 0 on success, or an appropriate error code otherwise. The translated
+ * device address is returned through the appropriate function argument.
+ */
+int rproc_pa_to_da(struct rproc *rproc, phys_addr_t pa, u64 *da)
+{
+       int ret = -EINVAL;
+       struct rproc_mem_entry *maps = NULL;
+
+       if (!rproc || !da)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&rproc->lock))
+               return -EINTR;
+
+       if (rproc->state == RPROC_RUNNING || rproc->state == RPROC_SUSPENDED) {
+               /* Look in the mappings first */
+               list_for_each_entry(maps, &rproc->mappings, node) {
+                       if (pa >= maps->dma && pa < (maps->dma + maps->len)) {
+                               *da = maps->da + (pa - maps->dma);
+                               ret = 0;
+                               goto exit;
+                       }
+               }
+               /* If not, check in the carveouts */
+               list_for_each_entry(maps, &rproc->carveouts, node) {
+                       if (pa >= maps->dma && pa < (maps->dma + maps->len)) {
+                               *da = maps->da + (pa - maps->dma);
+                               ret = 0;
+                               break;
+                       }
+               }
+       }
+exit:
+       mutex_unlock(&rproc->lock);
+       return ret;
+}
+EXPORT_SYMBOL(rproc_pa_to_da);
+
 /**
  * rproc_handle_vdev() - handle a vdev fw resource
  * @rproc: the remote processor
@@ -507,6 +562,7 @@ static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc,
         * We can't trust the remote processor not to change the resource
         * table, so we must maintain this info independently.
         */
+       mapping->dma = rsc->pa;
        mapping->da = rsc->da;
        mapping->len = rsc->len;
        list_add_tail(&mapping->node, &rproc->mappings);
index e1135fd0a959f16c11f1e97f368e45f7ad19ae2f..6459fa3d18504a9e6468d0c266016941c12c3df8 100644 (file)
@@ -533,6 +533,7 @@ int rproc_boot(struct rproc *rproc);
 void rproc_shutdown(struct rproc *rproc);
 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
 struct rproc *rproc_vdev_to_rproc_safe(struct virtio_device *vdev);
+int rproc_pa_to_da(struct rproc *rproc, phys_addr_t pa, u64 *da);
 
 static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev)
 {