From c896e938505714d4346388ddc8a82fb190f235aa Mon Sep 17 00:00:00 2001 From: Jason Liu Date: Tue, 5 Nov 2013 12:03:18 +0800 Subject: ARM: i.MX6: add more chip revision support Add more revision support for the new i.MX6DQ tape-out (TO1.5). This TO1.5 is the Rev 1.3 as documented in i.MX6DQ data sheet, because TO1.3 and TO1.4 are never revealed. Signed-off-by: Jason Liu Signed-off-by: Shawn Guo Acked-by: Sascha Hauer --- arch/arm/mach-imx/anatop.c | 13 +++++++++++++ arch/arm/mach-imx/mxc.h | 2 ++ 2 files changed, 15 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 4a40bbb46183..8259a625a920 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -104,6 +104,19 @@ void __init imx_init_revision_from_anatop(void) case 2: revision = IMX_CHIP_REVISION_1_2; break; + case 3: + revision = IMX_CHIP_REVISION_1_3; + break; + case 4: + revision = IMX_CHIP_REVISION_1_4; + break; + case 5: + /* + * i.MX6DQ TO1.5 is defined as Rev 1.3 in Data Sheet, marked + * as 'D' in Part Number last character. + */ + revision = IMX_CHIP_REVISION_1_5; + break; default: revision = IMX_CHIP_REVISION_UNKNOWN; } diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index a39b69ef4301..17a41ca65acf 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -43,6 +43,8 @@ #define IMX_CHIP_REVISION_1_1 0x11 #define IMX_CHIP_REVISION_1_2 0x12 #define IMX_CHIP_REVISION_1_3 0x13 +#define IMX_CHIP_REVISION_1_4 0x14 +#define IMX_CHIP_REVISION_1_5 0x15 #define IMX_CHIP_REVISION_2_0 0x20 #define IMX_CHIP_REVISION_2_1 0x21 #define IMX_CHIP_REVISION_2_2 0x22 -- cgit v1.2.3-55-g7522 From 24980dc810f2c41929a50277946737e25ab3c0cd Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sat, 26 Jul 2014 13:45:28 +0400 Subject: ARM: i.MX1: Add devicetree support This patch adds basic devicetree support for i.MX1 based SoCs. Signed-off-by: Alexander Shiyan Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 8 ++++++++ arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/imx1-dt.c | 26 ++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 arch/arm/mach-imx/imx1-dt.c (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 4e9b4f63d42b..11b2957f792b 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -69,6 +69,7 @@ config SOC_IMX1 select CPU_ARM920T select IMX_HAVE_IOMUX_V1 select MXC_AVIC + select PINCTRL_IMX1 config SOC_IMX21 bool @@ -124,6 +125,13 @@ config MACH_APF9328 help Say Yes here if you are using the Armadeus APF9328 development board +config MACH_IMX1_DT + bool "Support i.MX1 platforms from device tree" + select SOC_IMX1 + help + Include support for Freescale i.MX1 based platforms + using the device tree for discovery. + endif if ARCH_MULTI_V5 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 4147729775d2..ef215d108e4d 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -43,6 +43,7 @@ endif # i.MX1 based machines obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o obj-$(CONFIG_MACH_APF9328) += mach-apf9328.o +obj-$(CONFIG_MACH_IMX1_DT) += imx1-dt.o # i.MX21 based machines obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o diff --git a/arch/arm/mach-imx/imx1-dt.c b/arch/arm/mach-imx/imx1-dt.c new file mode 100644 index 000000000000..6f915b0961c4 --- /dev/null +++ b/arch/arm/mach-imx/imx1-dt.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 Alexander Shiyan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include + +#include "common.h" + +static const char * const imx1_dt_board_compat[] __initconst = { + "fsl,imx1", + NULL +}; + +DT_MACHINE_START(IMX1_DT, "Freescale i.MX1 (Device Tree Support)") + .map_io = mx1_map_io, + .init_early = imx1_init_early, + .init_irq = mx1_init_irq, + .dt_compat = imx1_dt_board_compat, + .restart = mxc_restart, +MACHINE_END -- cgit v1.2.3-55-g7522 From 3b18dd7a86f925951c8543339f8137a80fa40891 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 29 Jul 2014 16:20:28 +0200 Subject: ARM: imx: clk-vf610: introduce clks_init_on At the end of the boot process, the clock framework might disable required main PLL's. So far, this was no issue since drivers requested clocks, which are descended of the main PLL's (e.g. pll1_pfd1, which provides the system clock). To archive the full 500MHz system clock, DDR clock need to be a descendant of PLL2 rather than PLL1 (DDRC_CLK_SEL set to 0). The bootloader sets up the clocks accordingly before making use of DDR at all. However, in Linux, there is no driver using PLL2, which lead to PLL2 being disabled by the clock framework. With this patch, we make sure that the main system clock and the DDR clock are initially enabled and are kept enabled. Signed-off-by: Stefan Agner Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-vf610.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c index f60d6d569ce3..a41ed73219da 100644 --- a/arch/arm/mach-imx/clk-vf610.c +++ b/arch/arm/mach-imx/clk-vf610.c @@ -98,9 +98,15 @@ static struct clk_div_table pll4_main_div_table[] = { static struct clk *clk[VF610_CLK_END]; static struct clk_onecell_data clk_data; +static unsigned int const clks_init_on[] __initconst = { + VF610_CLK_SYS_BUS, + VF610_CLK_DDR_SEL, +}; + static void __init vf610_clocks_init(struct device_node *ccm_node) { struct device_node *np; + int i; clk[VF610_CLK_DUMMY] = imx_clk_fixed("dummy", 0); clk[VF610_CLK_SIRC_128K] = imx_clk_fixed("sirc_128k", 128000); @@ -322,6 +328,9 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk_set_parent(clk[VF610_CLK_SAI2_SEL], clk[VF610_CLK_AUDIO_EXT]); clk_set_parent(clk[VF610_CLK_SAI3_SEL], clk[VF610_CLK_AUDIO_EXT]); + for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) + clk_prepare_enable(clk[clks_init_on[i]]); + /* Add the clocks to provider list */ clk_data.clks = clk; clk_data.clk_num = ARRAY_SIZE(clk); -- cgit v1.2.3-55-g7522 From 47526e410d32f749d78ce2655b6eeb2bffd9ed3d Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 25 Jun 2014 17:10:12 +0800 Subject: ARM: imx: add cpufreq support for i.mx6sx Add cpufreq support for i.MX6SX, using common i.MX6Q cpufreq driver. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx6sx.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c index 673a734165ba..3de3b7369aef 100644 --- a/arch/arm/mach-imx/mach-imx6sx.c +++ b/arch/arm/mach-imx/mach-imx6sx.c @@ -42,6 +42,9 @@ static void __init imx6sx_init_irq(void) static void __init imx6sx_init_late(void) { imx6q_cpuidle_init(); + + if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) + platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0); } static const char * const imx6sx_dt_compat[] __initconst = { -- cgit v1.2.3-55-g7522 From 21231f81f13db2883f11664b67fc6fb2690e6af2 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Mon, 18 Aug 2014 22:07:12 +0200 Subject: ARM: imx: clk-vf610: Add USBPHY clocks This commit adds PLL7 which is required for USBPHY1. It also adds the USB PHY and USB Controller clocks and the gates to enable them. Acked-by: Jingchang Lu Signed-off-by: Stefan Agner Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-vf610.c | 12 ++++++++++-- include/dt-bindings/clock/vf610-clock.h | 5 ++++- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c index a41ed73219da..a17818475050 100644 --- a/arch/arm/mach-imx/clk-vf610.c +++ b/arch/arm/mach-imx/clk-vf610.c @@ -58,6 +58,8 @@ #define PFD_PLL1_BASE (anatop_base + 0x2b0) #define PFD_PLL2_BASE (anatop_base + 0x100) #define PFD_PLL3_BASE (anatop_base + 0xf0) +#define PLL3_CTRL (anatop_base + 0x10) +#define PLL7_CTRL (anatop_base + 0x20) static void __iomem *anatop_base; static void __iomem *ccm_base; @@ -154,6 +156,9 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_PLL5_MAIN] = imx_clk_fixed_factor("pll5_main", "fast_clk_sel", 125, 6); /* pll6: default 960Mhz */ clk[VF610_CLK_PLL6_MAIN] = imx_clk_fixed_factor("pll6_main", "fast_clk_sel", 40, 1); + /* pll7: USB1 PLL at 480MHz */ + clk[VF610_CLK_PLL7_MAIN] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_main", "fast_clk_sel", PLL7_CTRL, 0x2); + clk[VF610_CLK_PLL1_PFD_SEL] = imx_clk_mux("pll1_pfd_sel", CCM_CCSR, 16, 3, pll1_sels, 5); clk[VF610_CLK_PLL2_PFD_SEL] = imx_clk_mux("pll2_pfd_sel", CCM_CCSR, 19, 3, pll2_sels, 5); clk[VF610_CLK_SYS_SEL] = imx_clk_mux("sys_sel", CCM_CCSR, 0, 3, sys_sels, ARRAY_SIZE(sys_sels)); @@ -166,8 +171,11 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_main_div", "pll4_main", 0, CCM_CACRR, 6, 3, 0, pll4_main_div_table, &imx_ccm_lock); clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_main_div", "pll6_main", CCM_CACRR, 21, 1); - clk[VF610_CLK_USBC0] = imx_clk_gate2("usbc0", "pll3_main", CCM_CCGR1, CCM_CCGRx_CGn(4)); - clk[VF610_CLK_USBC1] = imx_clk_gate2("usbc1", "pll3_main", CCM_CCGR7, CCM_CCGRx_CGn(4)); + clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_main", PLL3_CTRL, 6); + clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_main", PLL7_CTRL, 6); + + clk[VF610_CLK_USBC0] = imx_clk_gate2("usbc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(4)); + clk[VF610_CLK_USBC1] = imx_clk_gate2("usbc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(4)); clk[VF610_CLK_QSPI0_SEL] = imx_clk_mux("qspi0_sel", CCM_CSCMR1, 22, 2, qspi_sels, 4); clk[VF610_CLK_QSPI0_EN] = imx_clk_gate("qspi0_en", "qspi0_sel", CCM_CSCDR3, 4); diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h index 00953d9484cb..d6b56b21539b 100644 --- a/include/dt-bindings/clock/vf610-clock.h +++ b/include/dt-bindings/clock/vf610-clock.h @@ -166,6 +166,9 @@ #define VF610_CLK_DMAMUX3 153 #define VF610_CLK_FLEXCAN0_EN 154 #define VF610_CLK_FLEXCAN1_EN 155 -#define VF610_CLK_END 156 +#define VF610_CLK_PLL7_MAIN 156 +#define VF610_CLK_USBPHY0 157 +#define VF610_CLK_USBPHY1 158 +#define VF610_CLK_END 159 #endif /* __DT_BINDINGS_CLOCK_VF610_H */ -- cgit v1.2.3-55-g7522 From bad66c3ebdcdb4043bdcfe24ddab4802d5fc4327 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 19 Aug 2014 15:21:11 -0300 Subject: ARM: clk-imx6sl: Remove csi_lcdif_sels[] Currently csi_lcdif_sels[] is a shared array for the providing the possible clock parents for csi and lcdif blocks. This is not correct, as csi and lcdif do not share the same clock parents. Introduce csi_sels[] for the csi and lcdif_axi_sels[] for the lcdif clocks in order to describe the parents correctly. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6sl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index fef46faf692f..ba3af22c1266 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -43,7 +43,8 @@ static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", }; static const char *periph_sels[] = { "pre_periph_sel", "periph_clk2_podf", }; static const char *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2_podf", }; -static const char *csi_lcdif_sels[] = { "mmdc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", }; +static const char *csi_sels[] = { "osc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", }; +static const char *lcdif_axi_sels[] = { "pll2_bus", "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", }; static const char *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", }; static const char *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", }; static const char *perclk_sels[] = { "ipg", "osc", }; @@ -241,8 +242,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) clks[IMX6SL_CLK_PRE_PERIPH_SEL] = imx_clk_mux("pre_periph_sel", base + 0x18, 18, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels)); clks[IMX6SL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); clks[IMX6SL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); - clks[IMX6SL_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_lcdif_sels, ARRAY_SIZE(csi_lcdif_sels)); - clks[IMX6SL_CLK_LCDIF_AXI_SEL] = imx_clk_mux("lcdif_axi_sel", base + 0x3c, 14, 2, csi_lcdif_sels, ARRAY_SIZE(csi_lcdif_sels)); + clks[IMX6SL_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels)); + clks[IMX6SL_CLK_LCDIF_AXI_SEL] = imx_clk_mux("lcdif_axi_sel", base + 0x3c, 14, 2, lcdif_axi_sels, ARRAY_SIZE(lcdif_axi_sels)); clks[IMX6SL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); clks[IMX6SL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); clks[IMX6SL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); -- cgit v1.2.3-55-g7522 From 0783a56087e9ecfae2f01f9662ff52081c5b5e25 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 19 Aug 2014 15:21:12 -0300 Subject: ARM: clk-imx6sl: Select appropriate parents for LCDIF clocks PLL5 is well suited for being the parent of IMX6SL_CLK_LCDIF_PIX_SEL and PLL2_PFD for IMX6SL_CLK_LCDIF_AXI_SEL. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6sl.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index ba3af22c1266..11908e8bf9ab 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -376,6 +376,13 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) /* Audio-related clocks configuration */ clk_set_parent(clks[IMX6SL_CLK_SPDIF0_SEL], clks[IMX6SL_CLK_PLL3_PFD3]); + /* set PLL5 video as lcdif pix parent clock */ + clk_set_parent(clks[IMX6SL_CLK_LCDIF_PIX_SEL], + clks[IMX6SL_CLK_PLL5_VIDEO_DIV]); + + clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL], + clks[IMX6SL_CLK_PLL2_PFD2]); + /* Set initial power mode */ imx6q_set_lpm(WAIT_CLOCKED); } -- cgit v1.2.3-55-g7522 From 7bce3d23ecfd327bd277598d67e93655fb4cc0ed Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 8 Aug 2014 15:02:47 +0800 Subject: ARM: clk-imx6q: refine clock tree for ESAI There are three clock for ESAI, esai_extal, esai_ipg, esai_mem. Rename 'esai' to 'esai_extal', 'esai_ahb' to 'esai_mem', and add 'esai_ipg'. Make the clock for ESAI more clear and align them with imx6sx. Signed-off-by: Shengjiu Wang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 7 ++++--- include/dt-bindings/clock/imx6qdl-clock.h | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 29d412975aff..2edcebf67cee 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -64,7 +64,7 @@ static const char *cko2_sels[] = { "ipu2", "vdo_axi", "osc", "gpu2d_core", "gpu3d_core", "usdhc2", "ssi1", "ssi2", "ssi3", "gpu3d_shader", "vpu_axi", "can_root", - "ldb_di0", "ldb_di1", "esai", "eim_slow", + "ldb_di0", "ldb_di1", "esai_extal", "eim_slow", "uart_serial", "spdif", "asrc", "hsi_tx", }; static const char *cko_sels[] = { "cko1", "cko2", }; @@ -331,8 +331,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) else clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8); clk[IMX6QDL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10); - clk[IMX6QDL_CLK_ESAI] = imx_clk_gate2_shared("esai", "esai_podf", base + 0x6c, 16, &share_count_esai); - clk[IMX6QDL_CLK_ESAI_AHB] = imx_clk_gate2_shared("esai_ahb", "ahb", base + 0x6c, 16, &share_count_esai); + clk[IMX6QDL_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); + clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ipg", base + 0x6c, 16, &share_count_esai); + clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20); clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22); if (cpu_is_imx6dl()) diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h index 654151e24288..323e8650f198 100644 --- a/include/dt-bindings/clock/imx6qdl-clock.h +++ b/include/dt-bindings/clock/imx6qdl-clock.h @@ -128,7 +128,7 @@ #define IMX6Q_CLK_ECSPI5 116 #define IMX6DL_CLK_I2C4 116 #define IMX6QDL_CLK_ENET 117 -#define IMX6QDL_CLK_ESAI 118 +#define IMX6QDL_CLK_ESAI_EXTAL 118 #define IMX6QDL_CLK_GPT_IPG 119 #define IMX6QDL_CLK_GPT_IPG_PER 120 #define IMX6QDL_CLK_GPU2D_CORE 121 @@ -218,7 +218,8 @@ #define IMX6QDL_CLK_LVDS2_SEL 205 #define IMX6QDL_CLK_LVDS1_GATE 206 #define IMX6QDL_CLK_LVDS2_GATE 207 -#define IMX6QDL_CLK_ESAI_AHB 208 -#define IMX6QDL_CLK_END 209 +#define IMX6QDL_CLK_ESAI_IPG 208 +#define IMX6QDL_CLK_ESAI_MEM 209 +#define IMX6QDL_CLK_END 210 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ -- cgit v1.2.3-55-g7522 From e37c1ad0327af0639f6358357f60f6209f8bbad6 Mon Sep 17 00:00:00 2001 From: Fancy Fang Date: Thu, 4 Sep 2014 16:33:12 +0800 Subject: ARM: clk-imx6sl: correct the pxp and epdc axi clock selections The parent clocks of IMX6SL_CLK_PXP_AXI_SEL and IMX6SL_CLK_EPDC_AXI_SEL clocks are not the same. So split the epdc_pxp_sels into two different clock selections 'pxp_axi_sels' and 'epdc_axi_sels'. Signed-off-by: Fancy Fang Signed-off-by: Robby Cai Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6sl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index 11908e8bf9ab..f4d732661d6d 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -48,7 +48,8 @@ static const char *lcdif_axi_sels[] = { "pll2_bus", "pll2_pfd2", "pll3_usb_otg", static const char *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", }; static const char *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", }; static const char *perclk_sels[] = { "ipg", "osc", }; -static const char *epdc_pxp_sels[] = { "mmdc", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd1", }; +static const char *pxp_axi_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd3", }; +static const char *epdc_axi_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd2", }; static const char *gpu2d_ovg_sels[] = { "pll3_pfd1", "pll3_usb_otg", "pll2_bus", "pll2_pfd2", }; static const char *gpu2d_sels[] = { "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", "pll2_bus", }; static const char *lcdif_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll3_pfd0", "pll3_pfd1", }; @@ -252,8 +253,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) clks[IMX6SL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); clks[IMX6SL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); clks[IMX6SL_CLK_PERCLK_SEL] = imx_clk_fixup_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels), imx_cscmr1_fixup); - clks[IMX6SL_CLK_PXP_AXI_SEL] = imx_clk_mux("pxp_axi_sel", base + 0x34, 6, 3, epdc_pxp_sels, ARRAY_SIZE(epdc_pxp_sels)); - clks[IMX6SL_CLK_EPDC_AXI_SEL] = imx_clk_mux("epdc_axi_sel", base + 0x34, 15, 3, epdc_pxp_sels, ARRAY_SIZE(epdc_pxp_sels)); + clks[IMX6SL_CLK_PXP_AXI_SEL] = imx_clk_mux("pxp_axi_sel", base + 0x34, 6, 3, pxp_axi_sels, ARRAY_SIZE(pxp_axi_sels)); + clks[IMX6SL_CLK_EPDC_AXI_SEL] = imx_clk_mux("epdc_axi_sel", base + 0x34, 15, 3, epdc_axi_sels, ARRAY_SIZE(epdc_axi_sels)); clks[IMX6SL_CLK_GPU2D_OVG_SEL] = imx_clk_mux("gpu2d_ovg_sel", base + 0x18, 4, 2, gpu2d_ovg_sels, ARRAY_SIZE(gpu2d_ovg_sels)); clks[IMX6SL_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", base + 0x18, 8, 2, gpu2d_sels, ARRAY_SIZE(gpu2d_sels)); clks[IMX6SL_CLK_LCDIF_PIX_SEL] = imx_clk_mux("lcdif_pix_sel", base + 0x38, 6, 3, lcdif_pix_sels, ARRAY_SIZE(lcdif_pix_sels)); -- cgit v1.2.3-55-g7522 From aec247d4ac578693ee75ac2bf10eac1c29299c45 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Thu, 4 Sep 2014 17:48:58 +0800 Subject: ARM: clk-imx6q: refine clock tree for ASRC ASRC has "asrc", "asrc_ipg", "asrc_mem" clocks, and they share the same gate bits. Signed-off-by: Shengjiu Wang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 5 ++++- include/dt-bindings/clock/imx6qdl-clock.h | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 2edcebf67cee..d5bf1e2940bf 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -107,6 +107,7 @@ static struct clk_div_table video_div_table[] = { }; static unsigned int share_count_esai; +static unsigned int share_count_asrc; static void __init imx6q_clocks_init(struct device_node *ccm_node) { @@ -317,7 +318,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) /* name parent_name reg shift */ clk[IMX6QDL_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4); - clk[IMX6QDL_CLK_ASRC] = imx_clk_gate2("asrc", "asrc_podf", base + 0x68, 6); + clk[IMX6QDL_CLK_ASRC] = imx_clk_gate2_shared("asrc", "asrc_podf", base + 0x68, 6, &share_count_asrc); + clk[IMX6QDL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); + clk[IMX6QDL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); clk[IMX6QDL_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14); clk[IMX6QDL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16); clk[IMX6QDL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18); diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h index 323e8650f198..1e996135cfc7 100644 --- a/include/dt-bindings/clock/imx6qdl-clock.h +++ b/include/dt-bindings/clock/imx6qdl-clock.h @@ -220,6 +220,8 @@ #define IMX6QDL_CLK_LVDS2_GATE 207 #define IMX6QDL_CLK_ESAI_IPG 208 #define IMX6QDL_CLK_ESAI_MEM 209 -#define IMX6QDL_CLK_END 210 +#define IMX6QDL_CLK_ASRC_IPG 210 +#define IMX6QDL_CLK_ASRC_MEM 211 +#define IMX6QDL_CLK_END 212 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ -- cgit v1.2.3-55-g7522 From bd404b1d337b960c44b75fcb01e3170f1d41ae80 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Thu, 4 Sep 2014 17:48:59 +0800 Subject: ARM: clk-imx6q: refine clock tree for SSI Each SSI has "ssi", "ssi_ipg" clocks, and they share same gate bits. Signed-off-by: Shengjiu Wang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index d5bf1e2940bf..013d3cda790e 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -108,6 +108,9 @@ static struct clk_div_table video_div_table[] = { static unsigned int share_count_esai; static unsigned int share_count_asrc; +static unsigned int share_count_ssi1; +static unsigned int share_count_ssi2; +static unsigned int share_count_ssi3; static void __init imx6q_clocks_init(struct device_node *ccm_node) { @@ -392,9 +395,12 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) 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_SSI1_IPG] = imx_clk_gate2("ssi1_ipg", "ipg", base + 0x7c, 18); - clk[IMX6QDL_CLK_SSI2_IPG] = imx_clk_gate2("ssi2_ipg", "ipg", base + 0x7c, 20); - clk[IMX6QDL_CLK_SSI3_IPG] = imx_clk_gate2("ssi3_ipg", "ipg", base + 0x7c, 22); + 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); + clk[IMX6QDL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); + clk[IMX6QDL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); + clk[IMX6QDL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); clk[IMX6QDL_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24); clk[IMX6QDL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26); clk[IMX6QDL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); -- cgit v1.2.3-55-g7522 From 19d863446a6b75b2f97b3012acf67c40b9f2ea1f Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 26 Aug 2014 15:06:33 +0800 Subject: ARM: imx: add an exclusive gate clock type There are a couple of gate clocks are mutually exclusive on i.MX6, i.e. LVDSCLK1_IBEN and LVDSCLK1_OBEN. They cannot be enabled simultaneously. This patches adds an exclusive gate clock type specifically for such case. The clock driver will need to call imx_clk_gate_exclusive() to register a gate clock with parameter exclusive_mask indicating the mask of gate bits which are mutually exclusive to this gate clock. Right now, it only handles the exclusive gate clocks which are defined in a single hardware register, which is the case we're running into today. But it can be extended to handle exclusive gate clocks defined in different registers later if needed. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Makefile | 3 +- arch/arm/mach-imx/clk-gate-exclusive.c | 94 ++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/clk.h | 3 ++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-imx/clk-gate-exclusive.c (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index ef215d108e4d..6e4fcd8339cd 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -16,7 +16,8 @@ obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o $(imx5-pm-y) obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ clk-pfd.o clk-busy.o clk.o \ - clk-fixup-div.o clk-fixup-mux.o + clk-fixup-div.o clk-fixup-mux.o \ + clk-gate-exclusive.o obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o diff --git a/arch/arm/mach-imx/clk-gate-exclusive.c b/arch/arm/mach-imx/clk-gate-exclusive.c new file mode 100644 index 000000000000..c12f5f2e04dc --- /dev/null +++ b/arch/arm/mach-imx/clk-gate-exclusive.c @@ -0,0 +1,94 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include "clk.h" + +/** + * struct clk_gate_exclusive - i.MX specific gate clock which is mutually + * exclusive with other gate clocks + * + * @gate: the parent class + * @exclusive_mask: mask of gate bits which are mutually exclusive to this + * gate clock + * + * The imx exclusive gate clock is a subclass of basic clk_gate + * with an addtional mask to indicate which other gate bits in the same + * register is mutually exclusive to this gate clock. + */ +struct clk_gate_exclusive { + struct clk_gate gate; + u32 exclusive_mask; +}; + +static int clk_gate_exclusive_enable(struct clk_hw *hw) +{ + struct clk_gate *gate = container_of(hw, struct clk_gate, hw); + struct clk_gate_exclusive *exgate = container_of(gate, + struct clk_gate_exclusive, gate); + u32 val = readl(gate->reg); + + if (val & exgate->exclusive_mask) + return -EBUSY; + + return clk_gate_ops.enable(hw); +} + +static void clk_gate_exclusive_disable(struct clk_hw *hw) +{ + clk_gate_ops.disable(hw); +} + +static int clk_gate_exclusive_is_enabled(struct clk_hw *hw) +{ + return clk_gate_ops.is_enabled(hw); +} + +static const struct clk_ops clk_gate_exclusive_ops = { + .enable = clk_gate_exclusive_enable, + .disable = clk_gate_exclusive_disable, + .is_enabled = clk_gate_exclusive_is_enabled, +}; + +struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, + void __iomem *reg, u8 shift, u32 exclusive_mask) +{ + struct clk_gate_exclusive *exgate; + struct clk_gate *gate; + struct clk *clk; + struct clk_init_data init; + + if (exclusive_mask == 0) + return ERR_PTR(-EINVAL); + + exgate = kzalloc(sizeof(*exgate), GFP_KERNEL); + if (!exgate) + return ERR_PTR(-ENOMEM); + gate = &exgate->gate; + + init.name = name; + init.ops = &clk_gate_exclusive_ops; + init.flags = CLK_SET_RATE_PARENT; + init.parent_names = parent ? &parent : NULL; + init.num_parents = parent ? 1 : 0; + + gate->reg = reg; + gate->bit_idx = shift; + gate->lock = &imx_ccm_lock; + gate->hw.init = &init; + exgate->exclusive_mask = exclusive_mask; + + clk = clk_register(NULL, &gate->hw); + if (IS_ERR(clk)) + kfree(exgate); + + return clk; +} diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h index d5ba76fee115..4cdf8b6a74e8 100644 --- a/arch/arm/mach-imx/clk.h +++ b/arch/arm/mach-imx/clk.h @@ -36,6 +36,9 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, struct clk * imx_obtain_fixed_clock( const char *name, unsigned long rate); +struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, + void __iomem *reg, u8 shift, u32 exclusive_mask); + static inline struct clk *imx_clk_gate2(const char *name, const char *parent, void __iomem *reg, u8 shift) { -- cgit v1.2.3-55-g7522 From b1f156db47ae914a308488ce28e84f3d4ad4f667 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 1 Sep 2014 14:17:48 +0800 Subject: ARM: imx6q: add BYPASS support for PLL clocks The imx6q clock driver currently hard-codes all PLL clocks to source from OSC24M without BYPASS support. The patch adds the missing lvds_in clock which is mutually exclusive with lvds_gate, and implements BYPASS and BYPASS_CLK_SRC selection for PLL clocks as per Figure 10-3. Primary Clock Generation in IMX6DQRM, i.e. both BYPASS_CLK_SRC and BYPASS bits are implemented as mux clocks, and ENABLE bit of PLL clocks is implemented as a gate clock after BYPASS mux. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 67 ++++++++++++++++++++++++++----- include/dt-bindings/clock/imx6qdl-clock.h | 27 ++++++++++++- 2 files changed, 83 insertions(+), 11 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 013d3cda790e..4ee6e77a0fdf 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -73,6 +73,14 @@ static const char *lvds_sels[] = { "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref", "pcie_ref_125m", "sata_ref_100m", }; +static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", }; +static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; +static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", }; +static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", }; +static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", }; +static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; +static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; +static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; static struct clk *clk[IMX6QDL_CLK_END]; static struct clk_onecell_data clk_data; @@ -123,6 +131,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0); clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); + /* Clock source from external clock via CLK1/2 PADs */ + clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); + clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0); np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); base = of_iomap(np, 0); @@ -136,14 +147,47 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) video_div_table[2].div = 1; }; - /* type name parent_name base div_mask */ - clk[IMX6QDL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f); - clk[IMX6QDL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1); - clk[IMX6QDL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3); - clk[IMX6QDL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f); - clk[IMX6QDL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f); - clk[IMX6QDL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3); - clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3); + clk[IMX6QDL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clk[IMX6QDL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clk[IMX6QDL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clk[IMX6QDL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clk[IMX6QDL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clk[IMX6QDL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clk[IMX6QDL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + + /* type name parent_name base div_mask */ + clk[IMX6QDL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f); + clk[IMX6QDL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1); + clk[IMX6QDL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3); + clk[IMX6QDL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f); + clk[IMX6QDL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f); + clk[IMX6QDL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3); + clk[IMX6QDL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3); + + clk[IMX6QDL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); + + /* Do not bypass PLLs initially */ + clk_set_parent(clk[IMX6QDL_PLL1_BYPASS], clk[IMX6QDL_CLK_PLL1]); + clk_set_parent(clk[IMX6QDL_PLL2_BYPASS], clk[IMX6QDL_CLK_PLL2]); + clk_set_parent(clk[IMX6QDL_PLL3_BYPASS], clk[IMX6QDL_CLK_PLL3]); + clk_set_parent(clk[IMX6QDL_PLL4_BYPASS], clk[IMX6QDL_CLK_PLL4]); + clk_set_parent(clk[IMX6QDL_PLL5_BYPASS], clk[IMX6QDL_CLK_PLL5]); + clk_set_parent(clk[IMX6QDL_PLL6_BYPASS], clk[IMX6QDL_CLK_PLL6]); + clk_set_parent(clk[IMX6QDL_PLL7_BYPASS], clk[IMX6QDL_CLK_PLL7]); + + clk[IMX6QDL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); + clk[IMX6QDL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); + clk[IMX6QDL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); + clk[IMX6QDL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); + clk[IMX6QDL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); + clk[IMX6QDL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); + clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0xe0, 13); /* * Bit 20 is the reserved and read-only bit, we do this only for: @@ -180,8 +224,11 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) * the "output_enable" bit as a gate, even though it's really just * enabling clock output. */ - clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate("lvds1_gate", "lvds1_sel", base + 0x160, 10); - clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate("lvds2_gate", "lvds2_sel", base + 0x160, 11); + clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12)); + clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13)); + + clk[IMX6QDL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); + clk[IMX6QDL_CLK_LVDS2_IN] = imx_clk_gate_exclusive("lvds2_in", "anaclk2", base + 0x160, 13, BIT(11)); /* name parent_name reg idx */ clk[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h index 1e996135cfc7..c0d88ab013b4 100644 --- a/include/dt-bindings/clock/imx6qdl-clock.h +++ b/include/dt-bindings/clock/imx6qdl-clock.h @@ -222,6 +222,31 @@ #define IMX6QDL_CLK_ESAI_MEM 209 #define IMX6QDL_CLK_ASRC_IPG 210 #define IMX6QDL_CLK_ASRC_MEM 211 -#define IMX6QDL_CLK_END 212 +#define IMX6QDL_CLK_LVDS1_IN 212 +#define IMX6QDL_CLK_LVDS2_IN 213 +#define IMX6QDL_CLK_ANACLK1 214 +#define IMX6QDL_CLK_ANACLK2 215 +#define IMX6QDL_PLL1_BYPASS_SRC 216 +#define IMX6QDL_PLL2_BYPASS_SRC 217 +#define IMX6QDL_PLL3_BYPASS_SRC 218 +#define IMX6QDL_PLL4_BYPASS_SRC 219 +#define IMX6QDL_PLL5_BYPASS_SRC 220 +#define IMX6QDL_PLL6_BYPASS_SRC 221 +#define IMX6QDL_PLL7_BYPASS_SRC 222 +#define IMX6QDL_CLK_PLL1 223 +#define IMX6QDL_CLK_PLL2 224 +#define IMX6QDL_CLK_PLL3 225 +#define IMX6QDL_CLK_PLL4 226 +#define IMX6QDL_CLK_PLL5 227 +#define IMX6QDL_CLK_PLL6 228 +#define IMX6QDL_CLK_PLL7 229 +#define IMX6QDL_PLL1_BYPASS 230 +#define IMX6QDL_PLL2_BYPASS 231 +#define IMX6QDL_PLL3_BYPASS 232 +#define IMX6QDL_PLL4_BYPASS 233 +#define IMX6QDL_PLL5_BYPASS 234 +#define IMX6QDL_PLL6_BYPASS 235 +#define IMX6QDL_PLL7_BYPASS 236 +#define IMX6QDL_CLK_END 237 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ -- cgit v1.2.3-55-g7522 From e90f41990dce3557e345410ef33b0a47e8cb49fc Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 1 Sep 2014 14:29:53 +0800 Subject: ARM: imx6sl: add BYPASS support for PLL clocks This is the same change for imx6sl clock driver as "ARM: imx6q: add BYPASS support for PLL clocks" for imx6q. The difference is that only anaclk1 is available on imx6sl. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6sl.c | 69 ++++++++++++++++++++++++++++---- include/dt-bindings/clock/imx6sl-clock.h | 27 ++++++++++++- 2 files changed, 87 insertions(+), 9 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index f4d732661d6d..6791ff3e8914 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -57,6 +57,20 @@ static const char *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_d static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", }; static const char *ecspi_sels[] = { "pll3_60m", "osc", }; static const char *uart_sels[] = { "pll3_80m", "osc", }; +static const char *lvds_sels[] = { + "pll1_sys", "pll2_bus", "pll2_pfd0", "pll2_pfd1", "pll2_pfd2", "dummy", "pll4_audio", "pll5_video", + "dummy", "enet_ref", "dummy", "dummy", "pll3_usb_otg", "pll7_usb_host", "pll3_pfd0", "pll3_pfd1", + "pll3_pfd2", "pll3_pfd3", "osc", "dummy", "dummy", "dummy", "dummy", "dummy", + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", +}; +static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", }; +static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; +static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", }; +static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", }; +static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", }; +static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; +static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; +static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; static struct clk_div_table clk_enet_ref_table[] = { { .val = 0, .div = 20, }, @@ -177,20 +191,59 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); clks[IMX6SL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); + /* Clock source from external clock via CLK1 PAD */ + clks[IMX6SL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop"); base = of_iomap(np, 0); WARN_ON(!base); anatop_base = base; - /* type name parent base div_mask */ - clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f); - clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1); - clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3); - clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f); - clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f); - clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3); - clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3); + clks[IMX6SL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + + /* type name parent_name base div_mask */ + clks[IMX6SL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f); + clks[IMX6SL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1); + clks[IMX6SL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3); + clks[IMX6SL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f); + clks[IMX6SL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f); + clks[IMX6SL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3); + clks[IMX6SL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3); + + clks[IMX6SL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); + + /* Do not bypass PLLs initially */ + clk_set_parent(clks[IMX6SL_PLL1_BYPASS], clks[IMX6SL_CLK_PLL1]); + clk_set_parent(clks[IMX6SL_PLL2_BYPASS], clks[IMX6SL_CLK_PLL2]); + clk_set_parent(clks[IMX6SL_PLL3_BYPASS], clks[IMX6SL_CLK_PLL3]); + clk_set_parent(clks[IMX6SL_PLL4_BYPASS], clks[IMX6SL_CLK_PLL4]); + clk_set_parent(clks[IMX6SL_PLL5_BYPASS], clks[IMX6SL_CLK_PLL5]); + clk_set_parent(clks[IMX6SL_PLL6_BYPASS], clks[IMX6SL_CLK_PLL6]); + clk_set_parent(clks[IMX6SL_PLL7_BYPASS], clks[IMX6SL_CLK_PLL7]); + + clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); + clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); + clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); + clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); + clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); + clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); + clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0xe0, 13); + + clks[IMX6SL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); + clks[IMX6SL_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12)); + clks[IMX6SL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); /* * usbphy1 and usbphy2 are implemented as dummy gates using reserve diff --git a/include/dt-bindings/clock/imx6sl-clock.h b/include/dt-bindings/clock/imx6sl-clock.h index b91dd462ba85..f10a928fe2dd 100644 --- a/include/dt-bindings/clock/imx6sl-clock.h +++ b/include/dt-bindings/clock/imx6sl-clock.h @@ -146,6 +146,31 @@ #define IMX6SL_CLK_PLL4_AUDIO_DIV 133 #define IMX6SL_CLK_SPBA 134 #define IMX6SL_CLK_ENET 135 -#define IMX6SL_CLK_END 136 +#define IMX6SL_CLK_LVDS1_SEL 136 +#define IMX6SL_CLK_LVDS1_OUT 137 +#define IMX6SL_CLK_LVDS1_IN 138 +#define IMX6SL_CLK_ANACLK1 139 +#define IMX6SL_PLL1_BYPASS_SRC 140 +#define IMX6SL_PLL2_BYPASS_SRC 141 +#define IMX6SL_PLL3_BYPASS_SRC 142 +#define IMX6SL_PLL4_BYPASS_SRC 143 +#define IMX6SL_PLL5_BYPASS_SRC 144 +#define IMX6SL_PLL6_BYPASS_SRC 145 +#define IMX6SL_PLL7_BYPASS_SRC 146 +#define IMX6SL_CLK_PLL1 147 +#define IMX6SL_CLK_PLL2 148 +#define IMX6SL_CLK_PLL3 149 +#define IMX6SL_CLK_PLL4 150 +#define IMX6SL_CLK_PLL5 151 +#define IMX6SL_CLK_PLL6 152 +#define IMX6SL_CLK_PLL7 153 +#define IMX6SL_PLL1_BYPASS 154 +#define IMX6SL_PLL2_BYPASS 155 +#define IMX6SL_PLL3_BYPASS 156 +#define IMX6SL_PLL4_BYPASS 157 +#define IMX6SL_PLL5_BYPASS 158 +#define IMX6SL_PLL6_BYPASS 159 +#define IMX6SL_PLL7_BYPASS 160 +#define IMX6SL_CLK_END 161 #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */ -- cgit v1.2.3-55-g7522 From db7c0659452c5f490ea5048390ad94de786f4b85 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 1 Sep 2014 15:15:57 +0800 Subject: ARM: imx6sx: add BYPASS support for PLL clocks This is the same change for imx6sx clock driver as "ARM: imx6q: add BYPASS support for PLL clocks" for imx6q. The difference is that only anaclk1 is available on imx6sx. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6sx.c | 63 +++++++++++++++++++++++++++----- include/dt-bindings/clock/imx6sx-clock.h | 25 ++++++++++++- 2 files changed, 78 insertions(+), 10 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c index ecde72bdfe88..27070a716935 100644 --- a/arch/arm/mach-imx/clk-imx6sx.c +++ b/arch/arm/mach-imx/clk-imx6sx.c @@ -81,6 +81,14 @@ static const char *lvds_sels[] = { "arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div", "dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2", }; +static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", }; +static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; +static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", }; +static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", }; +static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", }; +static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; +static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; +static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; static struct clk *clks[IMX6SX_CLK_CLK_END]; static struct clk_onecell_data clk_data; @@ -143,18 +151,54 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clks[IMX6SX_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0"); clks[IMX6SX_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1"); + /* Clock source from external clock via CLK1 PAD */ + clks[IMX6SX_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); + np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop"); base = of_iomap(np, 0); WARN_ON(!base); - /* type name parent_name base div_mask */ - clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f); - clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1); - clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3); - clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f); - clks[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f); - clks[IMX6SX_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3); - clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3); + clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); + + /* type name parent_name base div_mask */ + clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f); + clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1); + clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3); + clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f); + clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f); + clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3); + clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3); + + clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SX_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SX_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SX_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SX_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); + + /* Do not bypass PLLs initially */ + clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]); + clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]); + clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]); + clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]); + clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]); + clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]); + clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]); + + clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); + clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); + clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); + clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); + clks[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); + clks[IMX6SX_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); + clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0xe0, 13); /* * Bit 20 is the reserved and read-only bit, we do this only for: @@ -176,7 +220,8 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5); clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19); - clks[IMX6SX_CLK_LVDS1_OUT] = imx_clk_gate("lvds1_out", "lvds1_sel", base + 0x160, 10); + clks[IMX6SX_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12)); + clks[IMX6SX_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); clks[IMX6SX_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, base + 0xe0, 0, 2, 0, clk_enet_ref_table, diff --git a/include/dt-bindings/clock/imx6sx-clock.h b/include/dt-bindings/clock/imx6sx-clock.h index 421d8bb76f2f..995709119ec5 100644 --- a/include/dt-bindings/clock/imx6sx-clock.h +++ b/include/dt-bindings/clock/imx6sx-clock.h @@ -251,6 +251,29 @@ #define IMX6SX_CLK_SAI2_IPG 238 #define IMX6SX_CLK_ESAI_IPG 239 #define IMX6SX_CLK_ESAI_MEM 240 -#define IMX6SX_CLK_CLK_END 241 +#define IMX6SX_CLK_LVDS1_IN 241 +#define IMX6SX_CLK_ANACLK1 242 +#define IMX6SX_PLL1_BYPASS_SRC 243 +#define IMX6SX_PLL2_BYPASS_SRC 244 +#define IMX6SX_PLL3_BYPASS_SRC 245 +#define IMX6SX_PLL4_BYPASS_SRC 246 +#define IMX6SX_PLL5_BYPASS_SRC 247 +#define IMX6SX_PLL6_BYPASS_SRC 248 +#define IMX6SX_PLL7_BYPASS_SRC 249 +#define IMX6SX_CLK_PLL1 250 +#define IMX6SX_CLK_PLL2 251 +#define IMX6SX_CLK_PLL3 252 +#define IMX6SX_CLK_PLL4 253 +#define IMX6SX_CLK_PLL5 254 +#define IMX6SX_CLK_PLL6 255 +#define IMX6SX_CLK_PLL7 256 +#define IMX6SX_PLL1_BYPASS 257 +#define IMX6SX_PLL2_BYPASS 258 +#define IMX6SX_PLL3_BYPASS 259 +#define IMX6SX_PLL4_BYPASS 260 +#define IMX6SX_PLL5_BYPASS 261 +#define IMX6SX_PLL6_BYPASS 262 +#define IMX6SX_PLL7_BYPASS 263 +#define IMX6SX_CLK_CLK_END 264 #endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */ -- cgit v1.2.3-55-g7522 From dc4805c2e78ba5a22ea1632f3e3e4ee601a1743b Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 26 Aug 2014 23:06:33 +0800 Subject: ARM: imx: remove ENABLE and BYPASS bits from clk-pllv3 driver Since ENABLE and BYPASS bits of PLLs are now implemented as separate gate and mux clocks by clock drivers, the code handling these two bits can be removed from clk-pllv3 driver. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-pllv3.c | 37 ------------------------------------- 1 file changed, 37 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c index 61364050fccd..57de74da0acf 100644 --- a/arch/arm/mach-imx/clk-pllv3.c +++ b/arch/arm/mach-imx/clk-pllv3.c @@ -23,8 +23,6 @@ #define PLL_DENOM_OFFSET 0x20 #define BM_PLL_POWER (0x1 << 12) -#define BM_PLL_ENABLE (0x1 << 13) -#define BM_PLL_BYPASS (0x1 << 16) #define BM_PLL_LOCK (0x1 << 31) /** @@ -84,10 +82,6 @@ static int clk_pllv3_prepare(struct clk_hw *hw) if (ret) return ret; - val = readl_relaxed(pll->base); - val &= ~BM_PLL_BYPASS; - writel_relaxed(val, pll->base); - return 0; } @@ -97,7 +91,6 @@ static void clk_pllv3_unprepare(struct clk_hw *hw) u32 val; val = readl_relaxed(pll->base); - val |= BM_PLL_BYPASS; if (pll->powerup_set) val &= ~BM_PLL_POWER; else @@ -105,28 +98,6 @@ static void clk_pllv3_unprepare(struct clk_hw *hw) writel_relaxed(val, pll->base); } -static int clk_pllv3_enable(struct clk_hw *hw) -{ - struct clk_pllv3 *pll = to_clk_pllv3(hw); - u32 val; - - val = readl_relaxed(pll->base); - val |= BM_PLL_ENABLE; - writel_relaxed(val, pll->base); - - return 0; -} - -static void clk_pllv3_disable(struct clk_hw *hw) -{ - struct clk_pllv3 *pll = to_clk_pllv3(hw); - u32 val; - - val = readl_relaxed(pll->base); - val &= ~BM_PLL_ENABLE; - writel_relaxed(val, pll->base); -} - static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -169,8 +140,6 @@ 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, - .enable = clk_pllv3_enable, - .disable = clk_pllv3_disable, .recalc_rate = clk_pllv3_recalc_rate, .round_rate = clk_pllv3_round_rate, .set_rate = clk_pllv3_set_rate, @@ -225,8 +194,6 @@ 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, - .enable = clk_pllv3_enable, - .disable = clk_pllv3_disable, .recalc_rate = clk_pllv3_sys_recalc_rate, .round_rate = clk_pllv3_sys_round_rate, .set_rate = clk_pllv3_sys_set_rate, @@ -299,8 +266,6 @@ 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, - .enable = clk_pllv3_enable, - .disable = clk_pllv3_disable, .recalc_rate = clk_pllv3_av_recalc_rate, .round_rate = clk_pllv3_av_round_rate, .set_rate = clk_pllv3_av_set_rate, @@ -315,8 +280,6 @@ 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, - .enable = clk_pllv3_enable, - .disable = clk_pllv3_disable, .recalc_rate = clk_pllv3_enet_recalc_rate, }; -- cgit v1.2.3-55-g7522 From dbaf381ffbf3acd4ac9a987f567a2b1a5edf6e62 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 9 Sep 2014 17:13:25 +0800 Subject: ARM: clk-imx6sl: refine clock tree for SSI Each SSI has "ssi", "ssi_ipg" clocks, and they share same gate bits. Signed-off-by: Shengjiu Wang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6sl.c | 13 ++++++++++--- include/dt-bindings/clock/imx6sl-clock.h | 5 ++++- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index 6791ff3e8914..c8de87bc617f 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -95,6 +95,10 @@ 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 struct clk *clks[IMX6SL_CLK_END]; static struct clk_onecell_data clk_data; static void __iomem *ccm_base; @@ -392,9 +396,12 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) 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_SSI1] = imx_clk_gate2("ssi1", "ssi1_podf", base + 0x7c, 18); - clks[IMX6SL_CLK_SSI2] = imx_clk_gate2("ssi2", "ssi2_podf", base + 0x7c, 20); - clks[IMX6SL_CLK_SSI3] = imx_clk_gate2("ssi3", "ssi3_podf", base + 0x7c, 22); + 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); + clks[IMX6SL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); + clks[IMX6SL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); + clks[IMX6SL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); clks[IMX6SL_CLK_UART] = imx_clk_gate2("uart", "ipg", base + 0x7c, 24); clks[IMX6SL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_root", base + 0x7c, 26); clks[IMX6SL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); diff --git a/include/dt-bindings/clock/imx6sl-clock.h b/include/dt-bindings/clock/imx6sl-clock.h index f10a928fe2dd..9ce4e421096f 100644 --- a/include/dt-bindings/clock/imx6sl-clock.h +++ b/include/dt-bindings/clock/imx6sl-clock.h @@ -171,6 +171,9 @@ #define IMX6SL_PLL5_BYPASS 158 #define IMX6SL_PLL6_BYPASS 159 #define IMX6SL_PLL7_BYPASS 160 -#define IMX6SL_CLK_END 161 +#define IMX6SL_CLK_SSI1_IPG 161 +#define IMX6SL_CLK_SSI2_IPG 162 +#define IMX6SL_CLK_SSI3_IPG 163 +#define IMX6SL_CLK_END 164 #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */ -- cgit v1.2.3-55-g7522 From 69d9a3fe06ed4bdb69f0a20cfa031dbcb0ee8dc3 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 12 Sep 2014 10:40:28 +0800 Subject: ARM: imx: fix register offset of pll7_usb_host gate clock There is a copy&paste error on register offset of pll7_usb_host gate clock introduced by i.MX6 PLL bypass support patches. The error breaks the ENET function, because it overwrites the pll6_enet gate bit. Correct the offset for all i.MX6 clock drivers. Thanks to Fugang Duan for spotting the error. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 2 +- arch/arm/mach-imx/clk-imx6sl.c | 2 +- arch/arm/mach-imx/clk-imx6sx.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 4ee6e77a0fdf..4f8ce60a2e90 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -187,7 +187,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); clk[IMX6QDL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); clk[IMX6QDL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); - clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0xe0, 13); + clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); /* * Bit 20 is the reserved and read-only bit, we do this only for: diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index c8de87bc617f..e982ebe10814 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -243,7 +243,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); - clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0xe0, 13); + clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); clks[IMX6SL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); clks[IMX6SL_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12)); diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c index 27070a716935..17354a11356f 100644 --- a/arch/arm/mach-imx/clk-imx6sx.c +++ b/arch/arm/mach-imx/clk-imx6sx.c @@ -198,7 +198,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); clks[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); clks[IMX6SX_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); - clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0xe0, 13); + clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); /* * Bit 20 is the reserved and read-only bit, we do this only for: -- cgit v1.2.3-55-g7522 From 6f11c69d35d5b1db0ec4cfccd0188b00eada3ad3 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 11 Sep 2014 11:29:40 +0800 Subject: ARM: imx: add gpt_3m clk for i.mx6qdl Add gpt_3m clock for i.mx6qdl, as gpt can source clock from OSC, some i.MX6 series SOCs has fixed divider of 8 for gpt clock, so here add a fix clk of gpt_3m. i.MX6Q TO1.0 has no gpt_3m option, so force it to be from ipg_per. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 8 ++++++++ include/dt-bindings/clock/imx6qdl-clock.h | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 4f8ce60a2e90..1412daf4a714 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -245,6 +245,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); clk[IMX6QDL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2); + clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); if (cpu_is_imx6dl()) { clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1); clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1); @@ -461,6 +462,13 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7); clk[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24); + /* + * The gpt_3m clock is not available on i.MX6Q TO1.0. Let's point it + * to clock gpt_ipg_per to ease the gpt driver code. + */ + if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) + clk[IMX6QDL_CLK_GPT_3M] = clk[IMX6QDL_CLK_GPT_IPG_PER]; + imx_check_clocks(clk, ARRAY_SIZE(clk)); clk_data.clks = clk; diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h index c0d88ab013b4..ddaef8620b2c 100644 --- a/include/dt-bindings/clock/imx6qdl-clock.h +++ b/include/dt-bindings/clock/imx6qdl-clock.h @@ -247,6 +247,7 @@ #define IMX6QDL_PLL5_BYPASS 234 #define IMX6QDL_PLL6_BYPASS 235 #define IMX6QDL_PLL7_BYPASS 236 -#define IMX6QDL_CLK_END 237 +#define IMX6QDL_CLK_GPT_3M 237 +#define IMX6QDL_CLK_END 238 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ -- cgit v1.2.3-55-g7522 From bad3db104f8922df2c84fd7653cfbcbc93cd0cb7 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 11 Sep 2014 11:29:42 +0800 Subject: ARM: imx: source gpt per clk from OSC for system timer On i.MX6Q TO > 1.0, i.MX6DL and i.MX6SX, gpt per clock can be from OSC instead of ipg_per, as ipg_per's rate may be scaled when system enter low bus mode, to keep system timer NOT drift, better to make gpt per clock at fixed rate, here add support for gpt per clock to be from OSC which is at fixed rate always. There are some difference on this implementation of gpt per clock source, see below for details: i.MX6Q TO > 1.0: GPT_CR_CLKSRC, b'101 selects fix clock of OSC / 8 for gpt per clk; i.MX6DL and i.MX6SX: GPT_CR_CLKSRC, b'101 selects OSC for gpt per clk, and we must enable GPT_CR_24MEM to enable OSC clk source for gpt per, GPT_PR_PRESCALER24M is for pre-scaling of this OSC clk, here set it to 8 to make gpt per clk is 3MHz; i.MX6SL: ipg_per can be from OSC directly, so no need to implement this new clk source for gpt per. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/time.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index bf92e5a351c0..15d18e198303 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -60,17 +60,22 @@ #define MX2_TSTAT_CAPT (1 << 1) #define MX2_TSTAT_COMP (1 << 0) -/* MX31, MX35, MX25, MX5 */ +/* MX31, MX35, MX25, MX5, MX6 */ #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */ #define V2_TCTL_CLK_IPG (1 << 6) #define V2_TCTL_CLK_PER (2 << 6) +#define V2_TCTL_CLK_OSC_DIV8 (5 << 6) #define V2_TCTL_FRR (1 << 9) +#define V2_TCTL_24MEN (1 << 10) +#define V2_TPRER_PRE24M 12 #define V2_IR 0x0c #define V2_TSTAT 0x08 #define V2_TSTAT_OF1 (1 << 0) #define V2_TCN 0x24 #define V2_TCMP 0x10 +#define V2_TIMER_RATE_OSC_DIV8 3000000 + #define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) #define timer_is_v2() (!timer_is_v1()) @@ -312,10 +317,22 @@ static void __init _mxc_timer_init(int irq, __raw_writel(0, timer_base + MXC_TCTL); __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ - if (timer_is_v2()) - tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; - else + if (timer_is_v2()) { + tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; + if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) { + tctl_val |= V2_TCTL_CLK_OSC_DIV8; + if (cpu_is_imx6dl() || cpu_is_imx6sx()) { + /* 24 / 8 = 3 MHz */ + __raw_writel(7 << V2_TPRER_PRE24M, + timer_base + MXC_TPRER); + tctl_val |= V2_TCTL_24MEN; + } + } else { + tctl_val |= V2_TCTL_CLK_PER; + } + } else { tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; + } __raw_writel(tctl_val, timer_base + MXC_TCTL); @@ -349,9 +366,13 @@ static void __init mxc_timer_init_dt(struct device_node *np) WARN_ON(!timer_base); irq = irq_of_parse_and_map(np, 0); - clk_per = of_clk_get_by_name(np, "per"); clk_ipg = of_clk_get_by_name(np, "ipg"); + /* Try osc_per first, and fall back to per otherwise */ + clk_per = of_clk_get_by_name(np, "osc_per"); + if (IS_ERR(clk_per)) + clk_per = of_clk_get_by_name(np, "per"); + _mxc_timer_init(irq, clk_per, clk_ipg); } CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt); -- cgit v1.2.3-55-g7522 From 75fd32b8ef68adf273c233b34c6b898780d290f2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 13 Sep 2014 11:31:15 -0700 Subject: arm: mach-imx: Convert pr_warning to pr_warn Use the more common pr_warn. Signed-off-by: Joe Perches Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-armadillo5x0.c | 2 +- arch/arm/mach-imx/mach-mx31_3ds.c | 4 ++-- arch/arm/mach-imx/mach-mx31lite.c | 2 +- arch/arm/mach-imx/mach-pcm037.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-imx') diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index a7e9bd26a552..f2060523ba48 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c @@ -537,7 +537,7 @@ static void __init armadillo5x0_init(void) gpio_free(ARMADILLO5X0_RTC_GPIO); } if (armadillo5x0_i2c_rtc.irq == 0) - pr_warning("armadillo5x0_init: failed to get RTC IRQ\n"); + pr_warn("armadillo5x0_init: failed to get RTC IRQ\n"); i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1); /* USB */ diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c index 453f41a2c5a9..65a0dc06a97c 100644 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ b/arch/arm/mach-imx/mach-mx31_3ds.c @@ -307,7 +307,7 @@ static int mx31_3ds_sdhc1_init(struct device *dev, ret = gpio_request_array(mx31_3ds_sdhc1_gpios, ARRAY_SIZE(mx31_3ds_sdhc1_gpios)); if (ret) { - pr_warning("Unable to request the SD/MMC GPIOs.\n"); + pr_warn("Unable to request the SD/MMC GPIOs.\n"); return ret; } @@ -316,7 +316,7 @@ static int mx31_3ds_sdhc1_init(struct device *dev, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "sdhc1-detect", data); if (ret) { - pr_warning("Unable to request the SD/MMC card-detect IRQ.\n"); + pr_warn("Unable to request the SD/MMC card-detect IRQ.\n"); goto gpio_free; } diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c index 57eac6f45fab..4822a1738de4 100644 --- a/arch/arm/mach-imx/mach-mx31lite.c +++ b/arch/arm/mach-imx/mach-mx31lite.c @@ -270,7 +270,7 @@ static void __init mx31lite_init(void) /* SMSC9117 IRQ pin */ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq"); if (ret) - pr_warning("could not get LAN irq gpio\n"); + pr_warn("could not get LAN irq gpio\n"); else { gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_SFS6)); smsc911x_resources[1].start = diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c index 8eb1570f7851..6d879417db49 100644 --- a/arch/arm/mach-imx/mach-pcm037.c +++ b/arch/arm/mach-imx/mach-pcm037.c @@ -58,7 +58,7 @@ static int __init pcm037_variant_setup(char *str) if (!strcmp("eet", str)) pcm037_instance = PCM037_EET; else if (strcmp("pcm970", str)) - pr_warning("Unknown pcm037 baseboard variant %s\n", str); + pr_warn("Unknown pcm037 baseboard variant %s\n", str); return 1; } @@ -624,7 +624,7 @@ static void __init pcm037_init(void) /* LAN9217 IRQ pin */ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1), "lan9217-irq"); if (ret) - pr_warning("could not get LAN irq gpio\n"); + pr_warn("could not get LAN irq gpio\n"); else { gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)); smsc911x_resources[1].start = -- cgit v1.2.3-55-g7522