diff options
| -rw-r--r-- | arch/arm/mach-k3/am62px/am62p5_init.c | 87 | ||||
| -rw-r--r-- | arch/arm/mach-k3/am62x/am625_init.c | 84 | ||||
| -rw-r--r-- | arch/arm/mach-k3/common.c | 108 | ||||
| -rw-r--r-- | arch/arm/mach-k3/common.h | 11 | ||||
| -rw-r--r-- | arch/arm/mach-k3/include/mach/am62_hardware.h | 24 | ||||
| -rw-r--r-- | 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 aebd5200b0d..eeb054d575a 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@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) */ @@ -251,9 +214,7 @@ void board_init_f(ulong dummy) 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) diff --git a/arch/arm/mach-k3/am62x/am625_init.c b/arch/arm/mach-k3/am62x/am625_init.c index 14f93ac998f..9f7f2d8c084 100644 --- a/arch/arm/mach-k3/am62x/am625_init.c +++ b/arch/arm/mach-k3/am62x/am625_init.c @@ -12,7 +12,6 @@ #include <dm.h> #include <dm/uclass-internal.h> #include <dm/pinctrl.h> -#include <dm/ofnode.h> #include "../sysfw-loader.h" #include "../common.h" @@ -26,15 +25,34 @@ #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 @@ -123,62 +141,6 @@ static __maybe_unused void rtc_erratumi2327_init(void) 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; @@ -294,7 +256,7 @@ void board_init_f(ulong dummy) } 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) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 7c06764af82..3a97b70259e 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -304,6 +304,114 @@ void enable_caches(void) } #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)) diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h index 52d3faaab5c..6452188bd19 100644 --- a/arch/arm/mach-k3/common.h +++ b/arch/arm/mach-k3/common.h @@ -13,7 +13,8 @@ /* 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; @@ -21,6 +22,11 @@ struct fwl_data { 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 @@ -44,6 +50,9 @@ int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr); 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); diff --git a/arch/arm/mach-k3/include/mach/am62_hardware.h b/arch/arm/mach-k3/include/mach/am62_hardware.h index 2f5655bf24a..9b8fd6276f1 100644 --- a/arch/arm/mach-k3/include/mach/am62_hardware.h +++ b/arch/arm/mach-k3/include/mach/am62_hardware.h @@ -113,15 +113,6 @@ static inline int k3_get_core_nr(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); @@ -142,21 +133,6 @@ static inline int k3_get_max_temp(void) } } -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); diff --git a/arch/arm/mach-k3/include/mach/am62p_hardware.h b/arch/arm/mach-k3/include/mach/am62p_hardware.h index a310b52b45d..3c8fbb6b421 100644 --- a/arch/arm/mach-k3/include/mach/am62p_hardware.h +++ b/arch/arm/mach-k3/include/mach/am62p_hardware.h @@ -120,23 +120,6 @@ static inline int k3_get_max_temp(void) 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[] = {}; |
