All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] ARM: imx6: add BYPASS support for PLLs
@ 2014-09-01  8:13 Shawn Guo
  2014-09-01  8:14 ` [PATCH v2 1/5] ARM: imx: add an exclusive gate clock type Shawn Guo
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Shawn Guo @ 2014-09-01  8:13 UTC (permalink / raw)
  To: linux-arm-kernel

Motivated by an ESAI audio use case on imx6q-sabreauto board, where an
on-board oscillator provides master clock to ESAI controller via path
anatop CLK pad --> PLL_AUDIO --> ESAI.  This is not possible with the
current clock driver implementation, where clock source of PLLs is
hard-coded to be OSC24M.

The patch series adds the missing anaclk related clocks and implements
BYPASS support for i.MX6 clock drivers per Figure 10-3. Primary Clock
Generation in IMX6DQRM.

Changes since v1 (RFC):
 - Combine the exclusive gate patch series with this one
 - Add patches for imx6sl and imx6sx PLL BYPASS support

Shawn Guo (5):
  ARM: imx: add an exclusive gate clock type
  ARM: imx6q: add BYPASS support for PLL clocks
  ARM: imx6sl: add BYPASS support for PLL clocks
  ARM: imx6sx: add BYPASS support for PLL clocks
  ARM: imx: remove ENABLE and BYPASS bits from clk-pllv3 driver

 arch/arm/mach-imx/Makefile                |  3 +-
 arch/arm/mach-imx/clk-gate-exclusive.c    | 94 +++++++++++++++++++++++++++++++
 arch/arm/mach-imx/clk-imx6q.c             | 67 ++++++++++++++++++----
 arch/arm/mach-imx/clk-imx6sl.c            | 69 ++++++++++++++++++++---
 arch/arm/mach-imx/clk-imx6sx.c            | 63 ++++++++++++++++++---
 arch/arm/mach-imx/clk-pllv3.c             | 37 ------------
 arch/arm/mach-imx/clk.h                   |  3 +
 include/dt-bindings/clock/imx6qdl-clock.h | 27 ++++++++-
 include/dt-bindings/clock/imx6sl-clock.h  | 27 ++++++++-
 include/dt-bindings/clock/imx6sx-clock.h  | 25 +++++++-
 10 files changed, 347 insertions(+), 68 deletions(-)
 create mode 100644 arch/arm/mach-imx/clk-gate-exclusive.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/5] ARM: imx: add an exclusive gate clock type
  2014-09-01  8:13 [PATCH v2 0/5] ARM: imx6: add BYPASS support for PLLs Shawn Guo
@ 2014-09-01  8:14 ` Shawn Guo
  2014-09-01  8:14 ` [PATCH v2 2/5] ARM: imx6q: add BYPASS support for PLL clocks Shawn Guo
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Shawn Guo @ 2014-09-01  8:14 UTC (permalink / raw)
  To: linux-arm-kernel

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 <shawn.guo@freescale.com>
---
 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

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 9f1c359566bb..3e6476b6a698 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 <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#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)
 {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/5] ARM: imx6q: add BYPASS support for PLL clocks
  2014-09-01  8:13 [PATCH v2 0/5] ARM: imx6: add BYPASS support for PLLs Shawn Guo
  2014-09-01  8:14 ` [PATCH v2 1/5] ARM: imx: add an exclusive gate clock type Shawn Guo
@ 2014-09-01  8:14 ` Shawn Guo
  2014-09-01  8:14 ` [PATCH v2 3/5] ARM: imx6sl: " Shawn Guo
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Shawn Guo @ 2014-09-01  8:14 UTC (permalink / raw)
  To: linux-arm-kernel

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 <shawn.guo@freescale.com>
---
 arch/arm/mach-imx/clk-imx6q.c             | 67 ++++++++++++++++++++++++++-----
 include/dt-bindings/clock/imx6qdl-clock.h | 27 ++++++++++++-
 2 files changed, 83 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 2edcebf67cee..b5e18082426c 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;
@@ -119,6 +127,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);
@@ -132,14 +143,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:
@@ -176,8 +220,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 323e8650f198..361afd09c2b7 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -220,6 +220,31 @@
 #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_LVDS1_IN			210
+#define IMX6QDL_CLK_LVDS2_IN			211
+#define IMX6QDL_CLK_ANACLK1			212
+#define IMX6QDL_CLK_ANACLK2			213
+#define IMX6QDL_PLL1_BYPASS_SRC			214
+#define IMX6QDL_PLL2_BYPASS_SRC			215
+#define IMX6QDL_PLL3_BYPASS_SRC			216
+#define IMX6QDL_PLL4_BYPASS_SRC			217
+#define IMX6QDL_PLL5_BYPASS_SRC			218
+#define IMX6QDL_PLL6_BYPASS_SRC			219
+#define IMX6QDL_PLL7_BYPASS_SRC			220
+#define IMX6QDL_CLK_PLL1			221
+#define IMX6QDL_CLK_PLL2			222
+#define IMX6QDL_CLK_PLL3			223
+#define IMX6QDL_CLK_PLL4			224
+#define IMX6QDL_CLK_PLL5			225
+#define IMX6QDL_CLK_PLL6			226
+#define IMX6QDL_CLK_PLL7			227
+#define IMX6QDL_PLL1_BYPASS			228
+#define IMX6QDL_PLL2_BYPASS			229
+#define IMX6QDL_PLL3_BYPASS			230
+#define IMX6QDL_PLL4_BYPASS			231
+#define IMX6QDL_PLL5_BYPASS			232
+#define IMX6QDL_PLL6_BYPASS			233
+#define IMX6QDL_PLL7_BYPASS			234
+#define IMX6QDL_CLK_END				235
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/5] ARM: imx6sl: add BYPASS support for PLL clocks
  2014-09-01  8:13 [PATCH v2 0/5] ARM: imx6: add BYPASS support for PLLs Shawn Guo
  2014-09-01  8:14 ` [PATCH v2 1/5] ARM: imx: add an exclusive gate clock type Shawn Guo
  2014-09-01  8:14 ` [PATCH v2 2/5] ARM: imx6q: add BYPASS support for PLL clocks Shawn Guo
@ 2014-09-01  8:14 ` Shawn Guo
  2014-10-03  8:30   ` Stefan Agner
  2014-09-01  8:14 ` [PATCH v2 4/5] ARM: imx6sx: " Shawn Guo
  2014-09-01  8:14 ` [PATCH v2 5/5] ARM: imx: remove ENABLE and BYPASS bits from clk-pllv3 driver Shawn Guo
  4 siblings, 1 reply; 7+ messages in thread
From: Shawn Guo @ 2014-09-01  8:14 UTC (permalink / raw)
  To: linux-arm-kernel

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 <shawn.guo@freescale.com>
---
 arch/arm/mach-imx/clk-imx6sl.c           | 69 ++++++++++++++++++++++++++++----
 include/dt-bindings/clock/imx6sl-clock.h | 27 ++++++++++++-
 2 files changed, 87 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c
index 11908e8bf9ab..e5c93d81aecc 100644
--- a/arch/arm/mach-imx/clk-imx6sl.c
+++ b/arch/arm/mach-imx/clk-imx6sl.c
@@ -56,6 +56,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, },
@@ -176,20 +190,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 */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 4/5] ARM: imx6sx: add BYPASS support for PLL clocks
  2014-09-01  8:13 [PATCH v2 0/5] ARM: imx6: add BYPASS support for PLLs Shawn Guo
                   ` (2 preceding siblings ...)
  2014-09-01  8:14 ` [PATCH v2 3/5] ARM: imx6sl: " Shawn Guo
@ 2014-09-01  8:14 ` Shawn Guo
  2014-09-01  8:14 ` [PATCH v2 5/5] ARM: imx: remove ENABLE and BYPASS bits from clk-pllv3 driver Shawn Guo
  4 siblings, 0 replies; 7+ messages in thread
From: Shawn Guo @ 2014-09-01  8:14 UTC (permalink / raw)
  To: linux-arm-kernel

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 <shawn.guo@freescale.com>
---
 arch/arm/mach-imx/clk-imx6sx.c           | 63 +++++++++++++++++++++++++++-----
 include/dt-bindings/clock/imx6sx-clock.h | 25 ++++++++++++-
 2 files changed, 78 insertions(+), 10 deletions(-)

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 */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 5/5] ARM: imx: remove ENABLE and BYPASS bits from clk-pllv3 driver
  2014-09-01  8:13 [PATCH v2 0/5] ARM: imx6: add BYPASS support for PLLs Shawn Guo
                   ` (3 preceding siblings ...)
  2014-09-01  8:14 ` [PATCH v2 4/5] ARM: imx6sx: " Shawn Guo
@ 2014-09-01  8:14 ` Shawn Guo
  4 siblings, 0 replies; 7+ messages in thread
From: Shawn Guo @ 2014-09-01  8:14 UTC (permalink / raw)
  To: linux-arm-kernel

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 <shawn.guo@freescale.com>
---
 arch/arm/mach-imx/clk-pllv3.c | 37 -------------------------------------
 1 file changed, 37 deletions(-)

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,
 };
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/5] ARM: imx6sl: add BYPASS support for PLL clocks
  2014-09-01  8:14 ` [PATCH v2 3/5] ARM: imx6sl: " Shawn Guo
@ 2014-10-03  8:30   ` Stefan Agner
  0 siblings, 0 replies; 7+ messages in thread
From: Stefan Agner @ 2014-10-03  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Shawn,

I know it's too late since that patchset is already applied, but....

Am 2014-09-01 10:14, schrieb Shawn Guo:
> 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 <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-imx/clk-imx6sl.c           | 69 ++++++++++++++++++++++++++++----
>  include/dt-bindings/clock/imx6sl-clock.h | 27 ++++++++++++-
>  2 files changed, 87 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c
> index 11908e8bf9ab..e5c93d81aecc 100644
> --- a/arch/arm/mach-imx/clk-imx6sl.c
> +++ b/arch/arm/mach-imx/clk-imx6sl.c
> @@ -56,6 +56,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, },
> @@ -176,20 +190,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);

                        ^^^^

This is probably wrong and should be 0x20. imx6sx and imx6qdl are
affected too. Just realized that when looking into applying this BYPASS
stuff for Vybrid.

--
Stefan


> +
> +	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 */

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-10-03  8:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-01  8:13 [PATCH v2 0/5] ARM: imx6: add BYPASS support for PLLs Shawn Guo
2014-09-01  8:14 ` [PATCH v2 1/5] ARM: imx: add an exclusive gate clock type Shawn Guo
2014-09-01  8:14 ` [PATCH v2 2/5] ARM: imx6q: add BYPASS support for PLL clocks Shawn Guo
2014-09-01  8:14 ` [PATCH v2 3/5] ARM: imx6sl: " Shawn Guo
2014-10-03  8:30   ` Stefan Agner
2014-09-01  8:14 ` [PATCH v2 4/5] ARM: imx6sx: " Shawn Guo
2014-09-01  8:14 ` [PATCH v2 5/5] ARM: imx: remove ENABLE and BYPASS bits from clk-pllv3 driver Shawn Guo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.