From 78ae71ac882fbca3b092656b6fed46f0c2e71dd6 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Tue, 24 Nov 2015 12:17:58 +0100 Subject: clk: imx25: Remove osc clock from driver The 'osc' clock is already initialized by the fixed clock defined in imx25.dtsi. The imx25 clock driver tries to add this clock for a second time and fails with -EEXIST: i.MX clk 1: register failed with -17 As the clock is already properly setup in DT with a different driver, we can completely remove the handling in the imx25 clock driver. Signed-off-by: Markus Pargmann Reviewed-by: Lucas Stach Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx25.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'drivers/clk/imx') diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c index c4c141cab444..23686f756b5e 100644 --- a/drivers/clk/imx/clk-imx25.c +++ b/drivers/clk/imx/clk-imx25.c @@ -96,13 +96,11 @@ static struct clk ** const uart_clks[] __initconst = { NULL }; -static int __init __mx25_clocks_init(unsigned long osc_rate, - void __iomem *ccm_base) +static int __init __mx25_clocks_init(void __iomem *ccm_base) { BUG_ON(!ccm_base); clk[dummy] = imx_clk_fixed("dummy", 0); - clk[osc] = imx_clk_fixed("osc", osc_rate); clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "mpll", "osc", ccm(CCM_MPCTL)); clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "upll", "osc", ccm(CCM_UPCTL)); clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4); @@ -250,22 +248,10 @@ static int __init __mx25_clocks_init(unsigned long osc_rate, static void __init mx25_clocks_init_dt(struct device_node *np) { - struct device_node *refnp; - unsigned long osc_rate = 24000000; void __iomem *ccm; - /* retrieve the freqency of fixed clocks from device tree */ - for_each_compatible_node(refnp, NULL, "fixed-clock") { - u32 rate; - if (of_property_read_u32(refnp, "clock-frequency", &rate)) - continue; - - if (of_device_is_compatible(refnp, "fsl,imx-osc")) - osc_rate = rate; - } - ccm = of_iomap(np, 0); - __mx25_clocks_init(osc_rate, ccm); + __mx25_clocks_init(ccm); clk_data.clks = clk; clk_data.clk_num = ARRAY_SIZE(clk); -- cgit v1.2.3 From 4824b61c666831e1051530c7f0ff68b0ae6c2511 Mon Sep 17 00:00:00 2001 From: Bai Ping Date: Wed, 25 Nov 2015 00:06:53 +0800 Subject: clk: imx: add 'is_prepared' clk_ops callback for pllv3 clk Add 'is_prepared' callback function for pllv3 type clk to make sure when the system is bootup, the unused clk is in a known state to match the prepare count info. Signed-off-by: Bai Ping Reviewed-by: Lucas Stach Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-pllv3.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/clk/imx') diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c index 6addf8f58b97..c05c43d56a94 100644 --- a/drivers/clk/imx/clk-pllv3.c +++ b/drivers/clk/imx/clk-pllv3.c @@ -97,6 +97,16 @@ static void clk_pllv3_unprepare(struct clk_hw *hw) writel_relaxed(val, pll->base); } +static int clk_pllv3_is_prepared(struct clk_hw *hw) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + + if (readl_relaxed(pll->base) & BM_PLL_LOCK) + return 1; + + return 0; +} + static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -139,6 +149,7 @@ static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_pllv3_ops = { .prepare = clk_pllv3_prepare, .unprepare = clk_pllv3_unprepare, + .is_prepared = clk_pllv3_is_prepared, .recalc_rate = clk_pllv3_recalc_rate, .round_rate = clk_pllv3_round_rate, .set_rate = clk_pllv3_set_rate, @@ -193,6 +204,7 @@ static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_pllv3_sys_ops = { .prepare = clk_pllv3_prepare, .unprepare = clk_pllv3_unprepare, + .is_prepared = clk_pllv3_is_prepared, .recalc_rate = clk_pllv3_sys_recalc_rate, .round_rate = clk_pllv3_sys_round_rate, .set_rate = clk_pllv3_sys_set_rate, @@ -265,6 +277,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_pllv3_av_ops = { .prepare = clk_pllv3_prepare, .unprepare = clk_pllv3_unprepare, + .is_prepared = clk_pllv3_is_prepared, .recalc_rate = clk_pllv3_av_recalc_rate, .round_rate = clk_pllv3_av_round_rate, .set_rate = clk_pllv3_av_set_rate, @@ -279,6 +292,7 @@ static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw, static const struct clk_ops clk_pllv3_enet_ops = { .prepare = clk_pllv3_prepare, .unprepare = clk_pllv3_unprepare, + .is_prepared = clk_pllv3_is_prepared, .recalc_rate = clk_pllv3_enet_recalc_rate, }; -- cgit v1.2.3 From 2e133f61882baefaf89dc79c56a7975d80360ef4 Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Sun, 15 Nov 2015 11:38:04 +0100 Subject: clk: imx: clk-imx6q: Let OSC to be routed to anaclk2/2b OSC can be used as USB hub source clock. An example we can route to CLK2_P imx6 pin. This show a usage example: [...] usb_hub: usb-hub { compatible = "smsc,usb3503a"; clocks = <&clks IMX6QDL_CLK_LVDS2_GATE>; clock-names = "refclk"; }; }; [...] &clks { assigned-clocks = <&clks IMX6QDL_CLK_LVDS2_SEL>; assigned-clock-parents = <&clks IMX6QDL_CLK_OSC>; }; /sys/kernel/debug/clk/clk_summary osc 5 5 24000000 0 0 [...] lvds2_sel 1 1 24000000 0 0 lvds2_gate 1 1 24000000 0 0 [...] Signed-off-by: Michael Trimarchi Reviewed-by: Lucas Stach Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx6q.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/clk/imx') diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index c1935081d34a..f0efc6feeec2 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -70,7 +70,8 @@ static const char *cko_sels[] = { "cko1", "cko2", }; static const char *lvds_sels[] = { "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref", - "pcie_ref_125m", "sata_ref_100m", + "pcie_ref_125m", "sata_ref_100m", "usbphy1", "usbphy2", + "dummy", "dummy", "dummy", "dummy", "osc", }; static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", }; static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; -- cgit v1.2.3 From fdb868cd059a97b35e4a5fcfa073a5d9c375fcdf Mon Sep 17 00:00:00 2001 From: Bai Ping Date: Tue, 24 Nov 2015 18:25:14 +0800 Subject: clk: imx: Add a virtual arm clk on i.mx7d Add a virtual arm clk to abstract the actual steps when changing the ARM core frequency.So we can using the 'cpufreq-dt' driver on i.MX7D/Solo. Signed-off-by: Bai Ping Acked-by: Lucas Stach Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx7d.c | 6 ++++++ include/dt-bindings/clock/imx7d-clock.h | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/clk/imx') diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 448ef321948b..581b428d3133 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -833,6 +833,12 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); + clks[IMX7D_CLK_ARM] = imx_clk_cpu("arm", "arm_a7_root_clk", + clks[IMX7D_ARM_A7_ROOT_CLK], + clks[IMX7D_ARM_A7_ROOT_SRC], + clks[IMX7D_PLL_ARM_MAIN_CLK], + clks[IMX7D_PLL_SYS_MAIN_CLK]); + for (i = 0; i < ARRAY_SIZE(clks); i++) if (IS_ERR(clks[i])) pr_err("i.MX7D clk %d: register failed with %ld\n", diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h index a4a7a9ce3457..edca8985c50e 100644 --- a/include/dt-bindings/clock/imx7d-clock.h +++ b/include/dt-bindings/clock/imx7d-clock.h @@ -447,5 +447,6 @@ #define IMX7D_SEMA4_HS_ROOT_CLK 434 #define IMX7D_PLL_DRAM_TEST_DIV 435 #define IMX7D_ADC_ROOT_CLK 436 -#define IMX7D_CLK_END 437 +#define IMX7D_CLK_ARM 437 +#define IMX7D_CLK_END 438 #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ -- cgit v1.2.3 From 31cbb57d5ac3b8f7a84803eb329fcc8a73fb4ab6 Mon Sep 17 00:00:00 2001 From: Bai Ping Date: Thu, 26 Nov 2015 10:18:43 +0800 Subject: clk: imx: Replace clk error check with imx_check_clocks() As we already have a 'imx_check_clocks' to do the clock error check, so cleanup the error check code. Signed-off-by: Bai Ping Acked-by: Stephen Boyd Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx6ul.c | 4 +--- drivers/clk/imx/clk-imx7d.c | 5 +---- 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/clk/imx') diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 01718d05e952..08692d74b884 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -399,9 +399,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) /* mask handshake of mmdc */ writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR); - for (i = 0; i < ARRAY_SIZE(clks); i++) - if (IS_ERR(clks[i])) - pr_err("i.MX6UL clk %d: register failed with %ld\n", i, PTR_ERR(clks[i])); + imx_check_clocks(clks, ARRAY_SIZE(clks)); clk_data.clks = clks; clk_data.clk_num = ARRAY_SIZE(clks); diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 581b428d3133..fbb6a8c8653d 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -839,10 +839,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) clks[IMX7D_PLL_ARM_MAIN_CLK], clks[IMX7D_PLL_SYS_MAIN_CLK]); - for (i = 0; i < ARRAY_SIZE(clks); i++) - if (IS_ERR(clks[i])) - pr_err("i.MX7D clk %d: register failed with %ld\n", - i, PTR_ERR(clks[i])); + imx_check_clocks(clks, ARRAY_SIZE(clks)); clk_data.clks = clks; clk_data.clk_num = ARRAY_SIZE(clks); -- cgit v1.2.3 From c20737a2a7b8666648be3f4b386749339958dace Mon Sep 17 00:00:00 2001 From: Patrick Brünn Date: Wed, 2 Dec 2015 10:16:37 +0100 Subject: clk: imx5: ipu_di_sel clocks can set parent rates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To obtain exact pixel clocks, allow the DI clock selectors to influence the PLLs that they are derived from. Commit 4591b13289b5 ("ARM: i.MX6: ipu_di_sel clocks can set parent rates") did this for i.MX6. Port it to enable high display resolutions on i.MX53 based platforms such as CX9020 Embedded PC, too. Signed-off-by: Patrick Brünn Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx51-imx53.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/clk/imx') diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c index c6770348d2ab..29d4c44ef356 100644 --- a/drivers/clk/imx/clk-imx51-imx53.c +++ b/drivers/clk/imx/clk-imx51-imx53.c @@ -519,10 +519,10 @@ static void __init mx53_clocks_init(struct device_node *np) mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT); clk[IMX5_CLK_LDB_DI0_GATE] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28); clk[IMX5_CLK_LDB_DI1_GATE] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30); - clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, - mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel)); - clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, - mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel)); + clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_flags("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, + mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel), CLK_SET_RATE_PARENT); + clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux_flags("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, + mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel), CLK_SET_RATE_PARENT); clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT); clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30); -- cgit v1.2.3