summaryrefslogtreecommitdiff
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
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)
-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]);