| // SPDX-License-Identifier: GPL-2.0 |
| /* Copyright (C) 2018 Synaptics Incorporated */ |
| |
| #include <linux/module.h> |
| #include <linux/kernel.h> |
| #include <linux/of.h> |
| #include <linux/io.h> |
| #include <linux/printk.h> |
| #include <linux/of_address.h> |
| |
| unsigned char gDhub_EnableTEE __read_mostly; |
| static void *vir_addr; |
| static unsigned long base_addr; |
| static unsigned long reg_size; |
| |
| void *berlin_memmap_phy_to_vir(unsigned int phyaddr) |
| { |
| if (vir_addr && |
| (phyaddr >= base_addr) && |
| (phyaddr < |
| (base_addr + |
| reg_size))) { |
| return (phyaddr - base_addr + |
| vir_addr); |
| } |
| pr_err("Fail to map phyaddr: 0x%x, Base vir: %p!\n", phyaddr, |
| vir_addr); |
| |
| return 0; |
| } |
| EXPORT_SYMBOL(berlin_memmap_phy_to_vir); |
| |
| unsigned int berlin_memmap_vir_to_phy(void *v_addr) |
| { |
| if (vir_addr && |
| (v_addr >= vir_addr) && |
| (v_addr < vir_addr + reg_size)) { |
| return (v_addr - vir_addr + |
| base_addr); |
| } |
| |
| return 0; |
| } |
| EXPORT_SYMBOL(berlin_memmap_vir_to_phy); |
| |
| static int __init mrvl_dhub_init(void) |
| { |
| struct device_node *np, *iter; |
| struct resource res; |
| |
| np = of_find_compatible_node(NULL, NULL, "marvell,berlin-avio"); |
| |
| for_each_child_of_node(np, iter) { |
| if (of_device_is_compatible(iter, "marvell,berlin-tee")) { |
| if (of_device_is_available(iter)) |
| gDhub_EnableTEE = 1; |
| } |
| } |
| |
| if (of_address_to_resource(np, 0, &res)) |
| return -EINVAL; |
| base_addr = res.start; |
| reg_size = resource_size(&res); |
| |
| vir_addr = ioremap(base_addr, reg_size); |
| |
| if (!vir_addr) { |
| pr_err("Failed to map address before it is used!\n"); |
| return -1; |
| } |
| pr_err("ioremap success: vir_addr: 0x%p, size: 0x%lx, phy_addr: %p!\n", |
| vir_addr, reg_size, |
| (void *)base_addr); |
| |
| of_node_put(np); |
| |
| return 0; |
| } |
| subsys_initcall(mrvl_dhub_init); |
| |
| MODULE_LICENSE("GPL"); |