in ti_k3_r5_remoteproc.c [862:952]
static int k3_r5_reserved_mem_init(struct k3_r5_rproc *kproc)
{
struct device *dev = kproc->dev;
struct device_node *np = dev_of_node(dev);
struct device_node *rmem_np;
struct reserved_mem *rmem;
int num_rmems;
int ret, i;
num_rmems = of_property_count_elems_of_size(np, "memory-region",
sizeof(phandle));
if (num_rmems <= 0) {
dev_err(dev, "device does not have reserved memory regions, ret = %d\n",
num_rmems);
return -EINVAL;
}
if (num_rmems < 2) {
dev_err(dev, "device needs at least two memory regions to be defined, num = %d\n",
num_rmems);
return -EINVAL;
}
/* use reserved memory region 0 for vring DMA allocations */
ret = of_reserved_mem_device_init_by_idx(dev, np, 0);
if (ret) {
dev_err(dev, "device cannot initialize DMA pool, ret = %d\n",
ret);
return ret;
}
num_rmems--;
kproc->rmem = kcalloc(num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
if (!kproc->rmem) {
ret = -ENOMEM;
goto release_rmem;
}
/* use remaining reserved memory regions for static carveouts */
for (i = 0; i < num_rmems; i++) {
rmem_np = of_parse_phandle(np, "memory-region", i + 1);
if (!rmem_np) {
ret = -EINVAL;
goto unmap_rmem;
}
rmem = of_reserved_mem_lookup(rmem_np);
if (!rmem) {
of_node_put(rmem_np);
ret = -EINVAL;
goto unmap_rmem;
}
of_node_put(rmem_np);
kproc->rmem[i].bus_addr = rmem->base;
/*
* R5Fs do not have an MMU, but have a Region Address Translator
* (RAT) module that provides a fixed entry translation between
* the 32-bit processor addresses to 64-bit bus addresses. The
* RAT is programmable only by the R5F cores. Support for RAT
* is currently not supported, so 64-bit address regions are not
* supported. The absence of MMUs implies that the R5F device
* addresses/supported memory regions are restricted to 32-bit
* bus addresses, and are identical
*/
kproc->rmem[i].dev_addr = (u32)rmem->base;
kproc->rmem[i].size = rmem->size;
kproc->rmem[i].cpu_addr = ioremap_wc(rmem->base, rmem->size);
if (!kproc->rmem[i].cpu_addr) {
dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",
i + 1, &rmem->base, &rmem->size);
ret = -ENOMEM;
goto unmap_rmem;
}
dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
i + 1, &kproc->rmem[i].bus_addr,
kproc->rmem[i].size, kproc->rmem[i].cpu_addr,
kproc->rmem[i].dev_addr);
}
kproc->num_rmems = num_rmems;
return 0;
unmap_rmem:
for (i--; i >= 0; i--)
iounmap(kproc->rmem[i].cpu_addr);
kfree(kproc->rmem);
release_rmem:
of_reserved_mem_device_release(dev);
return ret;
}