[PATCH 2/3] mach-k3: refactor A53 speed grade clock-rate fixup
Anshul Dalal
anshuld at ti.com
Mon Nov 3 06:24:43 CET 2025
Hi Aniket,
On Sat Nov 1, 2025 at 9:30 AM IST, Aniket Limaye wrote:
> On 30/10/25 18:33, Anshul Dalal wrote:
>> The K3 ARM64 rproc driver uses the "assigned-clock-rates" value in the
>> respective "/a53 at 0" node to properly configure the clocks for the A53
>> core.
>>
>> Although the clock value in the DT node might need to be fixed based on
>> SoC's speed grade at runtime. Certain SoCs such as AM62p and AM62x
>> already had this implemented, this patch moves the common code to
>> common.c to avoid duplication and simplify speed grade handling.
>>
>> The logic to detect the correct entry in the "assigned-clock-rates"
>> property has also changed. Where we earlier relied on per SoC specific
>> device and clock IDs for the A53 core, we now use the "clock-names"
>> property which is device agnostic.
>>
>> Signed-off-by: Anshul Dalal <anshuld at ti.com>
>> ---
>> arch/arm/mach-k3/am62px/am62p5_init.c | 87 ++++++--------------
>> arch/arm/mach-k3/am62x/am625_init.c | 84 ++++++-------------
>> arch/arm/mach-k3/common.c | 108 +++++++++++++++++++++++++
>> arch/arm/mach-k3/common.h | 11 ++-
>> arch/arm/mach-k3/include/mach/am62_hardware.h | 24 ------
>> arch/arm/mach-k3/include/mach/am62p_hardware.h | 17 ----
>> 6 files changed, 165 insertions(+), 166 deletions(-)
>>
>> diff --git a/arch/arm/mach-k3/am62px/am62p5_init.c b/arch/arm/mach-k3/am62px/am62p5_init.c
>> index aebd5200b0db9959805d04408b34d283e21b6e2c..eeb054d575ad94040370817f648c5319850fe7f8 100644
>> --- a/arch/arm/mach-k3/am62px/am62p5_init.c
>> +++ b/arch/arm/mach-k3/am62px/am62p5_init.c
>> @@ -11,14 +11,10 @@
>> #include <dm.h>
>> #include <dm/uclass-internal.h>
>> #include <dm/pinctrl.h>
>> -#include <dm/ofnode.h>
>>
>> #include "../sysfw-loader.h"
>> #include "../common.h"
>>
>> -/* TISCI DEV ID for A53 Clock */
>> -#define AM62PX_DEV_A53SS0_CORE_0_DEV_ID 135
>> -
>> #define CTRLMMR_MCU_RST_CTRL 0x04518170
>> #define RST_CTRL_ESM_ERROR_RST_EN_Z_MASK 0xFFFDFFFF
>>
>> @@ -26,6 +22,29 @@ struct fwl_data cbass_main_fwls[] = {
>> { "FSS_DAT_REG3", 7, 8 },
>> };
>>
>> +const struct k3_speed_grade_map am62p_map[] = {
>> + {'O', 1000000000},
>> + {'S', 1250000000},
>> + {'T', 1250000000},
>> + {'U', 1250000000},
>> + {'V', 1250000000},
>> + {/* List Terminator */ },
>> +};
>> +
>> +char k3_get_speed_grade(void)
>> +{
>> + u32 efuse_val = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
>> + u32 efuse_speed = (efuse_val & JTAG_DEV_SPEED_MASK) >>
>> + JTAG_DEV_SPEED_SHIFT;
>> +
>> + return ('A' - 1) + efuse_speed;
>> +}
>> +
>> +const struct k3_speed_grade_map *k3_get_speed_grade_map(void)
>> +{
>> + return am62p_map;
>> +}
>> +
>> /*
>> * This uninitialized global variable would normal end up in the .bss section,
>> * but the .bss is cleared between writing and reading this variable, so move
>> @@ -74,62 +93,6 @@ static void ctrl_mmr_unlock(void)
>> mmr_unlock(PADCFG_MMR1_BASE, 1);
>> }
>>
>> -#if CONFIG_IS_ENABLED(OF_CONTROL)
>> -static int get_a53_cpu_clock_index(ofnode node)
>> -{
>> - int count, i;
>> - struct ofnode_phandle_args *args;
>> - ofnode clknode;
>> -
>> - clknode = ofnode_path("/bus at f0000/system-controller at 44043000/clock-controller");
>> - if (!ofnode_valid(clknode))
>> - return -1;
>> -
>> - count = ofnode_count_phandle_with_args(node, "assigned-clocks", "#clock-cells", 0);
>> -
>> - for (i = 0; i < count; i++) {
>> - if (!ofnode_parse_phandle_with_args(node, "assigned-clocks",
>> - "#clock-cells", 0, i, args)) {
>> - if (ofnode_equal(clknode, args->node) &&
>> - args->args[0] == AM62PX_DEV_A53SS0_CORE_0_DEV_ID)
>> - return i;
>> - }
>> - }
>> -
>> - return -1;
>> -}
>> -
>> -static void fixup_a53_cpu_freq_by_speed_grade(void)
>> -{
>> - int index, size;
>> - u32 *rates;
>> - ofnode node;
>> -
>> - node = ofnode_path("/a53 at 0");
>> - if (!ofnode_valid(node))
>> - return;
>> -
>> - rates = fdt_getprop_w(ofnode_to_fdt(node), ofnode_to_offset(node),
>> - "assigned-clock-rates", &size);
>> -
>> - index = get_a53_cpu_clock_index(node);
>> -
>> - if (!rates || index < 0 || index >= (size / sizeof(u32))) {
>> - printf("Wrong A53 assigned-clocks configuration\n");
>> - return;
>> - }
>> -
>> - rates[index] = cpu_to_fdt32(k3_get_a53_max_frequency());
>> -
>> - printf("Changed A53 CPU frequency to %dHz (%c grade) in DT\n",
>> - k3_get_a53_max_frequency(), k3_get_speed_grade());
>> -}
>> -#else
>> -static void fixup_a53_cpu_freq_by_speed_grade(void)
>> -{
>> -}
>> -#endif
>
> The original function here was implemented behind #if
> CONFIG_IS_ENABLED(OF_CONTROL). (With an empty function in the else case)
>
> While the new common implementation does not have such the config check.
> Is this intentional?
>
>
Yes, this was intentional since there are currently no K3 platforms
without OF_CONTROL as per qconfig:
$ tools/qconfig.py -f CONFIG_ARCH_K3 '~CONFIG_SPL_OF_CONTROL'
0 matches
Regards,
Anshul
More information about the U-Boot
mailing list