From 8efaf5ed4d442068a1b76f218c0a90e6a5989f11 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 6 Aug 2015 22:13:56 +0800 Subject: clk: imx: increase AXI clock rate to 264MHz for i.MX6UL On i.MX6UL, AXI clock rate's design target is 264MHz, but by default it is only set to 198MHz which is NOT good enough for performance, this patch increases AXI clock rate from 198MHz to 264MHz to meet the design target, this is done by switching its parent clock "periph" from 396MHz PFD to 528MHz PLL. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index aaa3665..01718d0 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -407,6 +407,24 @@ static void __init imx6ul_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); + /* + * Lower the AHB clock rate before changing the parent clock source, + * as AHB clock rate can NOT be higher than 133MHz, but its parent + * will be switched from 396MHz PFD to 528MHz PLL in order to increase + * AXI clock rate, so we need to lower AHB rate first to make sure at + * any time, AHB rate is <= 133MHz. + */ + clk_set_rate(clks[IMX6UL_CLK_AHB], 99000000); + + /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */ + clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_PLL3_USB_OTG]); + clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_CLK2]); + clk_set_parent(clks[IMX6UL_CLK_PERIPH_PRE], clks[IMX6UL_CLK_PLL2_BUS]); + clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_PRE]); + + /* Make sure AHB rate is 132MHz */ + clk_set_rate(clks[IMX6UL_CLK_AHB], 132000000); + /* set perclk to from OSC */ clk_set_parent(clks[IMX6UL_CLK_PERCLK_SEL], clks[IMX6UL_CLK_OSC]); -- cgit v0.10.2 From 0753f56e411a5e216c9899c21e54bd11dde17313 Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Mon, 7 Sep 2015 13:51:35 +0530 Subject: clk: clk-vf610: Add clock for Vybrid OCOTP controller Add clock support for Vybrid On-Chip One Time Programmable (OCOTP) controller. While the OCOTP block does not require explicit clock gating, for programming the OCOTP timing register the clock rate of ipg clock is required for timing calculations related to fuse and shadow register read sequence. We explicitly specify the ipg clock for OCOTP as a result. Signed-off-by: Sanchayan Maity Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index bff45ea..d1b1c95 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c @@ -387,6 +387,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7)); clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24); + clk[VF610_CLK_OCOTP] = imx_clk_gate("ocotp", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(5)); imx_check_clocks(clk, ARRAY_SIZE(clk)); diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h index d197634..56c16aa 100644 --- a/include/dt-bindings/clock/vf610-clock.h +++ b/include/dt-bindings/clock/vf610-clock.h @@ -194,6 +194,7 @@ #define VF610_PLL7_BYPASS 181 #define VF610_CLK_SNVS 182 #define VF610_CLK_DAP 183 -#define VF610_CLK_END 184 +#define VF610_CLK_OCOTP 184 +#define VF610_CLK_END 185 #endif /* __DT_BINDINGS_CLOCK_VF610_H */ -- cgit v0.10.2 From 8d449cb5e29a488cef44d81196f2819b92585513 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 9 Sep 2015 11:35:14 +0200 Subject: clk: imx35: Do not call mxc_timer_init twice when booting with DT mxc_timer_init must not be called from within mx35_clocks_init_dt. It will eventually be called by imx31_timer_init_dt (drivers/clocksource/timer-imx-gpt.c). This arranges the initialization code similar to clk-imx27.c Signed-off-by: Alexander Stein Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c index 8623cd4..76c463d 100644 --- a/drivers/clk/imx/clk-imx35.c +++ b/drivers/clk/imx/clk-imx35.c @@ -84,7 +84,7 @@ enum mx35_clks { static struct clk *clk[clk_max]; -int __init mx35_clocks_init(void) +static void __init _mx35_clocks_init(void) { void __iomem *base; u32 pdr0, consumer_sel, hsp_sel; @@ -220,6 +220,30 @@ int __init mx35_clocks_init(void) imx_check_clocks(clk, ARRAY_SIZE(clk)); + clk_prepare_enable(clk[spba_gate]); + clk_prepare_enable(clk[gpio1_gate]); + clk_prepare_enable(clk[gpio2_gate]); + clk_prepare_enable(clk[gpio3_gate]); + clk_prepare_enable(clk[iim_gate]); + clk_prepare_enable(clk[emi_gate]); + clk_prepare_enable(clk[max_gate]); + clk_prepare_enable(clk[iomuxc_gate]); + + /* + * SCC is needed to boot via mmc after a watchdog reset. The clock code + * before conversion to common clk also enabled UART1 (which isn't + * handled here and not needed for mmc) and IIM (which is enabled + * unconditionally above). + */ + clk_prepare_enable(clk[scc_gate]); + + imx_print_silicon_rev("i.MX35", mx35_revision()); +} + +int __init mx35_clocks_init(void) +{ + _mx35_clocks_init(); + clk_register_clkdev(clk[pata_gate], NULL, "pata_imx"); clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0"); clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1"); @@ -279,25 +303,6 @@ int __init mx35_clocks_init(void) clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); clk_register_clkdev(clk[admux_gate], "audmux", NULL); - clk_prepare_enable(clk[spba_gate]); - clk_prepare_enable(clk[gpio1_gate]); - clk_prepare_enable(clk[gpio2_gate]); - clk_prepare_enable(clk[gpio3_gate]); - clk_prepare_enable(clk[iim_gate]); - clk_prepare_enable(clk[emi_gate]); - clk_prepare_enable(clk[max_gate]); - clk_prepare_enable(clk[iomuxc_gate]); - - /* - * SCC is needed to boot via mmc after a watchdog reset. The clock code - * before conversion to common clk also enabled UART1 (which isn't - * handled here and not needed for mmc) and IIM (which is enabled - * unconditionally above). - */ - clk_prepare_enable(clk[scc_gate]); - - imx_print_silicon_rev("i.MX35", mx35_revision()); - mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31); return 0; @@ -305,10 +310,10 @@ int __init mx35_clocks_init(void) static void __init mx35_clocks_init_dt(struct device_node *ccm_node) { + _mx35_clocks_init(); + clk_data.clks = clk; clk_data.clk_num = ARRAY_SIZE(clk); of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data); - - mx35_clocks_init(); } CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt); -- cgit v0.10.2 From 55adc61c568af99419be1dc0412f8eae019c71f2 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 21 Sep 2015 18:53:57 +0200 Subject: clk: imx: add common logic to detect early UART usage Both earlycon and eralyprintk depend on the bootloader setup UART clocks being retained. This patch adds the common logic to detect such situations and make the information available to the clock drivers, as well as adding the facilities to disable those clocks at the end of the kernel init. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index df12b53..a634b11 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -73,3 +73,41 @@ void imx_cscmr1_fixup(u32 *val) *val ^= CSCMR1_FIXUP; return; } + +static int imx_keep_uart_clocks __initdata; +static struct clk ** const *imx_uart_clocks __initdata; + +static int __init imx_keep_uart_clocks_param(char *str) +{ + imx_keep_uart_clocks = 1; + + return 0; +} +__setup_param("earlycon", imx_keep_uart_earlycon, + imx_keep_uart_clocks_param, 0); +__setup_param("earlyprintk", imx_keep_uart_earlyprintk, + imx_keep_uart_clocks_param, 0); + +void __init imx_register_uart_clocks(struct clk ** const clks[]) +{ + if (imx_keep_uart_clocks) { + int i; + + imx_uart_clocks = clks; + for (i = 0; imx_uart_clocks[i]; i++) + clk_prepare_enable(*imx_uart_clocks[i]); + } +} + +static int __init imx_clk_disable_uart(void) +{ + if (imx_keep_uart_clocks && imx_uart_clocks) { + int i; + + for (i = 0; imx_uart_clocks[i]; i++) + clk_disable_unprepare(*imx_uart_clocks[i]); + } + + return 0; +} +late_initcall_sync(imx_clk_disable_uart); diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 1049b0c..c94ac5c 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -7,6 +7,7 @@ extern spinlock_t imx_ccm_lock; void imx_check_clocks(struct clk *clks[], unsigned int count); +void imx_register_uart_clocks(struct clk ** const clks[]); extern void imx_cscmr1_fixup(u32 *val); -- cgit v0.10.2 From 517c7f9302efdde86fe8ebca80bc9ef826fa62e5 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 21 Sep 2015 18:53:58 +0200 Subject: clk: imx25: retain early UART clocks during kernel init Make sure to keep UART clocks enabled during kernel init if earlyprintk or earlycon are active. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c index ec1a4c1..c4c141c 100644 --- a/drivers/clk/imx/clk-imx25.c +++ b/drivers/clk/imx/clk-imx25.c @@ -86,6 +86,16 @@ enum mx25_clks { static struct clk *clk[clk_max]; +static struct clk ** const uart_clks[] __initconst = { + &clk[uart_ipg_per], + &clk[uart1_ipg], + &clk[uart2_ipg], + &clk[uart3_ipg], + &clk[uart4_ipg], + &clk[uart5_ipg], + NULL +}; + static int __init __mx25_clocks_init(unsigned long osc_rate, void __iomem *ccm_base) { @@ -233,6 +243,8 @@ static int __init __mx25_clocks_init(unsigned long osc_rate, */ clk_set_parent(clk[cko_sel], clk[ipg]); + imx_register_uart_clocks(uart_clks); + return 0; } -- cgit v0.10.2 From 6f1871316347a5ef098d85305d5eb5ac6ac1f52a Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 21 Sep 2015 18:53:59 +0200 Subject: clk: imx27: retain early UART clocks during kernel init Make sure to keep UART clocks enabled during kernel init if earlyprintk or earlycon are active. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c index d9d50d5..0d7b8df 100644 --- a/drivers/clk/imx/clk-imx27.c +++ b/drivers/clk/imx/clk-imx27.c @@ -47,6 +47,17 @@ static const char *ssi_sel_clks[] = { "spll_gate", "mpll", }; static struct clk *clk[IMX27_CLK_MAX]; static struct clk_onecell_data clk_data; +static struct clk ** const uart_clks[] __initconst = { + &clk[IMX27_CLK_PER1_GATE], + &clk[IMX27_CLK_UART1_IPG_GATE], + &clk[IMX27_CLK_UART2_IPG_GATE], + &clk[IMX27_CLK_UART3_IPG_GATE], + &clk[IMX27_CLK_UART4_IPG_GATE], + &clk[IMX27_CLK_UART5_IPG_GATE], + &clk[IMX27_CLK_UART6_IPG_GATE], + NULL +}; + static void __init _mx27_clocks_init(unsigned long fref) { BUG_ON(!ccm); @@ -163,6 +174,8 @@ static void __init _mx27_clocks_init(unsigned long fref) clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]); + imx_register_uart_clocks(uart_clks); + imx_print_silicon_rev("i.MX27", mx27_revision()); } -- cgit v0.10.2 From 5c678cdd02f25398b4908638d672b134cff9d59c Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 21 Sep 2015 18:54:00 +0200 Subject: clk: imx31: retain early UART clocks during kernel init Make sure to keep UART clocks enabled during kernel init if earlyprintk or earlycon are active. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c index 1f83834..5520e20 100644 --- a/drivers/clk/imx/clk-imx31.c +++ b/drivers/clk/imx/clk-imx31.c @@ -62,6 +62,16 @@ enum mx31_clks { static struct clk *clk[clk_max]; static struct clk_onecell_data clk_data; +static struct clk ** const uart_clks[] __initconst = { + &clk[ipg], + &clk[uart1_gate], + &clk[uart2_gate], + &clk[uart3_gate], + &clk[uart4_gate], + &clk[uart5_gate], + NULL +}; + int __init mx31_clocks_init(unsigned long fref) { void __iomem *base; @@ -200,6 +210,8 @@ int __init mx31_clocks_init(unsigned long fref) mx31_revision(); clk_disable_unprepare(clk[iim_gate]); + imx_register_uart_clocks(uart_clks); + mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31); return 0; -- cgit v0.10.2 From 57d5a4c3ed001f813f1c8e1609db83c84d0e88cf Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 21 Sep 2015 18:54:01 +0200 Subject: clk: imx35: retain early UART clocks during kernel init Make sure to keep UART clocks enabled during kernel init if earlyprintk or earlycon are active. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c index 76c463d..a71d24c 100644 --- a/drivers/clk/imx/clk-imx35.c +++ b/drivers/clk/imx/clk-imx35.c @@ -84,6 +84,14 @@ enum mx35_clks { static struct clk *clk[clk_max]; +static struct clk ** const uart_clks[] __initconst = { + &clk[ipg], + &clk[uart1_gate], + &clk[uart2_gate], + &clk[uart3_gate], + NULL +}; + static void __init _mx35_clocks_init(void) { void __iomem *base; @@ -237,6 +245,8 @@ static void __init _mx35_clocks_init(void) */ clk_prepare_enable(clk[scc_gate]); + imx_register_uart_clocks(uart_clks); + imx_print_silicon_rev("i.MX35", mx35_revision()); } -- cgit v0.10.2 From 89981a6f7bbe5b98c3f9c8e01ca53c1f7b28030d Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 21 Sep 2015 18:54:02 +0200 Subject: clk: imx5: retain early UART clocks during kernel init Make sure to keep UART clocks enabled during kernel init if earlyprintk or earlycon are active. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c index a7e4f39..c677034 100644 --- a/drivers/clk/imx/clk-imx51-imx53.c +++ b/drivers/clk/imx/clk-imx51-imx53.c @@ -130,6 +130,20 @@ static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" }; static struct clk *clk[IMX5_CLK_END]; static struct clk_onecell_data clk_data; +static struct clk ** const uart_clks[] __initconst = { + &clk[IMX5_CLK_UART1_IPG_GATE], + &clk[IMX5_CLK_UART1_PER_GATE], + &clk[IMX5_CLK_UART2_IPG_GATE], + &clk[IMX5_CLK_UART2_PER_GATE], + &clk[IMX5_CLK_UART3_IPG_GATE], + &clk[IMX5_CLK_UART3_PER_GATE], + &clk[IMX5_CLK_UART4_IPG_GATE], + &clk[IMX5_CLK_UART4_PER_GATE], + &clk[IMX5_CLK_UART5_IPG_GATE], + &clk[IMX5_CLK_UART5_PER_GATE], + NULL +}; + static void __init mx5_clocks_common_init(void __iomem *ccm_base) { clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0); @@ -310,6 +324,8 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) clk_prepare_enable(clk[IMX5_CLK_TMAX1]); clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */ clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */ + + imx_register_uart_clocks(uart_clks); } static void __init mx50_clocks_init(struct device_node *np) -- cgit v0.10.2 From 0822f933735c1eee6adfc236c72f763f42ac0f3d Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 21 Sep 2015 18:54:03 +0200 Subject: clk: imx6: retain early UART clocks during kernel init Make sure to keep UART clocks enabled during kernel init if earlyprintk or earlycon are active. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index b2c1c04..e9ba018 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -130,6 +130,12 @@ static inline int clk_on_imx6dl(void) return of_machine_is_compatible("fsl,imx6dl"); } +static struct clk ** const uart_clks[] __initconst = { + &clk[IMX6QDL_CLK_UART_IPG], + &clk[IMX6QDL_CLK_UART_SERIAL], + NULL +}; + static void __init imx6q_clocks_init(struct device_node *ccm_node) { struct device_node *np; @@ -541,5 +547,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) /* All existing boards with PCIe use LVDS1 */ if (IS_ENABLED(CONFIG_PCI_IMX6)) clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]); + + imx_register_uart_clocks(uart_clks); } CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init); diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c index a0d4cf2..3c3333f 100644 --- a/drivers/clk/imx/clk-imx6sl.c +++ b/drivers/clk/imx/clk-imx6sl.c @@ -184,6 +184,12 @@ void imx6sl_set_wait_clk(bool enter) imx6sl_enable_pll_arm(false); } +static struct clk ** const uart_clks[] __initconst = { + &clks[IMX6SL_CLK_UART], + &clks[IMX6SL_CLK_UART_SERIAL], + NULL +}; + static void __init imx6sl_clocks_init(struct device_node *ccm_node) { struct device_node *np; @@ -439,5 +445,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL], clks[IMX6SL_CLK_PLL2_PFD2]); + + imx_register_uart_clocks(uart_clks); } CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init); diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index 5b95c2c..f0ad8bb 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c @@ -135,6 +135,12 @@ static u32 share_count_ssi1; static u32 share_count_ssi2; static u32 share_count_ssi3; +static struct clk ** const uart_clks[] __initconst = { + &clks[IMX6SX_CLK_UART_IPG], + &clks[IMX6SX_CLK_UART_SERIAL], + NULL +}; + static void __init imx6sx_clocks_init(struct device_node *ccm_node) { struct device_node *np; @@ -557,5 +563,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]); clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]); + + imx_register_uart_clocks(uart_clks); } CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init); -- cgit v0.10.2 From 1b9af68f325cb91ac9fc691f52d69dfb0826afd7 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 21 Sep 2015 18:54:04 +0200 Subject: clk: imx7d: retain early UART clocks during kernel init Make sure to keep UART clocks enabled during kernel init if earlyprintk or earlycon are active. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 71f3a94..f86b680 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -363,6 +363,17 @@ static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_ static struct clk_onecell_data clk_data; +static struct clk ** const uart_clks[] __initconst = { + &clks[IMX7D_UART1_ROOT_CLK], + &clks[IMX7D_UART2_ROOT_CLK], + &clks[IMX7D_UART3_ROOT_CLK], + &clks[IMX7D_UART4_ROOT_CLK], + &clks[IMX7D_UART5_ROOT_CLK], + &clks[IMX7D_UART6_ROOT_CLK], + &clks[IMX7D_UART7_ROOT_CLK], + NULL +}; + static void __init imx7d_clocks_init(struct device_node *ccm_node) { struct device_node *np; @@ -856,5 +867,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) /* set uart module clock's parent clock source that must be great then 80MHz */ clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); + imx_register_uart_clocks(uart_clks); + } CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init); -- cgit v0.10.2 From d9388c8432379e8c99b2315bff207f0773554462 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 30 Sep 2015 08:23:40 +0200 Subject: clk: imx31: Do not call mxc_timer_init twice when booting with DT mxc_timer_init must not be called from within mx31_clocks_init_dt. It will eventually be called by imx31_timer_init_dt (drivers/clocksource/timer-imx-gpt.c). This arranges the initialization code similar to clk-imx27.c Signed-off-by: Alexander Stein Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c index 5520e20..f65b8b1 100644 --- a/drivers/clk/imx/clk-imx31.c +++ b/drivers/clk/imx/clk-imx31.c @@ -72,7 +72,7 @@ static struct clk ** const uart_clks[] __initconst = { NULL }; -int __init mx31_clocks_init(unsigned long fref) +static void __init _mx31_clocks_init(unsigned long fref) { void __iomem *base; struct device_node *np; @@ -142,6 +142,12 @@ int __init mx31_clocks_init(unsigned long fref) imx_check_clocks(clk, ARRAY_SIZE(clk)); + clk_set_parent(clk[csi], clk[upll]); + clk_prepare_enable(clk[emi_gate]); + clk_prepare_enable(clk[iim_gate]); + mx31_revision(); + clk_disable_unprepare(clk[iim_gate]); + np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm"); if (np) { @@ -149,6 +155,13 @@ int __init mx31_clocks_init(unsigned long fref) clk_data.clk_num = ARRAY_SIZE(clk); of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); } +} + +int __init mx31_clocks_init(void) +{ + u32 fref = 26000000; /* default */ + + _mx31_clocks_init(fref); clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); @@ -204,14 +217,8 @@ int __init mx31_clocks_init(unsigned long fref) clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma"); clk_register_clkdev(clk[iim_gate], "iim", NULL); - clk_set_parent(clk[csi], clk[upll]); - clk_prepare_enable(clk[emi_gate]); - clk_prepare_enable(clk[iim_gate]); - mx31_revision(); - clk_disable_unprepare(clk[iim_gate]); imx_register_uart_clocks(uart_clks); - mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31); return 0; @@ -230,5 +237,7 @@ int __init mx31_clocks_init_dt(void) break; } - return mx31_clocks_init(fref); + _mx31_clocks_init(fref); + + return 0; } -- cgit v0.10.2 From ab4c6a240731f701806154fe3e0cfb8a3abec369 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Thu, 8 Oct 2015 18:59:06 +0800 Subject: clk: imx7d: add ADC root clock Add ADC root clock support in imx7d clock tree. Signed-off-by: Haibo Chen Acked-by: Stephen Boyd Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index f86b680..448ef32 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -829,6 +829,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate2("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0); clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate2("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0); clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate2("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0); + clks[IMX7D_ADC_ROOT_CLK] = imx_clk_gate2("adc_root_clk", "ipg_root_clk", base + 0x4200, 0); clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h index 728df28..a4a7a9c 100644 --- a/include/dt-bindings/clock/imx7d-clock.h +++ b/include/dt-bindings/clock/imx7d-clock.h @@ -446,5 +446,6 @@ #define IMX7D_MU_ROOT_CLK 433 #define IMX7D_SEMA4_HS_ROOT_CLK 434 #define IMX7D_PLL_DRAM_TEST_DIV 435 -#define IMX7D_CLK_END 436 +#define IMX7D_ADC_ROOT_CLK 436 +#define IMX7D_CLK_END 437 #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ -- cgit v0.10.2 From 84a87250ee4e4f7cf5865be9757e2ea758e5cae3 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Sat, 10 Oct 2015 18:15:06 +0800 Subject: clk: imx6: Add SPDIF_GCLK clock in clock tree Correct SPDIF clock setting issue in clock tree, the SPDIF_GCLK is also one clock of SPDIF, which is missed before. We found an issue that imx can't enter low power mode with spdif if IMX6x_CLK_SPDIF is used as the core clock of spdif. Because spdif driver will register IMX6x_CLK_SPDIF clock to regmap, regmap will do clk_prepare in init function, then IMX6x_CLK_SPDIF clock is prepared in probe, so its parent clock (PLL clock) is prepared, the prepare operation of PLL clock is to enable the clock. But I.MX needs all PLL clock is disabled, then it can enter low power mode. So we can't use IMX6x_CLK_SPDIF as the core clock of spdif, the correct spdif core clock is SPDIF_GCLK, which share same gate bit with IMX6x_CLK_SPDIF clock. SPDIF_GCLK's parent clock is ipg clock. Signed-off-by: Shengjiu Wang Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index e9ba018..c193508 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -119,6 +119,7 @@ static unsigned int share_count_ssi1; static unsigned int share_count_ssi2; static unsigned int share_count_ssi3; static unsigned int share_count_mipi_core_cfg; +static unsigned int share_count_spdif; static inline int clk_on_imx6q(void) { @@ -462,7 +463,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); - clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif_podf", base + 0x7c, 14); + clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_spdif); + clk[IMX6QDL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_spdif); clk[IMX6QDL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); clk[IMX6QDL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); clk[IMX6QDL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c index 3c3333f..1be6230 100644 --- a/drivers/clk/imx/clk-imx6sl.c +++ b/drivers/clk/imx/clk-imx6sl.c @@ -97,6 +97,7 @@ static struct clk_div_table video_div_table[] = { static unsigned int share_count_ssi1; static unsigned int share_count_ssi2; static unsigned int share_count_ssi3; +static unsigned int share_count_spdif; static struct clk *clks[IMX6SL_CLK_END]; static struct clk_onecell_data clk_data; @@ -397,7 +398,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22); clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6); clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); - clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif0_podf", base + 0x7c, 14); + clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif0_podf", base + 0x7c, 14, &share_count_spdif); + clks[IMX6SL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_spdif); clks[IMX6SL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); clks[IMX6SL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); clks[IMX6SL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index f0ad8bb..fea125e 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c @@ -460,6 +460,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); clks[IMX6SX_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); + clks[IMX6SX_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_audio); clks[IMX6SX_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); clks[IMX6SX_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); clks[IMX6SX_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h index 8de173f..77985cc 100644 --- a/include/dt-bindings/clock/imx6qdl-clock.h +++ b/include/dt-bindings/clock/imx6qdl-clock.h @@ -254,6 +254,7 @@ #define IMX6QDL_CLK_CAAM_MEM 241 #define IMX6QDL_CLK_CAAM_ACLK 242 #define IMX6QDL_CLK_CAAM_IPG 243 -#define IMX6QDL_CLK_END 244 +#define IMX6QDL_CLK_SPDIF_GCLK 244 +#define IMX6QDL_CLK_END 245 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ diff --git a/include/dt-bindings/clock/imx6sl-clock.h b/include/dt-bindings/clock/imx6sl-clock.h index 9ce4e42..e14573e 100644 --- a/include/dt-bindings/clock/imx6sl-clock.h +++ b/include/dt-bindings/clock/imx6sl-clock.h @@ -174,6 +174,7 @@ #define IMX6SL_CLK_SSI1_IPG 161 #define IMX6SL_CLK_SSI2_IPG 162 #define IMX6SL_CLK_SSI3_IPG 163 -#define IMX6SL_CLK_END 164 +#define IMX6SL_CLK_SPDIF_GCLK 164 +#define IMX6SL_CLK_END 165 #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */ diff --git a/include/dt-bindings/clock/imx6sx-clock.h b/include/dt-bindings/clock/imx6sx-clock.h index 9957091..36f0324 100644 --- a/include/dt-bindings/clock/imx6sx-clock.h +++ b/include/dt-bindings/clock/imx6sx-clock.h @@ -274,6 +274,7 @@ #define IMX6SX_PLL5_BYPASS 261 #define IMX6SX_PLL6_BYPASS 262 #define IMX6SX_PLL7_BYPASS 263 -#define IMX6SX_CLK_CLK_END 264 +#define IMX6SX_CLK_SPDIF_GCLK 264 +#define IMX6SX_CLK_CLK_END 265 #endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */ -- cgit v0.10.2