[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