ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/linux/drivers/soc/asr/regs-addr.c b/marvell/linux/drivers/soc/asr/regs-addr.c
new file mode 100644
index 0000000..f81e57b
--- /dev/null
+++ b/marvell/linux/drivers/soc/asr/regs-addr.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Register ioremap for ASR SoC
+ * Copyright (C) 2019 ASR Micro Limited
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+
+#include <soc/asr/regs-addr.h>
+
+struct regs_addr {
+	void __iomem *va;
+	phys_addr_t pa;
+};
+
+static struct regs_addr all_regs_addr[REGS_ADDR_MAX];
+
+struct of_device_id regs_addr_matches[] = {
+	{
+		.compatible = "marvell,mmp-pmu-mpmu",
+		.data = &all_regs_addr[REGS_ADDR_MPMU],
+	},
+	{
+		.compatible = "marvell,mmp-pmu-apmu",
+		.data = &all_regs_addr[REGS_ADDR_APMU],
+	},
+	{
+		.compatible = "marvell,mmp-pmu-apbc",
+		.data = &all_regs_addr[REGS_ADDR_APBC],
+	},
+	{
+		.compatible = "marvell,mmp-apb-spare",
+		.data = &all_regs_addr[REGS_ADDR_APBS],
+	},
+	{
+		.compatible = "marvell,mmp-ciu",
+		.data = &all_regs_addr[REGS_ADDR_CIU],
+	},
+	{
+		.compatible = "marvell,mmp-squ",
+		.data = &all_regs_addr[REGS_ADDR_SQU],
+	},
+	{},
+};
+
+void regs_addr_iomap(void)
+{
+	struct device_node *np;
+	struct regs_addr *cell;
+	const __be32 *tmp_addr;
+
+	for_each_matching_node(np, regs_addr_matches) {
+		const struct of_device_id *match =
+				of_match_node(regs_addr_matches, np);
+		cell = (struct regs_addr *)match->data;
+
+		tmp_addr = of_get_address(np, 0, NULL, NULL);
+
+		if (tmp_addr) {
+			cell->pa = of_translate_address(np, tmp_addr);
+			cell->va = of_io_request_and_map(np, 0,
+							of_node_full_name(np));
+
+			if ((cell->pa == OF_BAD_ADDR) || IS_ERR(cell->va))
+				pr_warn("%s: device %s invalid address\n",
+					__func__, match->compatible);
+		} else {
+			pr_err("%s: device %s fail to get reg address !\n",
+					__func__, match->compatible);
+		}
+	}
+
+	pr_info("regs address io map done\n");
+}
+
+phys_addr_t regs_addr_get_pa(unsigned int id)
+{
+	phys_addr_t pa;
+
+	if (id >= REGS_ADDR_MAX)
+		return 0;
+
+	pa = all_regs_addr[id].pa;
+	BUG_ON(pa == 0);
+
+	return pa;
+}
+EXPORT_SYMBOL_GPL(regs_addr_get_pa);
+
+void __iomem *regs_addr_get_va(unsigned int id)
+{
+	static void __iomem *va;
+
+	if (id >= REGS_ADDR_MAX)
+		return NULL;
+
+	va = all_regs_addr[id].va;
+
+	return va;
+}
+EXPORT_SYMBOL_GPL(regs_addr_get_va);