b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* |
| 3 | * Register ioremap for ASR SoC |
| 4 | * Copyright (C) 2019 ASR Micro Limited |
| 5 | */ |
| 6 | |
| 7 | #include <linux/init.h> |
| 8 | #include <linux/io.h> |
| 9 | #include <linux/of_platform.h> |
| 10 | #include <linux/of_address.h> |
| 11 | |
| 12 | #include <soc/asr/regs-addr.h> |
| 13 | |
| 14 | struct regs_addr { |
| 15 | void __iomem *va; |
| 16 | phys_addr_t pa; |
| 17 | }; |
| 18 | |
| 19 | static struct regs_addr all_regs_addr[REGS_ADDR_MAX]; |
| 20 | |
| 21 | struct of_device_id regs_addr_matches[] = { |
| 22 | { |
| 23 | .compatible = "marvell,mmp-pmu-mpmu", |
| 24 | .data = &all_regs_addr[REGS_ADDR_MPMU], |
| 25 | }, |
| 26 | { |
| 27 | .compatible = "marvell,mmp-pmu-apmu", |
| 28 | .data = &all_regs_addr[REGS_ADDR_APMU], |
| 29 | }, |
| 30 | { |
| 31 | .compatible = "marvell,mmp-pmu-apbc", |
| 32 | .data = &all_regs_addr[REGS_ADDR_APBC], |
| 33 | }, |
| 34 | { |
| 35 | .compatible = "marvell,mmp-apb-spare", |
| 36 | .data = &all_regs_addr[REGS_ADDR_APBS], |
| 37 | }, |
| 38 | { |
| 39 | .compatible = "marvell,mmp-ciu", |
| 40 | .data = &all_regs_addr[REGS_ADDR_CIU], |
| 41 | }, |
| 42 | { |
| 43 | .compatible = "marvell,mmp-squ", |
| 44 | .data = &all_regs_addr[REGS_ADDR_SQU], |
| 45 | }, |
| 46 | {}, |
| 47 | }; |
| 48 | |
| 49 | void regs_addr_iomap(void) |
| 50 | { |
| 51 | struct device_node *np; |
| 52 | struct regs_addr *cell; |
| 53 | const __be32 *tmp_addr; |
| 54 | |
| 55 | for_each_matching_node(np, regs_addr_matches) { |
| 56 | const struct of_device_id *match = |
| 57 | of_match_node(regs_addr_matches, np); |
| 58 | cell = (struct regs_addr *)match->data; |
| 59 | |
| 60 | tmp_addr = of_get_address(np, 0, NULL, NULL); |
| 61 | |
| 62 | if (tmp_addr) { |
| 63 | cell->pa = of_translate_address(np, tmp_addr); |
| 64 | cell->va = of_io_request_and_map(np, 0, |
| 65 | of_node_full_name(np)); |
| 66 | |
| 67 | if ((cell->pa == OF_BAD_ADDR) || IS_ERR(cell->va)) |
| 68 | pr_warn("%s: device %s invalid address\n", |
| 69 | __func__, match->compatible); |
| 70 | } else { |
| 71 | pr_err("%s: device %s fail to get reg address !\n", |
| 72 | __func__, match->compatible); |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | pr_info("regs address io map done\n"); |
| 77 | } |
| 78 | |
| 79 | phys_addr_t regs_addr_get_pa(unsigned int id) |
| 80 | { |
| 81 | phys_addr_t pa; |
| 82 | |
| 83 | if (id >= REGS_ADDR_MAX) |
| 84 | return 0; |
| 85 | |
| 86 | pa = all_regs_addr[id].pa; |
| 87 | BUG_ON(pa == 0); |
| 88 | |
| 89 | return pa; |
| 90 | } |
| 91 | EXPORT_SYMBOL_GPL(regs_addr_get_pa); |
| 92 | |
| 93 | void __iomem *regs_addr_get_va(unsigned int id) |
| 94 | { |
| 95 | static void __iomem *va; |
| 96 | |
| 97 | if (id >= REGS_ADDR_MAX) |
| 98 | return NULL; |
| 99 | |
| 100 | va = all_regs_addr[id].va; |
| 101 | |
| 102 | return va; |
| 103 | } |
| 104 | EXPORT_SYMBOL_GPL(regs_addr_get_va); |