AM62P SoC has multiple speed grades. Add function to delete
non-relevant CPU frequency nodes, based on the information
retrieved from hardware registers. Fastest grade's maximum
frequency also depends on PMIC voltage, hence to simplify
implementation use the smaller value.

Signed-off-by: Aparna Patra <a-pa...@ti.com>
---
 arch/arm/mach-k3/am62px/am62p5_fdt.c          | 12 ++++++++++++
 .../arm/mach-k3/include/mach/am62p_hardware.h | 19 +++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/arch/arm/mach-k3/am62px/am62p5_fdt.c 
b/arch/arm/mach-k3/am62px/am62p5_fdt.c
index 96194cebcd..2c40fa5a59 100644
--- a/arch/arm/mach-k3/am62px/am62p5_fdt.c
+++ b/arch/arm/mach-k3/am62px/am62p5_fdt.c
@@ -74,12 +74,24 @@ static void fdt_fixup_thermal_zone_nodes_am62p(void *blob, 
int maxc)
        }
 }
 
+static void fdt_fixup_cpu_freq_nodes_am62p(void *blob, int max_freq)
+{
+       if (max_freq >= 1250000000)
+               return;
+
+       if (max_freq <= 1000000000) {
+               fdt_del_node_path(blob, "/opp-table/opp-1250000000");
+               fdt_del_node_path(blob, "/opp-table/opp-1400000000");
+       }
+}
+
 int ft_system_setup(void *blob, struct bd_info *bd)
 {
        fdt_fixup_cores_wdt_nodes_am62p(blob, k3_get_core_nr());
        fdt_fixup_video_codec_nodes_am62p(blob, k3_has_video_codec());
        fdt_fixup_canfd_nodes_am62p(blob, k3_has_canfd());
        fdt_fixup_thermal_zone_nodes_am62p(blob, k3_get_max_temp());
+       fdt_fixup_cpu_freq_nodes_am62p(blob, k3_get_a53_max_frequency());
        fdt_fixup_reserved(blob, "tfa", CONFIG_K3_ATF_LOAD_ADDR, 0x80000);
        fdt_fixup_reserved(blob, "optee", CONFIG_K3_OPTEE_LOAD_ADDR, 0x1800000);
 
diff --git a/arch/arm/mach-k3/include/mach/am62p_hardware.h 
b/arch/arm/mach-k3/include/mach/am62p_hardware.h
index 2f1c8517e6..95af5c5c54 100644
--- a/arch/arm/mach-k3/include/mach/am62p_hardware.h
+++ b/arch/arm/mach-k3/include/mach/am62p_hardware.h
@@ -26,6 +26,8 @@
 #define JTAG_DEV_CANFD_SHIFT                   15
 #define JTAG_DEV_VIDEO_CODEC_MASK                      BIT(14)
 #define JTAG_DEV_VIDEO_CODEC_SHIFT                     14
+#define JTAG_DEV_SPEED_MASK                    GENMASK(10, 6)
+#define JTAG_DEV_SPEED_SHIFT                   6
 #define JTAG_DEV_TEMP_MASK                     GENMASK(5, 3)
 #define JTAG_DEV_TEMP_SHIFT                    3
 
@@ -118,6 +120,23 @@ static inline int k3_get_max_temp(void)
                return JTAG_DEV_TEMP_EXTENDED_VALUE;
 }
 
+static inline char k3_get_speed_grade(void)
+{
+       u32 dev_id = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
+       u32 speed_grade = (dev_id & JTAG_DEV_SPEED_MASK) >>
+                          JTAG_DEV_SPEED_SHIFT;
+
+       return 'A' - 1 + speed_grade;
+}
+
+static inline int k3_get_a53_max_frequency(void)
+{
+       if (k3_get_speed_grade() == 'O')
+               return 1000000000;
+       else
+               return 1250000000;
+}
+
 #if defined(CONFIG_SYS_K3_SPL_ATF) && !defined(__ASSEMBLY__)
 
 static const u32 put_device_ids[] = {};
-- 
2.34.1

Reply via email to