diff options
author | Suman Anna <s-anna@ti.com> | 2016-11-23 07:24:41 (GMT) |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-12-04 18:54:49 (GMT) |
commit | 1b42ab3eda8aa7b6eed029632c8b1858dcbe8b26 (patch) | |
tree | 8c5e6415359dd5dd250849e82530d2f3a0539251 /arch/arm/mach-omap2/omap5/fdt.c | |
parent | fba82eb7c9eea2fcf5fa05c45cbec26c3410f9f3 (diff) | |
download | u-boot-1b42ab3eda8aa7b6eed029632c8b1858dcbe8b26.tar.xz |
ARM: DRA7: Fixup DSPEVE, IVA and GPU clock frequencies based on OPP
This patch adds support to update the device-tree blob to adjust the
DSP and IVA DPLL clocks pertinent to the selected OPP choice, with
the default being OPP_NOM. The voltage settings are done in u-boot,
but the actual clock configuration itself is done in kernel because
of the following reasons:
1. SoC definition constraints us to NOT to do dynamic voltage
scaling ever after the initial avs0 setting in bootloader
- so the voltage must be set in bootloader.
2. The voltage level must be set even if the IP blocks like
GPU/DSP are unused.
3. The IVA, GPU and DSP DPLLs are not essential for u-boot functionality,
and similar DPLL clock configuration code has been cleaned up in
v2014.10 u-boot release. See commit, 02c41535b6a4 ("ARM: OMAP4/5:
Remove dead code against CONFIG_SYS_CLOCKS_ENABLE_ALL").
The non-essential DPLLs are configured within the kernel during
the clock init step when parsing the device tree and creating
the clock devices. This approach meets both the u-boot and kernel
needs.
Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Subhajit Paul <subhajit_paul@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap5/fdt.c')
-rw-r--r-- | arch/arm/mach-omap2/omap5/fdt.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap5/fdt.c b/arch/arm/mach-omap2/omap5/fdt.c index afa0037..900f001 100644 --- a/arch/arm/mach-omap2/omap5/fdt.c +++ b/arch/arm/mach-omap2/omap5/fdt.c @@ -266,6 +266,141 @@ static void ft_hs_fixups(void *fdt, bd_t *bd) } #endif /* #ifdef CONFIG_TI_SECURE_DEVICE */ +#if defined(CONFIG_TARGET_DRA7XX_EVM) || defined(CONFIG_TARGET_AM57XX_EVM) +#define OPP_DSP_CLK_NUM 3 +#define OPP_IVA_CLK_NUM 2 +#define OPP_GPU_CLK_NUM 2 + +const char *dra7_opp_dsp_clk_names[OPP_DSP_CLK_NUM] = { + "dpll_dsp_ck", + "dpll_dsp_m2_ck", + "dpll_dsp_m3x2_ck", +}; + +const char *dra7_opp_iva_clk_names[OPP_IVA_CLK_NUM] = { + "dpll_iva_ck", + "dpll_iva_m2_ck", +}; + +const char *dra7_opp_gpu_clk_names[OPP_GPU_CLK_NUM] = { + "dpll_gpu_ck", + "dpll_gpu_m2_ck", +}; + +/* DSPEVE voltage domain */ +u32 dra7_opp_dsp_clk_rates[NUM_OPPS][OPP_DSP_CLK_NUM] = { + {}, /*OPP_LOW */ + {600000000, 600000000, 400000000}, /* OPP_NOM */ + {700000000, 700000000, 466666667}, /* OPP_OD */ + {750000000, 750000000, 500000000}, /* OPP_HIGH */ +}; + +/* IVA voltage domain */ +u32 dra7_opp_iva_clk_rates[NUM_OPPS][OPP_IVA_CLK_NUM] = { + {}, /* OPP_LOW */ + {1165000000, 388333334}, /* OPP_NOM */ + {860000000, 430000000}, /* OPP_OD */ + {1064000000, 532000000}, /* OPP_HIGH */ +}; + +/* GPU voltage domain */ +u32 dra7_opp_gpu_clk_rates[NUM_OPPS][OPP_GPU_CLK_NUM] = { + {}, /* OPP_LOW */ + {1277000000, 425666667}, /* OPP_NOM */ + {1000000000, 500000000}, /* OPP_OD */ + {1064000000, 532000000}, /* OPP_HIGH */ +}; + +static int ft_fixup_clocks(void *fdt, const char **names, u32 *rates, int num) +{ + int offs, node_offs, ret, i; + uint32_t phandle; + + offs = fdt_path_offset(fdt, "/ocp/l4@4a000000/cm_core_aon@5000/clocks"); + if (offs < 0) { + debug("Could not find cm_core_aon clocks node path offset : %s\n", + fdt_strerror(offs)); + return offs; + } + + for (i = 0; i < num; i++) { + node_offs = fdt_subnode_offset(fdt, offs, names[i]); + if (node_offs < 0) { + debug("Could not find clock sub-node %s: %s\n", + names[i], fdt_strerror(node_offs)); + return offs; + } + + phandle = fdt_get_phandle(fdt, node_offs); + if (!phandle) { + debug("Could not find phandle for clock %s\n", + names[i]); + return -1; + } + + ret = fdt_setprop_u32(fdt, node_offs, "assigned-clocks", + phandle); + if (ret < 0) { + debug("Could not add assigned-clocks property to clock node %s: %s\n", + names[i], fdt_strerror(ret)); + return ret; + } + + ret = fdt_setprop_u32(fdt, node_offs, "assigned-clock-rates", + rates[i]); + if (ret < 0) { + debug("Could not add assigned-clock-rates property to clock node %s: %s\n", + names[i], fdt_strerror(ret)); + return ret; + } + } + + return 0; +} + +static void ft_opp_clock_fixups(void *fdt, bd_t *bd) +{ + const char **clk_names; + u32 *clk_rates; + int ret; + + if (!is_dra72x() && !is_dra7xx()) + return; + + /* fixup DSP clocks */ + clk_names = dra7_opp_dsp_clk_names; + clk_rates = dra7_opp_dsp_clk_rates[get_voltrail_opp(VOLT_EVE)]; + ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_DSP_CLK_NUM); + if (ret) { + printf("ft_fixup_clocks failed for DSP voltage domain: %s\n", + fdt_strerror(ret)); + return; + } + + /* fixup IVA clocks */ + clk_names = dra7_opp_iva_clk_names; + clk_rates = dra7_opp_iva_clk_rates[get_voltrail_opp(VOLT_IVA)]; + ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_IVA_CLK_NUM); + if (ret) { + printf("ft_fixup_clocks failed for IVA voltage domain: %s\n", + fdt_strerror(ret)); + return; + } + + /* fixup GPU clocks */ + clk_names = dra7_opp_gpu_clk_names; + clk_rates = dra7_opp_gpu_clk_rates[get_voltrail_opp(VOLT_GPU)]; + ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_GPU_CLK_NUM); + if (ret) { + printf("ft_fixup_clocks failed for GPU voltage domain: %s\n", + fdt_strerror(ret)); + return; + } +} +#else +static void ft_opp_clock_fixups(void *fdt, bd_t *bd) { } +#endif /* CONFIG_TARGET_DRA7XX_EVM || CONFIG_TARGET_AM57XX_EVM */ + /* * Place for general cpu/SoC FDT fixups. Board specific * fixups should remain in the board files which is where @@ -274,4 +409,5 @@ static void ft_hs_fixups(void *fdt, bd_t *bd) void ft_cpu_setup(void *fdt, bd_t *bd) { ft_hs_fixups(fdt, bd); + ft_opp_clock_fixups(fdt, bd); } |