#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
{ "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
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@f0000/system-controller@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@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
-
static __maybe_unused void enable_mcu_esm_reset(void)
{
/* Set CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RST_EN_Z to '0' (low active) */
spl_enable_cache();
setup_qos();
- debug("am62px_init: %s done\n", __func__);
-
- fixup_a53_cpu_freq_by_speed_grade();
+ k3_fix_rproc_clock("/a53@0");
}
u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
#include <dm.h>
#include <dm/uclass-internal.h>
#include <dm/pinctrl.h>
-#include <dm/ofnode.h>
#include "../sysfw-loader.h"
#include "../common.h"
#define K3RTC_KICK0_UNLOCK_VALUE 0x83e70b13
#define K3RTC_KICK1_UNLOCK_VALUE 0x95a4f1e0
-/* TISCI DEV ID for A53 Clock */
-#define AM62X_DEV_A53SS0_CORE_0_DEV_ID 135
-
struct fwl_data rom_fwls[] = {
{ "SOC_DEVGRP_MAIN", 641, 1 },
{ "SOC_DEVGRP_MAIN", 642, 1 },
{ "SOC_DEVGRP_MAIN", 642, 2 },
};
+const struct k3_speed_grade_map am62x_map[] = {
+ {'G', 300000000},
+ {'K', 800000000},
+ {'S', 1000000000},
+ {'T', 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 am62x_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
writel(K3RTC_KICK1_UNLOCK_VALUE, REG_K3RTC_KICK1);
}
-#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@f0000/system-controller@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] == AM62X_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@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
-
void board_init_f(ulong dummy)
{
struct udevice *dev;
}
spl_enable_cache();
- fixup_a53_cpu_freq_by_speed_grade();
+ k3_fix_rproc_clock("/a53@0");
}
u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
}
#endif
+__weak char k3_get_speed_grade(void)
+{
+ return K3_SPEED_GRADE_UNKNOWN;
+}
+
+__weak const struct k3_speed_grade_map *k3_get_speed_grade_map(void)
+{
+ return NULL;
+}
+
+static int k3_fdt_set_assigned_clk_rate(const char *path, const char *clk_name,
+ unsigned int new_clk_rate)
+{
+ int size, clk_name_index, phandle_count;
+ struct ofnode_phandle_args phandle_args;
+ unsigned int dev_id, clock_id, i;
+ ofnode node = ofnode_path(path);
+ u32 *clk_rates;
+ int ret;
+
+ debug("%s: Setting clock '%s' frequency of '%s' to %u\n", __func__,
+ path, clk_name, new_clk_rate);
+
+ clk_name_index =
+ ofnode_stringlist_search(node, "clock-names", clk_name);
+ if (clk_name_index < 0)
+ return clk_name_index;
+
+ ret = ofnode_parse_phandle_with_args(node, "clocks", "#clock-cells", 0,
+ clk_name_index, &phandle_args);
+
+ if (ret || phandle_args.args_count != 2)
+ return -EINVAL;
+
+ dev_id = phandle_args.args[0];
+ clock_id = phandle_args.args[1];
+
+ debug("%s: Found dev_id: %u, clock_id: %u\n", __func__, dev_id,
+ clock_id);
+
+ phandle_count = ofnode_count_phandle_with_args(node, "assigned-clocks",
+ "#clock-cells", 0);
+
+ for (i = 0; i < phandle_count; i++) {
+ ret = ofnode_parse_phandle_with_args(node, "assigned-clocks",
+ "#clock-cells", 0, i,
+ &phandle_args);
+
+ if (ret || phandle_args.args_count != 2)
+ continue;
+
+ if (phandle_args.args[0] == dev_id &&
+ phandle_args.args[1] == clock_id) {
+ clk_rates = (u32 *)ofnode_read_prop(node,
+ "assigned-clock-rates", &size);
+
+ if (i >= (size / sizeof(u32)))
+ return -EOVERFLOW;
+
+ clk_rates[i] = cpu_to_fdt32(new_clk_rate);
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static u32 k3_get_a_core_frequency(char speed_grade)
+{
+ const struct k3_speed_grade_map *map = k3_get_speed_grade_map();
+ unsigned int i;
+
+ if (!map)
+ return 0;
+
+ for (i = 0; map[i].speed_grade != 0; i++) {
+ if (map[i].speed_grade == speed_grade)
+ return map[i].a_core_frequency;
+ }
+
+ return 0;
+}
+
+void k3_fix_rproc_clock(const char *path)
+{
+ u32 a_core_frequency;
+ char speed_grade;
+ int ret;
+
+ if (IS_ENABLED(CONFIG_ARM64))
+ return;
+
+ speed_grade = k3_get_speed_grade();
+ a_core_frequency = k3_get_a_core_frequency(speed_grade);
+
+ if (!a_core_frequency) {
+ printf("%s: Failed to get speed grade frequency\n", __func__);
+ return;
+ }
+
+ ret = k3_fdt_set_assigned_clk_rate(path, "core", a_core_frequency);
+ if (ret)
+ printf("Failed to set clock rates for '%s': %d\n", path, ret);
+ else
+ printf("Set clock rates for '%s', CPU: %dMHz at Speed Grade '%c'\n",
+ path, a_core_frequency / 1000000, speed_grade);
+}
+
void spl_enable_cache(void)
{
#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
/* keep ram_top in the 32-bit address space */
#define CFG_MAX_MEM_MAPPED 0x100000000
-#define K3_FIREWALL_BACKGROUND_BIT (8)
+#define K3_FIREWALL_BACKGROUND_BIT (8)
+#define K3_SPEED_GRADE_UNKNOWN '\0'
struct fwl_data {
const char *name;
u16 regions;
};
+struct k3_speed_grade_map {
+ char speed_grade;
+ u32 a_core_frequency;
+};
+
enum k3_firewall_region_type {
K3_FIREWALL_REGION_FOREGROUND,
K3_FIREWALL_REGION_BACKGROUND
void k3_sysfw_print_ver(void);
void k3_dm_print_ver(void);
void spl_enable_cache(void);
+char k3_get_speed_grade(void);
+const struct k3_speed_grade_map *k3_get_speed_grade_map(void);
+void k3_fix_rproc_clock(const char *path);
void mmr_unlock(uintptr_t base, u32 partition);
bool is_rom_loaded_sysfw(struct rom_extended_boot_data *data);
enum k3_device_type get_device_type(void);
return (full_devid & JTAG_DEV_CORE_NR_MASK) >> JTAG_DEV_CORE_NR_SHIFT;
}
-static inline char k3_get_speed_grade(void)
-{
- u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
- u32 speed_grade = (full_devid & JTAG_DEV_SPEED_MASK) >>
- JTAG_DEV_SPEED_SHIFT;
-
- return 'A' - 1 + speed_grade;
-}
-
static inline int k3_get_temp_grade(void)
{
u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
}
}
-static inline int k3_get_a53_max_frequency(void)
-{
- switch (k3_get_speed_grade()) {
- case 'K':
- return 800000000;
- case 'S':
- return 1000000000;
- case 'T':
- return 1250000000;
- case 'G':
- default:
- return 300000000;
- }
-}
-
static inline int k3_has_pru(void)
{
u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
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[] = {};