blob: f81e57bfd40a45dfe51dbd80345d3f5ee83ce3f5 [file] [log] [blame]
// 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);