Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

remoteproc: add a rproc ops for performing address translation

The rproc_da_to_va API is currently used to perform any device to
kernel address translations to meet the different needs of the remoteproc
core/drivers (eg: loading). The functionality is achieved within the
remoteproc core, and is limited only for carveouts allocated within the
core.

A new rproc ops, da_to_va, is added to provide flexibility to platform
implementations to perform the address translation themselves when the
above conditions cannot be met by the implementations. The rproc_da_to_va()
API is extended to invoke this ops if present, and fallback to regular
processing if the platform implementation cannot provide the translation.
This will allow any remoteproc implementations to translate addresses for
dedicated memories like internal memories.

While at this, also update the rproc_da_to_va() documentation since it
is an exported function.

Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>

authored by

Suman Anna and committed by
Ohad Ben-Cohen
a01f7cd6 fec47d86

+27 -6
+25 -6
drivers/remoteproc/remoteproc_core.c
··· 137 137 iommu_domain_free(domain); 138 138 } 139 139 140 - /* 140 + /** 141 + * rproc_da_to_va() - lookup the kernel virtual address for a remoteproc address 142 + * @rproc: handle of a remote processor 143 + * @da: remoteproc device address to translate 144 + * @len: length of the memory region @da is pointing to 145 + * 141 146 * Some remote processors will ask us to allocate them physically contiguous 142 147 * memory regions (which we call "carveouts"), and map them to specific 143 - * device addresses (which are hardcoded in the firmware). 148 + * device addresses (which are hardcoded in the firmware). They may also have 149 + * dedicated memory regions internal to the processors, and use them either 150 + * exclusively or alongside carveouts. 144 151 * 145 152 * They may then ask us to copy objects into specific device addresses (e.g. 146 153 * code/data sections) or expose us certain symbols in other device address 147 154 * (e.g. their trace buffer). 148 155 * 149 - * This function is an internal helper with which we can go over the allocated 150 - * carveouts and translate specific device address to kernel virtual addresses 151 - * so we can access the referenced memory. 156 + * This function is a helper function with which we can go over the allocated 157 + * carveouts and translate specific device addresses to kernel virtual addresses 158 + * so we can access the referenced memory. This function also allows to perform 159 + * translations on the internal remoteproc memory regions through a platform 160 + * implementation specific da_to_va ops, if present. 161 + * 162 + * The function returns a valid kernel address on success or NULL on failure. 152 163 * 153 164 * Note: phys_to_virt(iommu_iova_to_phys(rproc->domain, da)) will work too, 154 165 * but only on kernel direct mapped RAM memory. Instead, we're just using 155 - * here the output of the DMA API, which should be more correct. 166 + * here the output of the DMA API for the carveouts, which should be more 167 + * correct. 156 168 */ 157 169 void *rproc_da_to_va(struct rproc *rproc, u64 da, int len) 158 170 { 159 171 struct rproc_mem_entry *carveout; 160 172 void *ptr = NULL; 173 + 174 + if (rproc->ops->da_to_va) { 175 + ptr = rproc->ops->da_to_va(rproc, da, len); 176 + if (ptr) 177 + goto out; 178 + } 161 179 162 180 list_for_each_entry(carveout, &rproc->carveouts, node) { 163 181 int offset = da - carveout->da; ··· 193 175 break; 194 176 } 195 177 178 + out: 196 179 return ptr; 197 180 } 198 181 EXPORT_SYMBOL(rproc_da_to_va);
+2
include/linux/remoteproc.h
··· 330 330 * @start: power on the device and boot it 331 331 * @stop: power off the device 332 332 * @kick: kick a virtqueue (virtqueue id given as a parameter) 333 + * @da_to_va: optional platform hook to perform address translations 333 334 */ 334 335 struct rproc_ops { 335 336 int (*start)(struct rproc *rproc); 336 337 int (*stop)(struct rproc *rproc); 337 338 void (*kick)(struct rproc *rproc, int vqid); 339 + void * (*da_to_va)(struct rproc *rproc, u64 da, int len); 338 340 }; 339 341 340 342 /**