Add a small helper that reads the LPM meta data address from the
devicetree. The wkup R5F node references its firmware memory regions
through memory-region/memory-region-names; the region named
"lpm-metadata" is the one holding the LPM meta data.

This replaces deriving the address from a hardcoded offset into the
former single wkup R5F memory region.

The helper returns a negative errno if the memory-region-names property
is absent, if no region is named "lpm-metadata", if the phandle cannot be
parsed at the resulting index or if the region node has no reg property.

Signed-off-by: Markus Schneider-Pargmann (TI) <[email protected]>
---
 arch/arm/mach-k3/am62xx-lpm-common.c | 49 ++++++++++++++++++++++++++++++++++++
 arch/arm/mach-k3/am62xx-lpm-common.h |  1 +
 2 files changed, 50 insertions(+)

diff --git a/arch/arm/mach-k3/am62xx-lpm-common.c 
b/arch/arm/mach-k3/am62xx-lpm-common.c
index 009d05db4357..a39592ce57b7 100644
--- a/arch/arm/mach-k3/am62xx-lpm-common.c
+++ b/arch/arm/mach-k3/am62xx-lpm-common.c
@@ -9,6 +9,8 @@
 #include <config.h>
 #include <asm/arch/hardware.h>
 #include <asm/io.h>
+#include <dm/of_access.h>
+#include <dm/ofnode.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
 #include <linux/stddef.h>
 #include <vsprintf.h>
@@ -127,6 +129,49 @@ int __maybe_unused 
wkup_ctrl_remove_can_io_isolation_if_set(void)
 }
 
 #if IS_ENABLED(CONFIG_K3_IODDR)
+int wkup_r5f_am62_lpm_meta_data_addr(u64 *meta_data_addr)
+{
+       struct ofnode_phandle_args memregion_phandle;
+       ofnode memregion;
+       ofnode wkup_bus;
+       int index;
+       int ret;
+
+       wkup_bus = ofnode_path("/bus@f0000/bus@b00000");
+       if (!ofnode_valid(wkup_bus)) {
+               printf("Failed to find wkup bus\n");
+               return -EINVAL;
+       }
+
+       memregion = ofnode_by_compatible(wkup_bus, "ti,am62-r5f");
+       if (!ofnode_valid(memregion)) {
+               printf("Failed to find r5f devicetree node ti,am62-r5f\n");
+               return -EINVAL;
+       }
+
+       index = ofnode_stringlist_search(memregion, "memory-region-names",
+                                        "lpm-metadata");
+       if (index < 0) {
+               printf("Failed to find lpm-metadata memory region name\n");
+               return index;
+       }
+
+       ret = ofnode_parse_phandle_with_args(memregion, "memory-region", NULL,
+                                            0, index, &memregion_phandle);
+       if (ret) {
+               printf("Failed to parse phandle for lpm-metadata memory 
region\n");
+               return ret;
+       }
+
+       ret = ofnode_read_u64_index(memregion_phandle.node, "reg", 0, 
meta_data_addr);
+       if (ret) {
+               printf("Failed to read lpm-metadata memory region\n");
+               return ret;
+       }
+
+       return 0;
+}
+
 /*
  * Restore TIFS context for LPM resume.
  * @ctx_addr: DDR address pointing to the location containing the actual
@@ -183,6 +228,10 @@ void __noreturn lpm_resume_from_ddr(u64 meta_data_addr)
        image_entry();
 }
 #else
+int wkup_r5f_am62_lpm_meta_data_addr(u64 *meta_data_addr)
+{
+       return -EINVAL;
+}
 
 void __noreturn lpm_resume_from_ddr(u64 meta_data_addr)
 {
diff --git a/arch/arm/mach-k3/am62xx-lpm-common.h 
b/arch/arm/mach-k3/am62xx-lpm-common.h
index d5793759da4a..741e3ccbcbd0 100644
--- a/arch/arm/mach-k3/am62xx-lpm-common.h
+++ b/arch/arm/mach-k3/am62xx-lpm-common.h
@@ -13,6 +13,7 @@
 
 bool wkup_ctrl_is_lpm_exit(void);
 int wkup_ctrl_remove_can_io_isolation_if_set(void);
+int wkup_r5f_am62_lpm_meta_data_addr(u64 *meta_data_addr);
 void lpm_resume_from_ddr(u64 meta_data_addr);
 
 #endif  /* _AM62XX_LPM_COMMON_H_ */

-- 
2.55.0

Reply via email to