summaryrefslogtreecommitdiffstats
path: root/drivers/clk/imx/clk-imx7.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/imx/clk-imx7.c')
-rw-r--r--drivers/clk/imx/clk-imx7.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/drivers/clk/imx/clk-imx7.c b/drivers/clk/imx/clk-imx7.c
index 781bc43e09..224471a982 100644
--- a/drivers/clk/imx/clk-imx7.c
+++ b/drivers/clk/imx/clk-imx7.c
@@ -1,24 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
*/
#include <common.h>
#include <init.h>
#include <driver.h>
+#include <deep-probe.h>
#include <linux/clk.h>
#include <io.h>
#include <of.h>
#include <linux/clkdev.h>
#include <linux/err.h>
-#include <mach/imx7-regs.h>
-#include <mach/revision.h>
+#include <mach/imx/imx7-regs.h>
+#include <mach/imx/revision.h>
#include <dt-bindings/clock/imx7d-clock.h>
#include "clk.h"
@@ -364,9 +359,11 @@ static int const clks_init_on[] __initconst = {
static struct clk_onecell_data clk_data;
-static int imx7_clk_initialized;
+static struct device_node *ccm_np;
-static int imx7_ccm_probe(struct device_d *dev)
+static int imx7_clk_setup(void);
+
+static int imx7_ccm_probe(struct device *dev)
{
struct resource *iores;
void __iomem *base, *anatop_base, *ccm_base;
@@ -728,10 +725,12 @@ static int imx7_ccm_probe(struct device_d *dev)
clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate4("ocram_s_clk", "ahb_post_div", base + 0x4120, 0);
clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_gate4("nand_usdhc_root_clk", "nand_usdhc_post_div", base + 0x4130, 0);
clks[IMX7D_AHB_CHANNEL_ROOT_CLK] = imx_clk_gate4("ahb_root_clk", "ahb_post_div", base + 0x4200, 0);
+ clks[IMX7D_IPG_ROOT_CLK] = imx_clk_divider_flags("ipg_root_clk", "ahb_root_clk", base + 0x9080, 0, 2, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_PARENT);
clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate4("dram_root_clk", "dram_post_div", base + 0x4130, 0);
clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
+ clks[IMX7D_OCOTP_CLK] = imx_clk_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0);
clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0);
clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
@@ -808,21 +807,37 @@ static int imx7_ccm_probe(struct device_d *dev)
clk_data.clks = clks;
clk_data.clk_num = ARRAY_SIZE(clks);
- of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data);
+ of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, &clk_data);
+
+ ccm_np = dev->of_node;
- imx7_clk_initialized = 1;
+ /*
+ * imx7_clk_setup() requires both the CCM and fixed-clock osc devices
+ * to be available.
+ * With deep probe enabled, we can instead just directly call
+ * imx7_clk_setup because the osc fixed-clock will just be probed
+ * on demand if not yet available. Otherwise, the imx7_clk_setup
+ * will run at postcore_initcall level.
+ */
+ if (deep_probe_is_supported())
+ return imx7_clk_setup();
return 0;
}
static int imx7_clk_setup(void)
{
+ struct clk *clk;
int i;
- if (!imx7_clk_initialized)
+ if (!ccm_np)
return 0;
- clks[IMX7D_OSC_24M_CLK] = clk_lookup("osc");
+ clk = of_clk_get_by_name(ccm_np, "osc");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ clks[IMX7D_OSC_24M_CLK] = clk;
for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
clk_enable(clks[clks_init_on[i]]);
@@ -844,6 +859,8 @@ static int imx7_clk_setup(void)
clk_set_rate(clks[IMX7D_ENET1_TIME_ROOT_CLK], 25000000);
clk_set_rate(clks[IMX7D_ENET2_TIME_ROOT_CLK], 25000000);
+ ccm_np = NULL;
+
return 0;
}
postcore_initcall(imx7_clk_setup);
@@ -855,15 +872,12 @@ static __maybe_unused struct of_device_id imx7_ccm_dt_ids[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, imx7_ccm_dt_ids);
-static struct driver_d imx7_ccm_driver = {
+static struct driver imx7_ccm_driver = {
.probe = imx7_ccm_probe,
.name = "imx6-ccm",
.of_compatible = DRV_OF_COMPAT(imx7_ccm_dt_ids),
};
-static int imx7_ccm_init(void)
-{
- return platform_driver_register(&imx7_ccm_driver);
-}
-core_initcall(imx7_ccm_init); \ No newline at end of file
+core_platform_driver(imx7_ccm_driver);