From 1b42ab3eda8aa7b6eed029632c8b1858dcbe8b26 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 23 Nov 2016 12:54:41 +0530 Subject: [PATCH] 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 Signed-off-by: Subhajit Paul Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- arch/arm/mach-omap2/omap5/fdt.c | 136 ++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/arch/arm/mach-omap2/omap5/fdt.c b/arch/arm/mach-omap2/omap5/fdt.c index afa003774b..900f0010f6 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); } -- 2.25.1