Merge patch series "Improve Verdin AM62P thermal setup by generalizing ft_board_setup_ex()"

João Paulo Gonçalves <jpaulo.silvagoncalves@gmail.com> says:

In some use cases, board-specific device tree changes must not be overwritten
by system fixups. Although U-Boot provides ft_board_setup_ex() for this
purpose, it is currently only used on TI Keystone. This series makes
ft_board_setup_ex() a generic option, allowing its use by other architectures
and boards.

Additionally, considering that Toradex Verdin-AM62P hardware lifetime
guarantees are based on a 105°C junction temperature (while TI AM62Px supports
up to 125°C), this series implements necessary changes within TI K3 AM62P and
Toradex board code. These changes include exporting common fixup device Tree
functions used in TI K3 for board-code access and also fixup for AM62P thermal
zones to correctly reflect the number of CPU nodes according to the SoC part
number.

Link: https://lore.kernel.org/r/20250623-am62p-fdt-fixup-trip-points-v1-0-12355eb6a72f@toradex.com
This commit is contained in:
Tom Rini
2025-07-09 08:40:36 -06:00
17 changed files with 134 additions and 114 deletions
+1
View File
@@ -822,6 +822,7 @@ config ARCH_KEYSTONE
imply CMD_SAVES
imply DM_I2C
imply FIT
imply OF_BOARD_SETUP_EXTENDED
imply SOC_TI
imply TI_KEYSTONE_SERDES
+1 -2
View File
@@ -3,11 +3,10 @@
* Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <asm/arch/k3-common-fdt.h>
#include <asm/hardware.h>
#include <fdt_support.h>
#include "../common_fdt.h"
int ft_system_setup(void *blob, struct bd_info *bd)
{
fdt_fixup_reserved(blob, "tfa", CONFIG_K3_ATF_LOAD_ADDR, 0x80000);
+39 -38
View File
@@ -3,9 +3,10 @@
* Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <asm/arch/k3-common-fdt.h>
#include <asm/hardware.h>
#include "../common_fdt.h"
#include <fdt_support.h>
#include <fdtdec.h>
static void fdt_fixup_cores_wdt_nodes_am62p(void *blob, int core_nr)
{
@@ -38,42 +39,6 @@ static void fdt_fixup_canfd_nodes_am62p(void *blob, bool has_canfd)
}
}
static int fdt_fixup_trips_node(void *blob, int zoneoffset, int maxc)
{
int node, trip;
node = fdt_subnode_offset(blob, zoneoffset, "trips");
if (node < 0)
return -1;
fdt_for_each_subnode(trip, blob, node) {
const char *type = fdt_getprop(blob, trip, "type", NULL);
if (!type || (strncmp(type, "critical", 8) != 0))
continue;
if (fdt_setprop_u32(blob, trip, "temperature", 1000 * maxc) < 0)
return -1;
}
return 0;
}
static void fdt_fixup_thermal_zone_nodes_am62p(void *blob, int maxc)
{
int node, zone;
node = fdt_path_offset(blob, "/thermal-zones");
if (node < 0)
return;
fdt_for_each_subnode(zone, blob, node) {
if (fdt_fixup_trips_node(blob, zone, maxc) < 0)
printf("Failed to set temperature in %s critical trips\n",
fdt_get_name(blob, zone, NULL));
}
}
static void fdt_fixup_cpu_freq_nodes_am62p(void *blob, int max_freq)
{
if (max_freq >= 1250000000)
@@ -85,12 +50,48 @@ static void fdt_fixup_cpu_freq_nodes_am62p(void *blob, int max_freq)
}
}
static void fdt_fixup_thermal_cooling_device_cpus_am62p(void *blob, int core_nr)
{
static const char * const thermal_path[] = {
"/thermal-zones/main0-thermal/cooling-maps/map0",
"/thermal-zones/main1-thermal/cooling-maps/map0",
"/thermal-zones/main2-thermal/cooling-maps/map0"
};
int node, cnt, i, ret;
u32 cooling_dev[12];
for (i = 0; i < ARRAY_SIZE(thermal_path); i++) {
int new_count = core_nr * 3; /* Each CPU has 3 entries */
int j;
node = fdt_path_offset(blob, thermal_path[i]);
if (node < 0)
continue;
cnt = fdtdec_get_int_array_count(blob, node, "cooling-device",
cooling_dev, ARRAY_SIZE(cooling_dev));
if (cnt < 0)
continue;
for (j = 0; j < new_count; j++)
cooling_dev[j] = cpu_to_fdt32(cooling_dev[j]);
ret = fdt_setprop(blob, node, "cooling-device", cooling_dev,
new_count * sizeof(u32));
if (ret < 0)
printf("Error %s, cooling-device setprop failed %d\n",
thermal_path[i], ret);
}
}
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_thermal_critical_trips_k3(blob, k3_get_max_temp());
fdt_fixup_thermal_cooling_device_cpus_am62p(blob, k3_get_core_nr());
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);
+2 -39
View File
@@ -3,12 +3,11 @@
* Copyright 2023 Toradex - https://www.toradex.com/
*/
#include <asm/arch/k3-common-fdt.h>
#include <asm/hardware.h>
#include <fdt_support.h>
#include <fdtdec.h>
#include "../common_fdt.h"
static void fdt_fixup_cores_nodes_am625(void *blob, int core_nr)
{
char node_path[32];
@@ -40,42 +39,6 @@ static void fdt_fixup_pru_node_am625(void *blob, int has_pru)
fdt_del_node_path(blob, "/bus@f0000/pruss@30040000");
}
static int fdt_fixup_trips_node(void *blob, int zoneoffset, int maxc)
{
int node, trip;
node = fdt_subnode_offset(blob, zoneoffset, "trips");
if (node < 0)
return -1;
fdt_for_each_subnode(trip, blob, node) {
const char *type = fdt_getprop(blob, trip, "type", NULL);
if (!type || (strncmp(type, "critical", 8) != 0))
continue;
if (fdt_setprop_u32(blob, trip, "temperature", 1000 * maxc) < 0)
return -1;
}
return 0;
}
static void fdt_fixup_thermal_zone_nodes_am625(void *blob, int maxc)
{
int node, zone;
node = fdt_path_offset(blob, "/thermal-zones");
if (node < 0)
return;
fdt_for_each_subnode(zone, blob, node) {
if (fdt_fixup_trips_node(blob, zone, maxc) < 0)
printf("Failed to set temperature in %s critical trips\n",
fdt_get_name(blob, zone, NULL));
}
}
static void fdt_fixup_thermal_cooling_device_cpus_am625(void *blob, int core_nr)
{
static const char * const thermal_path[] = {
@@ -115,7 +78,7 @@ int ft_system_setup(void *blob, struct bd_info *bd)
fdt_fixup_cores_nodes_am625(blob, k3_get_core_nr());
fdt_fixup_gpu_nodes_am625(blob, k3_has_gpu());
fdt_fixup_pru_node_am625(blob, k3_has_pru());
fdt_fixup_thermal_zone_nodes_am625(blob, k3_get_max_temp());
fdt_fixup_thermal_critical_trips_k3(blob, k3_get_max_temp());
fdt_fixup_thermal_cooling_device_cpus_am625(blob, k3_get_core_nr());
fdt_fixup_reserved(blob, "tfa", CONFIG_K3_ATF_LOAD_ADDR, 0x80000);
fdt_fixup_reserved(blob, "optee", CONFIG_K3_OPTEE_LOAD_ADDR, 0x1800000);
+1 -2
View File
@@ -3,10 +3,9 @@
* Copyright 2023 Toradex - https://www.toradex.com/
*/
#include <asm/arch/k3-common-fdt.h>
#include <fdt_support.h>
#include "../common_fdt.h"
int ft_system_setup(void *blob, struct bd_info *bd)
{
return fdt_fixup_msmc_ram_k3(blob);
+37 -1
View File
@@ -3,11 +3,11 @@
* Copyright 2023 Toradex - https://www.toradex.com/
*/
#include <asm/arch/k3-common-fdt.h>
#include "common.h"
#include <dm.h>
#include <fdt_support.h>
#include <linux/soc/ti/ti_sci_protocol.h>
#include "common_fdt.h"
static int fdt_fixup_msmc_ram(void *blob, char *parent_path, char *node_name)
{
@@ -164,3 +164,39 @@ add_carveout:
return 0;
}
static int fdt_fixup_critical_trips(void *blob, int zoneoffset, int maxc)
{
int node, trip;
node = fdt_subnode_offset(blob, zoneoffset, "trips");
if (node < 0)
return -1;
fdt_for_each_subnode(trip, blob, node) {
const char *type = fdt_getprop(blob, trip, "type", NULL);
if (!type || (strncmp(type, "critical", 8) != 0))
continue;
if (fdt_setprop_u32(blob, trip, "temperature", 1000 * maxc) < 0)
return -1;
}
return 0;
}
void fdt_fixup_thermal_critical_trips_k3(void *blob, int maxc)
{
int node, zone;
node = fdt_path_offset(blob, "/thermal-zones");
if (node < 0)
return;
fdt_for_each_subnode(zone, blob, node) {
if (fdt_fixup_critical_trips(blob, zone, maxc) < 0)
printf("Failed to set temperature in %s critical trips\n",
fdt_get_name(blob, zone, NULL));
}
}
@@ -3,12 +3,13 @@
* Copyright 2023 Toradex - https://www.toradex.com/
*/
#ifndef _COMMON_FDT_H
#define _COMMON_FDT_H
#ifndef _K3_COMMON_FDT_H
#define _K3_COMMON_FDT_H
int fdt_fixup_msmc_ram_k3(void *blob);
int fdt_del_node_path(void *blob, const char *path);
int fdt_fixup_reserved(void *blob, const char *name,
unsigned int new_address, unsigned int new_size);
void fdt_fixup_thermal_critical_trips_k3(void *blob, int maxc);
#endif /* _COMMON_FDT_H */
#endif /* _K3_COMMON_FDT_H */
+1 -2
View File
@@ -3,10 +3,9 @@
* Copyright 2023 Toradex - https://www.toradex.com/
*/
#include <asm/arch/k3-common-fdt.h>
#include <fdt_support.h>
#include "../common_fdt.h"
int ft_system_setup(void *blob, struct bd_info *bd)
{
return fdt_fixup_msmc_ram_k3(blob);
+1 -2
View File
@@ -3,10 +3,9 @@
* Copyright 2023 Toradex - https://www.toradex.com/
*/
#include <asm/arch/k3-common-fdt.h>
#include <fdt_support.h>
#include "../common_fdt.h"
int ft_system_setup(void *blob, struct bd_info *bd)
{
return fdt_fixup_msmc_ram_k3(blob);
+1 -1
View File
@@ -3,8 +3,8 @@
* Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <asm/arch/k3-common-fdt.h>
#include <asm/hardware.h>
#include "../common_fdt.h"
#include <fdt_support.h>
int ft_system_setup(void *blob, struct bd_info *bd)
+1 -2
View File
@@ -6,10 +6,9 @@
* Apurva Nandan <a-nandan@ti.com>
*/
#include <asm/arch/k3-common-fdt.h>
#include <fdt_support.h>
#include "../common_fdt.h"
int ft_system_setup(void *blob, struct bd_info *bd)
{
return fdt_fixup_msmc_ram_k3(blob);
@@ -8,6 +8,7 @@
#include <config.h>
#include <asm/arch/hardware.h>
#include <asm/arch/k3-common-fdt.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <dm/uclass.h>
@@ -97,6 +98,13 @@ int ft_board_setup(void *blob, struct bd_info *bd)
}
#endif
#if IS_ENABLED(CONFIG_OF_BOARD_SETUP_EXTENDED)
void ft_board_setup_ex(void *blob, struct bd_info *bd)
{
fdt_fixup_thermal_critical_trips_k3(blob, 105);
}
#endif
static void select_dt_from_module_version(void)
{
char variant[32];
+10
View File
@@ -1850,6 +1850,16 @@ config OF_BOARD_SETUP
board-specific information in the device tree for use by the OS.
The device tree is then passed to the OS.
config OF_BOARD_SETUP_EXTENDED
bool "Set up latest board-specific details in device tree before boot"
imply OF_BOARD_SETUP
help
This causes U-Boot to call ft_board_setup_ex() before booting into
the Operating System. Similar function as ft_board_setup(). However,
its modifications are not overwritten by other system changes and are
applied to the device tree as the very last step before boot.
The device tree is then passed to the OS.
config OF_SYSTEM_SETUP
bool "Set up system-specific details in device tree before boot"
help
+13 -14
View File
@@ -587,6 +587,7 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb)
{
ulong *initrd_start = &images->initrd_start;
ulong *initrd_end = &images->initrd_end;
bool skip_board_fixup = false;
int ret, fdt_ret, of_size;
if (IS_ENABLED(CONFIG_OF_ENV_SETUP)) {
@@ -637,18 +638,18 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb)
fdt_fixup_pstore(blob);
#endif
if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) {
const char *skip_board_fixup;
skip_board_fixup = (env_get_ulong("skip_board_fixup", 10, 0) == 1);
skip_board_fixup = env_get("skip_board_fixup");
if (skip_board_fixup && ((int)simple_strtol(skip_board_fixup, NULL, 10) == 1)) {
printf("skip board fdt fixup\n");
} else {
fdt_ret = ft_board_setup(blob, gd->bd);
if (fdt_ret) {
printf("ERROR: board-specific fdt fixup failed: %s\n",
fdt_strerror(fdt_ret));
goto err;
}
if (skip_board_fixup)
printf("skip all board fdt fixup\n");
}
if (IS_ENABLED(CONFIG_OF_BOARD_SETUP) && !skip_board_fixup) {
fdt_ret = ft_board_setup(blob, gd->bd);
if (fdt_ret) {
printf("ERROR: board-specific fdt fixup failed: %s\n",
fdt_strerror(fdt_ret));
goto err;
}
}
if (IS_ENABLED(CONFIG_OF_SYSTEM_SETUP)) {
@@ -710,10 +711,8 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb)
}
}
#if defined(CONFIG_ARCH_KEYSTONE)
if (IS_ENABLED(CONFIG_OF_BOARD_SETUP))
if (IS_ENABLED(CONFIG_OF_BOARD_SETUP_EXTENDED) && !skip_board_fixup)
ft_board_setup_ex(blob, gd->bd);
#endif
return 0;
err:
+3 -3
View File
@@ -691,9 +691,9 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
fdt_strerror(err));
return CMD_RET_FAILURE;
}
#ifdef CONFIG_ARCH_KEYSTONE
ft_board_setup_ex(working_fdt, gd->bd);
#endif
if (IS_ENABLED(CONFIG_OF_BOARD_SETUP_EXTENDED))
ft_board_setup_ex(working_fdt, gd->bd);
}
#endif
/* Create a chosen node */
+1
View File
@@ -35,6 +35,7 @@ CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000
CONFIG_BOOTSTD_FULL=y
CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_BOOTDELAY=1
CONFIG_OF_BOARD_SETUP_EXTENDED=y
CONFIG_BOOTCOMMAND="bootflow scan -b"
CONFIG_USE_PREBOOT=y
CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile k3-am62p5-verdin-${variant}-${fdt_board}.dtb"
+10 -5
View File
@@ -240,11 +240,16 @@ int board_rng_seed(struct abuf *buf);
*/
const char *board_fdt_chosen_bootargs(const struct fdt_property *fdt_ba);
/*
* The keystone2 SOC requires all 32 bit aliased addresses to be converted
* to their 36 physical format. This has to happen after all fdt nodes
* are added or modified by the image_setup_libfdt(). The ft_board_setup_ex()
* called at the end of the image_setup_libfdt() is to do that convertion.
/**
* ft_board_setup_ex() - Latest board-specific FDT changes
*
* @blob: FDT blob to update
* @bd: Pointer to board data
*
* Execute board-specific device tree modifications that must be the latest FDT
* changes and cannot be overwritten by other system fixups.
*
* This function is called if CONFIG_OF_BOARD_SETUP_EXTENDED is defined.
*/
void ft_board_setup_ex(void *blob, struct bd_info *bd);