diff options
Diffstat (limited to 'drivers/clk/imx/clk-imx7.c')
-rw-r--r-- | drivers/clk/imx/clk-imx7.c | 56 |
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); |