summaryrefslogtreecommitdiff
path: root/drivers/clk/imx/clk-imx8mm.c
diff options
context:
space:
mode:
authorPeng Fan <peng.fan@nxp.com>2018-08-06 17:28:45 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:33:06 +0800
commit9e6aab30391588d9610bd585f262894444fd53b7 (patch)
tree2d84e0f17a5951545e33eb09b81b4591ab3720b3 /drivers/clk/imx/clk-imx8mm.c
parente7d20cd998f8a3c4ea056b41080aaad316547a0f (diff)
MLK-19130-2 clk: imx8mm: parse clk init on from device tree
Add a new init-on-array property, the clk driver will parse this array and prepare enable the related clocks. Previously, the clocks needs to be init on are hardcoded in SoC clk driver. When we need to support two OSes, some clks needs to be ini on, however such clocks does not need to be init on for Single Linux OS environment. At current stage using Jailhouse hypervisor supporting Two Linux OS, OS1 use SDHC2, OS2 use SDHC3, they share one IMX8MM_CLK_NAND_USDHC_BUS_CG, because no power management supported, so we need clk_ignore_unused and make sure this clk being enabled, to make sure the 2nd OS could has SDHC3 working. The i.MX8MQ also has same code, but there is no good place to hold it in common place, so duplicate it clk-imx8mm.c for now. Signed-off-by: Peng Fan <peng.fan@nxp.com> (cherry picked from commit 58d25fb00099142f15bcf2a66432b25da75ef38e)
Diffstat (limited to 'drivers/clk/imx/clk-imx8mm.c')
-rw-r--r--drivers/clk/imx/clk-imx8mm.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index d05e14e57e9a..a835ddb51adc 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -395,6 +395,32 @@ static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m",
static struct clk *clks[IMX8MM_CLK_END];
static struct clk_onecell_data clk_data;
+static int __init imx_clk_init_on(struct device_node *np,
+ struct clk * const clks[])
+{
+ u32 *array;
+ int i, ret, elems;
+
+ elems = of_property_count_u32_elems(np, "init-on-array");
+ if (elems < 0)
+ return elems;
+ array = kcalloc(elems, sizeof(elems), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(array))
+ return PTR_ERR(array);
+
+ ret = of_property_read_u32_array(np, "init-on-array", array, elems);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < elems; i++) {
+ ret = clk_prepare_enable(clks[array[i]]);
+ if (ret)
+ pr_err("clk_prepare_enable failed %d\n", array[i]);
+ }
+
+ return 0;
+}
+
static void __init imx8mm_clocks_init(struct device_node *ccm_node)
{
struct device_node *np;
@@ -917,8 +943,10 @@ static void __init imx8mm_clocks_init(struct device_node *ccm_node)
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
- for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
- clk_prepare_enable(clks[clks_init_on[i]]);
+ if (imx_clk_init_on(ccm_node, clks)) {
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_prepare_enable(clks[clks_init_on[i]]);
+ }
clk_set_parent(clks[IMX8MM_CLK_AUDIO_AHB_SRC], clks[IMX8MM_SYS_PLL1_800M]);