[PATCH 2/3] mach-k3: refactor A53 speed grade clock-rate fixup
Aniket Limaye
a-limaye at ti.com
Mon Nov 3 07:05:26 CET 2025
Hi Anshul,
On 03/11/25 10:54, Anshul Dalal wrote:
> 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
Alright, makes sense.
Reviewed-by: Aniket Limaye <a-limaye at ti.com>
>
> Regards,
> Anshul
More information about the U-Boot
mailing list