All of lore.kernel.org
 help / color / mirror / Atom feed
* Convert i.MX architecture to generic clock framework
@ 2012-04-10 13:45 Sascha Hauer
  2012-04-10 13:45 ` [PATCH 01/40] clkdev: add clkname to struct clk_lookup Sascha Hauer
                   ` (39 more replies)
  0 siblings, 40 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi All,

The following series is the first series converting the complete
i.MX architecture to the generic clock framework. I am currently
waiting for Mike posting his cleanup series to the clock framework
which will cause some adjustments to this series. However, this
series will only need some changes to the interface between i.MX
and the clock framework. The association between the devices and
the clocks (clk_lookup) and also the clocks themselves will stay
unchanged. Due to the huge amount of changes there *will* be
regressions, so now is the time to check if this works with your
favourite devices and boards. I'll happily integrate fixup patches
into this series.

As mentioned before my plan is to put this into the arm-soc staging
area soon (hopefully when Mikes series is posted and acked)

Thanks to Shawn for porting over the i.MX6.

Sascha

The following changes since commit b41c67c587c98eb2efb2a79d4b8122b04b519d4a:

  clkdev: Implement managed clk_get() (2012-04-10 09:35:09 +0200)

are available in the git repository at:

  git://git.pengutronix.de/git/imx/linux-2.6.git work/v3.4-rc2-imx-clk

for you to fetch changes up to 3134a067ba4a66921acc8461165634abbae42e22:

  ARM i.MX: Remove now unused struct clk argument from mxc_timer_init (2012-04-10 09:35:54 +0200)

----------------------------------------------------------------
Sascha Hauer (35):
      clkdev: add clkname to struct clk_lookup
      clk: add a fixed factor clock
      dmaengine i.MX SDMA: do not depend on grouped clocks
      spi i.MX: do not depend on grouped clocks
      video imxfb: do not depend on grouped clocks
      net fec: do not depend on grouped clocks
      mmc mxcmmc: do not depend on grouped clocks
      mmc sdhc i.MX: do not depend on grouped clocks
      serial i.MX: do not depend on grouped clocks
      mtd mxc_nand: prepare/unprepare clock
      USB ehci mxc: prepare/unprepare clock
      w1 i.MX: prepare/unprepare clock
      watchdog imx2: prepare clk before enabling it
      media mx3 camera: prepare clk before enabling it
      dmaengine i.MX ipu: clk_prepare/unprepare clock
      ARM i.MX5: prepare gpc_dvfs_clk
      ARM i.MX: prepare for common clock framework
      ARM i.MX timer: request correct clock
      ARM i.MX: Add common clock support for pllv1
      ARM i.MX: Add common clock support for pllv2
      ARM i.MX: Add common clock support for 2bit gate
      ARM i.MX3: Make ccm base address a variable
      ARM i.MX25: implement clocks using common clock framework
      ARM i.MX1: implement clocks using common clock framework
      ARM i.MX21: implement clocks using common clock framework
      ARM i.MX27: implement clocks using common clock framework
      ARM i.MX31: implement clocks using common clock framework
      ARM i.MX5: implement clocks using common clock framework
      ARM i.MX35: implement clocks using common clock framework
      ARM i.MX: remove now unused old clock support
      ARM i.MX pllv1: move mxc_decode_pll to its only user
      ARM i.MX: remove unused legacy clock support
      USB gadget i.MX: fix clock handling
      USB ehci i.MX: Fix clock handling
      ARM i.MX: Remove now unused struct clk argument from mxc_timer_init

Shawn Guo (5):
      clk: declare clk_ops of basic clks in clk-provider.h
      ARM: imx: add common clock support for pllv3
      ARM: imx: add common clock support for pfd
      ARM: imx: add common clock support for clk busy
      ARM: imx6: implement clocks using common clock framework

 arch/arm/mach-imx/Kconfig               |    8 +
 arch/arm/mach-imx/Makefile              |   19 +-
 arch/arm/mach-imx/clk-busy.c            |  167 +++
 arch/arm/mach-imx/clk-gate2.c           |  125 ++
 arch/arm/mach-imx/clk-imx1.c            |  108 ++
 arch/arm/mach-imx/clk-imx21.c           |  173 +++
 arch/arm/mach-imx/clk-imx25.c           |  232 ++++
 arch/arm/mach-imx/clk-imx27.c           |  254 ++++
 arch/arm/mach-imx/clk-imx31.c           |  167 +++
 arch/arm/mach-imx/clk-imx35.c           |  258 ++++
 arch/arm/mach-imx/clk-imx51-imx53.c     |  412 ++++++
 arch/arm/mach-imx/clk-imx6q.c           |  407 ++++++
 arch/arm/mach-imx/clk-pfd.c             |  138 ++
 arch/arm/mach-imx/clk-pllv1.c           |  104 ++
 arch/arm/mach-imx/clk-pllv2.c           |  243 ++++
 arch/arm/mach-imx/clk-pllv3.c           |  408 ++++++
 arch/arm/mach-imx/clk.h                 |   83 ++
 arch/arm/mach-imx/clock-imx1.c          |  636 ----------
 arch/arm/mach-imx/clock-imx21.c         | 1239 ------------------
 arch/arm/mach-imx/clock-imx25.c         |  346 -----
 arch/arm/mach-imx/clock-imx27.c         |  785 ------------
 arch/arm/mach-imx/clock-imx31.c         |  630 ---------
 arch/arm/mach-imx/clock-imx35.c         |  536 --------
 arch/arm/mach-imx/clock-imx6q.c         | 2111 -------------------------------
 arch/arm/mach-imx/clock-mx51-mx53.c     | 1675 ------------------------
 arch/arm/mach-imx/crmregs-imx3.h        |   79 +-
 arch/arm/mach-imx/mm-imx3.c             |    6 +
 arch/arm/mach-imx/mm-imx5.c             |    1 +
 arch/arm/mach-imx/pm-imx3.c             |    4 +-
 arch/arm/plat-mxc/clock.c               |  228 +---
 arch/arm/plat-mxc/include/mach/clock.h  |   43 +-
 arch/arm/plat-mxc/include/mach/common.h |    2 +-
 arch/arm/plat-mxc/time.c                |   16 +-
 drivers/clk/Makefile                    |    2 +-
 drivers/clk/clk-fixed-factor.c          |   97 ++
 drivers/clk/clkdev.c                    |    8 +
 drivers/dma/imx-sdma.c                  |   40 +-
 drivers/dma/ipu/ipu_idmac.c             |    6 +-
 drivers/media/video/mx3_camera.c        |    4 +-
 drivers/mmc/host/mxcmmc.c               |   39 +-
 drivers/mmc/host/sdhci-esdhc-imx.c      |   42 +-
 drivers/mtd/nand/mxc_nand.c             |    6 +-
 drivers/net/ethernet/freescale/fec.c    |   35 +-
 drivers/spi/spi-imx.c                   |   30 +-
 drivers/tty/serial/imx.c                |   38 +-
 drivers/usb/gadget/fsl_mxc_udc.c        |   74 +-
 drivers/usb/host/ehci-mxc.c             |   58 +-
 drivers/video/imxfb.c                   |   50 +-
 drivers/w1/masters/mxc_w1.c             |    4 +-
 drivers/watchdog/imx2_wdt.c             |    2 +-
 include/linux/clk-private.h             |    8 -
 include/linux/clk-provider.h            |   12 +
 include/linux/clkdev.h                  |    3 +
 53 files changed, 3736 insertions(+), 8465 deletions(-)
 create mode 100644 arch/arm/mach-imx/clk-busy.c
 create mode 100644 arch/arm/mach-imx/clk-gate2.c
 create mode 100644 arch/arm/mach-imx/clk-imx1.c
 create mode 100644 arch/arm/mach-imx/clk-imx21.c
 create mode 100644 arch/arm/mach-imx/clk-imx25.c
 create mode 100644 arch/arm/mach-imx/clk-imx27.c
 create mode 100644 arch/arm/mach-imx/clk-imx31.c
 create mode 100644 arch/arm/mach-imx/clk-imx35.c
 create mode 100644 arch/arm/mach-imx/clk-imx51-imx53.c
 create mode 100644 arch/arm/mach-imx/clk-imx6q.c
 create mode 100644 arch/arm/mach-imx/clk-pfd.c
 create mode 100644 arch/arm/mach-imx/clk-pllv1.c
 create mode 100644 arch/arm/mach-imx/clk-pllv2.c
 create mode 100644 arch/arm/mach-imx/clk-pllv3.c
 create mode 100644 arch/arm/mach-imx/clk.h
 delete mode 100644 arch/arm/mach-imx/clock-imx1.c
 delete mode 100644 arch/arm/mach-imx/clock-imx21.c
 delete mode 100644 arch/arm/mach-imx/clock-imx25.c
 delete mode 100644 arch/arm/mach-imx/clock-imx27.c
 delete mode 100644 arch/arm/mach-imx/clock-imx31.c
 delete mode 100644 arch/arm/mach-imx/clock-imx35.c
 delete mode 100644 arch/arm/mach-imx/clock-imx6q.c
 delete mode 100644 arch/arm/mach-imx/clock-mx51-mx53.c
 create mode 100644 drivers/clk/clk-fixed-factor.c

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 14:30   ` Russell King - ARM Linux
  2012-04-10 13:45 ` [PATCH 02/40] clk: add a fixed factor clock Sascha Hauer
                   ` (38 subsequent siblings)
  39 siblings, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

With the generic clock framework we do not necessarily have
a pointer to the struct clk we want to register a lookup
for, so add a const char *clkname field to struct clk_lookup
so that a lookup can be registered with a clock name.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clkdev.c   |    8 ++++++++
 include/linux/clkdev.h |    3 +++
 2 files changed, 11 insertions(+)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index a9a1137..535d3d7 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -19,6 +19,7 @@
 #include <linux/mutex.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 
 static LIST_HEAD(clocks);
 static DEFINE_MUTEX(clocks_mutex);
@@ -67,6 +68,13 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id)
 
 	mutex_lock(&clocks_mutex);
 	cl = clk_find(dev_id, con_id);
+#ifdef CONFIG_COMMON_CLK
+	if (cl && cl->clkname && !cl->clk) {
+		cl->clk = __clk_lookup(cl->clkname);
+		if (!cl->clk)
+			return ERR_PTR(-ENOENT);
+	}
+#endif
 	if (cl && !__clk_get(cl->clk))
 		cl = NULL;
 	mutex_unlock(&clocks_mutex);
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index d9a4fd0..2f589ff 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -21,6 +21,9 @@ struct clk_lookup {
 	struct list_head	node;
 	const char		*dev_id;
 	const char		*con_id;
+#ifdef CONFIG_COMMON_CLK
+	const char		*clkname;
+#endif
 	struct clk		*clk;
 };
 
-- 
1.7.9.5

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

* [PATCH 02/40] clk: add a fixed factor clock
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
  2012-04-10 13:45 ` [PATCH 01/40] clkdev: add clkname to struct clk_lookup Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-17 10:15   ` Viresh Kumar
  2012-04-19  3:48   ` Viresh Kumar
  2012-04-10 13:45 ` [PATCH 03/40] clk: declare clk_ops of basic clks in clk-provider.h Sascha Hauer
                   ` (37 subsequent siblings)
  39 siblings, 2 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Having fixed factors/dividers in hardware is a common pattern, so
add a basic clock type doing this. It basically describes a fixed
factor clock using a nominator and a denominator.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/Makefile           |    2 +-
 drivers/clk/clk-fixed-factor.c |   97 ++++++++++++++++++++++++++++++++++++++++
 include/linux/clk-provider.h   |    4 ++
 3 files changed, 102 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/clk-fixed-factor.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 1f736bc..24aa714 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,4 +1,4 @@
 
 obj-$(CONFIG_CLKDEV_LOOKUP)	+= clkdev.o
 obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-fixed-rate.o clk-gate.o \
-				   clk-mux.o clk-divider.o
+				   clk-mux.o clk-divider.o clk-fixed-factor.o
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
new file mode 100644
index 0000000..7c5e1fc
--- /dev/null
+++ b/drivers/clk/clk-fixed-factor.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * 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.
+ *
+ * Standard functionality for the common clock API.
+ */
+#include <linux/module.h>
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+struct clk_fixed_factor {
+	struct clk_hw	hw;
+	unsigned int	mult;
+	unsigned int	div;
+	char		*parent[1];
+};
+
+#define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
+
+static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
+
+	return (parent_rate / fix->div) * fix->mult;
+}
+
+static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
+
+	if (prate) {
+		unsigned long best_parent;
+		best_parent = (rate / fix->mult) * fix->div;
+		*prate = __clk_round_rate(__clk_get_parent(hw->clk),
+				best_parent);
+		return (*prate / fix->div) * fix->mult;
+	} else {
+		return (__clk_get_rate(__clk_get_parent(hw->clk)) / fix->div) * fix->mult;
+	}
+}
+
+static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate)
+{
+	return 0;
+}
+
+struct clk_ops clk_fixed_factor_ops = {
+	.round_rate = clk_factor_round_rate,
+	.set_rate = clk_factor_set_rate,
+	.recalc_rate = clk_factor_recalc_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
+
+struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		unsigned int mult, unsigned int div)
+{
+	struct clk_fixed_factor *fix;
+	struct clk *clk;
+
+	fix = kmalloc(sizeof(struct clk_gate), GFP_KERNEL);
+
+	if (!fix) {
+		pr_err("%s: could not allocate gated clk\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/* struct clk_gate assignments */
+	fix->mult = mult;
+	fix->div = div;
+
+	if (parent_name) {
+		fix->parent[0] = kstrdup(parent_name, GFP_KERNEL);
+		if (!fix->parent[0])
+			goto out;
+	}
+
+	clk = clk_register(dev, name,
+			&clk_fixed_factor_ops, &fix->hw,
+			fix->parent,
+			(parent_name ? 1 : 0),
+			flags);
+	if (clk)
+		return clk;
+
+out:
+	kfree(fix->parent[0]);
+	kfree(fix);
+
+	return NULL;
+}
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 5508897..21ca2f8 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -257,6 +257,10 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
 		void __iomem *reg, u8 shift, u8 width,
 		u8 clk_mux_flags, spinlock_t *lock);
 
+struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		unsigned int mult, unsigned int div);
+
 /**
  * clk_register - allocate a new clock, register it and return an opaque cookie
  * @dev: device that is registering this clock
-- 
1.7.9.5

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

* [PATCH 03/40] clk: declare clk_ops of basic clks in clk-provider.h
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
  2012-04-10 13:45 ` [PATCH 01/40] clkdev: add clkname to struct clk_lookup Sascha Hauer
  2012-04-10 13:45 ` [PATCH 02/40] clk: add a fixed factor clock Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 04/40] dmaengine i.MX SDMA: do not depend on grouped clocks Sascha Hauer
                   ` (36 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

Besides the static initialization, the clk_ops of basic clks could
also be used by particular clk type being subclass of the basic clks.

For example, clk_busy_divider has the same clk_ops as clk_divider,
except it has to wait for a busy bit before return success with
.set_rate.  clk_busy_divider will somehow reuse clk_ops of clk_divider.

Since clk-provider.h is included by clk-private.h, it's safe to move
those clk_ops declaration of basic clks form  clk-private.h into
clk-provider.h, so that implementation of clks like clk_busy_divider
above do not need to include clk-private.h to access those clk_ops.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 include/linux/clk-private.h  |    8 --------
 include/linux/clk-provider.h |    8 ++++++++
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index 5e4312b..f19fee0 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -55,8 +55,6 @@ struct clk {
  * alternative macro for static initialization
  */
 
-extern struct clk_ops clk_fixed_rate_ops;
-
 #define DEFINE_CLK_FIXED_RATE(_name, _flags, _rate,		\
 				_fixed_rate_flags)		\
 	static struct clk _name;				\
@@ -78,8 +76,6 @@ extern struct clk_ops clk_fixed_rate_ops;
 		.flags = _flags,				\
 	};
 
-extern struct clk_ops clk_gate_ops;
-
 #define DEFINE_CLK_GATE(_name, _parent_name, _parent_ptr,	\
 				_flags, _reg, _bit_idx,		\
 				_gate_flags, _lock)		\
@@ -110,8 +106,6 @@ extern struct clk_ops clk_gate_ops;
 		.flags = _flags,				\
 	};
 
-extern struct clk_ops clk_divider_ops;
-
 #define DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr,	\
 				_flags, _reg, _shift, _width,	\
 				_divider_flags, _lock)		\
@@ -143,8 +137,6 @@ extern struct clk_ops clk_divider_ops;
 		.flags = _flags,				\
 	};
 
-extern struct clk_ops clk_mux_ops;
-
 #define DEFINE_CLK_MUX(_name, _parent_names, _parents, _flags,	\
 				_reg, _shift, _width,		\
 				_mux_flags, _lock)		\
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 21ca2f8..587f54b 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -149,6 +149,8 @@ struct clk_fixed_rate {
 	u8		flags;
 };
 
+extern struct clk_ops clk_fixed_rate_ops;
+
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		unsigned long fixed_rate);
@@ -180,6 +182,8 @@ struct clk_gate {
 
 #define CLK_GATE_SET_TO_DISABLE		BIT(0)
 
+extern struct clk_ops clk_gate_ops;
+
 struct clk *clk_register_gate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 bit_idx,
@@ -218,6 +222,8 @@ struct clk_divider {
 #define CLK_DIVIDER_ONE_BASED		BIT(0)
 #define CLK_DIVIDER_POWER_OF_TWO	BIT(1)
 
+extern struct clk_ops clk_divider_ops;
+
 struct clk *clk_register_divider(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
@@ -252,6 +258,8 @@ struct clk_mux {
 #define CLK_MUX_INDEX_ONE		BIT(0)
 #define CLK_MUX_INDEX_BIT		BIT(1)
 
+extern struct clk_ops clk_mux_ops;
+
 struct clk *clk_register_mux(struct device *dev, const char *name,
 		char **parent_names, u8 num_parents, unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
-- 
1.7.9.5

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

* [PATCH 04/40] dmaengine i.MX SDMA: do not depend on grouped clocks
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (2 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 03/40] clk: declare clk_ops of basic clks in clk-provider.h Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 05/40] spi i.MX: " Sascha Hauer
                   ` (35 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

the current i.MX clock support groups together unrelated clocks
to a single clock which is then used by the driver. This can't
be accomplished with the generic clock framework so we instead
request the individual clocks in the driver. For i.MX there are
generally three different clocks:

ipg: bus clock (needed to access registers)
ahb: dma relevant clock, sometimes referred to as hclk in the datasheet
per: bit clock, pixel clock

This patch changes the driver to request the individual clocks.
Currently all clk_get will get the same clock until the SoCs
are converted to the generic clock framework

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/imx-sdma.c |   40 ++++++++++++++++++++++++++++------------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index d3e38e2..fddccae 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -322,7 +322,8 @@ struct sdma_engine {
 	struct sdma_context_data	*context;
 	dma_addr_t			context_phys;
 	struct dma_device		dma_device;
-	struct clk			*clk;
+	struct clk			*clk_ipg;
+	struct clk			*clk_ahb;
 	struct mutex			channel_0_lock;
 	struct sdma_script_start_addrs	*script_addrs;
 };
@@ -859,7 +860,8 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
 	sdmac->peripheral_type = data->peripheral_type;
 	sdmac->event_id0 = data->dma_request;
 
-	clk_enable(sdmac->sdma->clk);
+	clk_enable(sdmac->sdma->clk_ipg);
+	clk_enable(sdmac->sdma->clk_ahb);
 
 	ret = sdma_request_channel(sdmac);
 	if (ret)
@@ -896,7 +898,8 @@ static void sdma_free_chan_resources(struct dma_chan *chan)
 
 	dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys);
 
-	clk_disable(sdma->clk);
+	clk_disable(sdma->clk_ipg);
+	clk_disable(sdma->clk_ahb);
 }
 
 static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
@@ -1169,12 +1172,14 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
 	addr = (void *)header + header->script_addrs_start;
 	ram_code = (void *)header + header->ram_code_start;
 
-	clk_enable(sdma->clk);
+	clk_enable(sdma->clk_ipg);
+	clk_enable(sdma->clk_ahb);
 	/* download the RAM image for SDMA */
 	sdma_load_script(sdma, ram_code,
 			header->ram_code_size,
 			addr->ram_code_start_addr);
-	clk_disable(sdma->clk);
+	clk_disable(sdma->clk_ipg);
+	clk_disable(sdma->clk_ahb);
 
 	sdma_add_scripts(sdma, addr);
 
@@ -1216,7 +1221,8 @@ static int __init sdma_init(struct sdma_engine *sdma)
 		return -ENODEV;
 	}
 
-	clk_enable(sdma->clk);
+	clk_enable(sdma->clk_ipg);
+	clk_enable(sdma->clk_ahb);
 
 	/* Be sure SDMA has not started yet */
 	writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
@@ -1269,12 +1275,14 @@ static int __init sdma_init(struct sdma_engine *sdma)
 	/* Initializes channel's priorities */
 	sdma_set_channel_priority(&sdma->channel[0], 7);
 
-	clk_disable(sdma->clk);
+	clk_disable(sdma->clk_ipg);
+	clk_disable(sdma->clk_ahb);
 
 	return 0;
 
 err_dma_alloc:
-	clk_disable(sdma->clk);
+	clk_disable(sdma->clk_ipg);
+	clk_disable(sdma->clk_ahb);
 	dev_err(sdma->dev, "initialisation failed with %d\n", ret);
 	return ret;
 }
@@ -1313,12 +1321,21 @@ static int __init sdma_probe(struct platform_device *pdev)
 		goto err_request_region;
 	}
 
-	sdma->clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(sdma->clk)) {
-		ret = PTR_ERR(sdma->clk);
+	sdma->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(sdma->clk_ipg)) {
+		ret = PTR_ERR(sdma->clk_ipg);
 		goto err_clk;
 	}
 
+	sdma->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(sdma->clk_ahb)) {
+		ret = PTR_ERR(sdma->clk_ahb);
+		goto err_clk;
+	}
+
+	clk_prepare(sdma->clk_ipg);
+	clk_prepare(sdma->clk_ahb);
+
 	sdma->regs = ioremap(iores->start, resource_size(iores));
 	if (!sdma->regs) {
 		ret = -ENOMEM;
@@ -1426,7 +1443,6 @@ err_alloc:
 err_request_irq:
 	iounmap(sdma->regs);
 err_ioremap:
-	clk_put(sdma->clk);
 err_clk:
 	release_mem_region(iores->start, resource_size(iores));
 err_request_region:
-- 
1.7.9.5

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

* [PATCH 05/40] spi i.MX: do not depend on grouped clocks
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (3 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 04/40] dmaengine i.MX SDMA: do not depend on grouped clocks Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 06/40] video imxfb: " Sascha Hauer
                   ` (34 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

the current i.MX clock support groups together unrelated clocks
to a single clock which is then used by the driver. This can't
be accomplished with the generic clock framework so we instead
request the individual clocks in the driver. For i.MX there are
generally three different clocks:

ipg: bus clock (needed to access registers)
ahb: dma relevant clock, sometimes referred to as hclk in the datasheet
per: bit clock, pixel clock

This patch changes the driver to request the individual clocks.
Currently all clk_get will get the same clock until the SoCs
are converted to the generic clock framework

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/spi/spi-imx.c |   30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 31054e3..b54bfe8 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -85,7 +85,8 @@ struct spi_imx_data {
 	struct completion xfer_done;
 	void *base;
 	int irq;
-	struct clk *clk;
+	struct clk *clk_per;
+	struct clk *clk_ipg;
 	unsigned long spi_clk;
 
 	unsigned int count;
@@ -841,15 +842,22 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
 		goto out_iounmap;
 	}
 
-	spi_imx->clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(spi_imx->clk)) {
-		dev_err(&pdev->dev, "unable to get clock\n");
-		ret = PTR_ERR(spi_imx->clk);
+	spi_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(spi_imx->clk_ipg)) {
+		ret = PTR_ERR(spi_imx->clk_ipg);
 		goto out_free_irq;
 	}
 
-	clk_enable(spi_imx->clk);
-	spi_imx->spi_clk = clk_get_rate(spi_imx->clk);
+	spi_imx->clk_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(spi_imx->clk_per)) {
+		ret = PTR_ERR(spi_imx->clk_per);
+		goto out_free_irq;
+	}
+
+	clk_prepare_enable(spi_imx->clk_per);
+	clk_prepare_enable(spi_imx->clk_ipg);
+
+	spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per);
 
 	spi_imx->devtype_data->reset(spi_imx);
 
@@ -867,8 +875,8 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
 	return ret;
 
 out_clk_put:
-	clk_disable(spi_imx->clk);
-	clk_put(spi_imx->clk);
+	clk_disable_unprepare(spi_imx->clk_per);
+	clk_disable_unprepare(spi_imx->clk_ipg);
 out_free_irq:
 	free_irq(spi_imx->irq, spi_imx);
 out_iounmap:
@@ -896,8 +904,8 @@ static int __devexit spi_imx_remove(struct platform_device *pdev)
 	spi_bitbang_stop(&spi_imx->bitbang);
 
 	writel(0, spi_imx->base + MXC_CSPICTRL);
-	clk_disable(spi_imx->clk);
-	clk_put(spi_imx->clk);
+	clk_disable_unprepare(spi_imx->clk_per);
+	clk_disable_unprepare(spi_imx->clk_ipg);
 	free_irq(spi_imx->irq, spi_imx);
 	iounmap(spi_imx->base);
 
-- 
1.7.9.5

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

* [PATCH 06/40] video imxfb: do not depend on grouped clocks
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (4 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 05/40] spi i.MX: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 07/40] net fec: " Sascha Hauer
                   ` (33 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

the current i.MX clock support groups together unrelated clocks
to a single clock which is then used by the driver. This can't
be accomplished with the generic clock framework so we instead
request the individual clocks in the driver. For i.MX there are
generally three different clocks:

ipg: bus clock (needed to access registers)
ahb: dma relevant clock, sometimes referred to as hclk in the datasheet
per: bit clock, pixel clock

This patch changes the driver to request the individual clocks.
Currently all clk_get will get the same clock until the SoCs
are converted to the generic clock framework

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/video/imxfb.c |   50 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 35 insertions(+), 15 deletions(-)

diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index f135dbe..caad368 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -131,7 +131,9 @@ struct imxfb_rgb {
 struct imxfb_info {
 	struct platform_device  *pdev;
 	void __iomem		*regs;
-	struct clk		*clk;
+	struct clk		*clk_ipg;
+	struct clk		*clk_ahb;
+	struct clk		*clk_per;
 
 	/*
 	 * These are the addresses we mapped
@@ -340,7 +342,7 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 
 	pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
 
-	lcd_clk = clk_get_rate(fbi->clk);
+	lcd_clk = clk_get_rate(fbi->clk_per);
 
 	tmp = var->pixclock * (unsigned long long)lcd_clk;
 
@@ -455,11 +457,17 @@ static int imxfb_bl_update_status(struct backlight_device *bl)
 
 	fbi->pwmr = (fbi->pwmr & ~0xFF) | brightness;
 
-	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
-		clk_enable(fbi->clk);
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK) {
+		clk_prepare_enable(fbi->clk_ipg);
+		clk_prepare_enable(fbi->clk_ahb);
+		clk_prepare_enable(fbi->clk_per);
+	}
 	writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
-	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
-		clk_disable(fbi->clk);
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK) {
+		clk_disable_unprepare(fbi->clk_per);
+		clk_disable_unprepare(fbi->clk_ahb);
+		clk_disable_unprepare(fbi->clk_ipg);
+	}
 
 	return 0;
 }
@@ -522,7 +530,9 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
 	 */
 	writel(RMCR_LCDC_EN_MX1, fbi->regs + LCDC_RMCR);
 
-	clk_enable(fbi->clk);
+	clk_prepare_enable(fbi->clk_ipg);
+	clk_prepare_enable(fbi->clk_ahb);
+	clk_prepare_enable(fbi->clk_per);
 
 	if (fbi->backlight_power)
 		fbi->backlight_power(1);
@@ -539,7 +549,9 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
 	if (fbi->lcd_power)
 		fbi->lcd_power(0);
 
-	clk_disable(fbi->clk);
+	clk_disable_unprepare(fbi->clk_per);
+	clk_disable_unprepare(fbi->clk_ipg);
+	clk_disable_unprepare(fbi->clk_ahb);
 
 	writel(0, fbi->regs + LCDC_RMCR);
 }
@@ -770,10 +782,21 @@ static int __init imxfb_probe(struct platform_device *pdev)
 		goto failed_req;
 	}
 
-	fbi->clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(fbi->clk)) {
-		ret = PTR_ERR(fbi->clk);
-		dev_err(&pdev->dev, "unable to get clock: %d\n", ret);
+	fbi->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(fbi->clk_ipg)) {
+		ret = PTR_ERR(fbi->clk_ipg);
+		goto failed_getclock;
+	}
+
+	fbi->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(fbi->clk_ahb)) {
+		ret = PTR_ERR(fbi->clk_ahb);
+		goto failed_getclock;
+	}
+
+	fbi->clk_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(fbi->clk_per)) {
+		ret = PTR_ERR(fbi->clk_per);
 		goto failed_getclock;
 	}
 
@@ -858,7 +881,6 @@ failed_platform_init:
 failed_map:
 	iounmap(fbi->regs);
 failed_ioremap:
-	clk_put(fbi->clk);
 failed_getclock:
 	release_mem_region(res->start, resource_size(res));
 failed_req:
@@ -895,8 +917,6 @@ static int __devexit imxfb_remove(struct platform_device *pdev)
 
 	iounmap(fbi->regs);
 	release_mem_region(res->start, resource_size(res));
-	clk_disable(fbi->clk);
-	clk_put(fbi->clk);
 
 	platform_set_drvdata(pdev, NULL);
 
-- 
1.7.9.5

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

* [PATCH 07/40] net fec: do not depend on grouped clocks
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (5 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 06/40] video imxfb: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 08/40] mmc mxcmmc: " Sascha Hauer
                   ` (32 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

the current i.MX clock support groups together unrelated clocks
to a single clock which is then used by the driver. This can't
be accomplished with the generic clock framework so we instead
request the individual clocks in the driver. For i.MX there are
generally three different clocks:

ipg: bus clock (needed to access registers)
ahb: dma relevant clock, sometimes referred to as hclk in the datasheet
per: bit clock, pixel clock

This patch changes the driver to request the individual clocks.
Currently all clk_get will get the same clock until the SoCs
are converted to the generic clock framework

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/ethernet/freescale/fec.c |   35 ++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index a12b3f5..b249463 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -206,7 +206,8 @@ struct fec_enet_private {
 
 	struct net_device *netdev;
 
-	struct clk *clk;
+	struct clk *clk_ipg;
+	struct clk *clk_ahb;
 
 	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
 	unsigned char *tx_bounce[TX_RING_SIZE];
@@ -1064,7 +1065,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
 	 * Reference Manual has an error on this, and gets fixed on i.MX6Q
 	 * document.
 	 */
-	fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk), 5000000);
+	fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ahb), 5000000);
 	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
 		fep->phy_speed--;
 	fep->phy_speed <<= 1;
@@ -1609,12 +1610,20 @@ fec_probe(struct platform_device *pdev)
 		}
 	}
 
-	fep->clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(fep->clk)) {
-		ret = PTR_ERR(fep->clk);
+	fep->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(fep->clk_ipg)) {
+		ret = PTR_ERR(fep->clk_ipg);
 		goto failed_clk;
 	}
-	clk_prepare_enable(fep->clk);
+
+	fep->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(fep->clk_ahb)) {
+		ret = PTR_ERR(fep->clk_ahb);
+		goto failed_clk;
+	}
+
+	clk_prepare_enable(fep->clk_ahb);
+	clk_prepare_enable(fep->clk_ipg);
 
 	ret = fec_enet_init(ndev);
 	if (ret)
@@ -1637,8 +1646,8 @@ failed_register:
 	fec_enet_mii_remove(fep);
 failed_mii_init:
 failed_init:
-	clk_disable_unprepare(fep->clk);
-	clk_put(fep->clk);
+	clk_disable_unprepare(fep->clk_ahb);
+	clk_disable_unprepare(fep->clk_ipg);
 failed_clk:
 	for (i = 0; i < FEC_IRQ_NUM; i++) {
 		irq = platform_get_irq(pdev, i);
@@ -1670,8 +1679,8 @@ fec_drv_remove(struct platform_device *pdev)
 		if (irq > 0)
 			free_irq(irq, ndev);
 	}
-	clk_disable_unprepare(fep->clk);
-	clk_put(fep->clk);
+	clk_disable_unprepare(fep->clk_ahb);
+	clk_disable_unprepare(fep->clk_ipg);
 	iounmap(fep->hwp);
 	free_netdev(ndev);
 
@@ -1695,7 +1704,8 @@ fec_suspend(struct device *dev)
 		fec_stop(ndev);
 		netif_device_detach(ndev);
 	}
-	clk_disable_unprepare(fep->clk);
+	clk_disable_unprepare(fep->clk_ahb);
+	clk_disable_unprepare(fep->clk_ipg);
 
 	return 0;
 }
@@ -1706,7 +1716,8 @@ fec_resume(struct device *dev)
 	struct net_device *ndev = dev_get_drvdata(dev);
 	struct fec_enet_private *fep = netdev_priv(ndev);
 
-	clk_prepare_enable(fep->clk);
+	clk_prepare_enable(fep->clk_ahb);
+	clk_prepare_enable(fep->clk_ipg);
 	if (netif_running(ndev)) {
 		fec_restart(ndev, fep->full_duplex);
 		netif_device_attach(ndev);
-- 
1.7.9.5

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

* [PATCH 08/40] mmc mxcmmc: do not depend on grouped clocks
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (6 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 07/40] net fec: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 09/40] mmc sdhc i.MX: " Sascha Hauer
                   ` (31 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

the current i.MX clock support groups together unrelated clocks
to a single clock which is then used by the driver. This can't
be accomplished with the generic clock framework so we instead
request the individual clocks in the driver. For i.MX there are
generally three different clocks:

ipg: bus clock (needed to access registers)
ahb: dma relevant clock, sometimes referred to as hclk in the datasheet
per: bit clock, pixel clock

This patch changes the driver to request the individual clocks.
Currently all clk_get will get the same clock until the SoCs
are converted to the generic clock framework

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mmc/host/mxcmmc.c |   39 +++++++++++++++++++++++++--------------
 1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index b2058b4..28ed52d 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -136,7 +136,8 @@ struct mxcmci_host {
 	u16			rev_no;
 	unsigned int		cmdat;
 
-	struct clk		*clk;
+	struct clk		*clk_ipg;
+	struct clk		*clk_per;
 
 	int			clock;
 
@@ -672,7 +673,7 @@ static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
 {
 	unsigned int divider;
 	int prescaler = 0;
-	unsigned int clk_in = clk_get_rate(host->clk);
+	unsigned int clk_in = clk_get_rate(host->clk_per);
 
 	while (prescaler <= 0x800) {
 		for (divider = 1; divider <= 0xF; divider++) {
@@ -900,12 +901,20 @@ static int mxcmci_probe(struct platform_device *pdev)
 	host->res = r;
 	host->irq = irq;
 
-	host->clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(host->clk)) {
-		ret = PTR_ERR(host->clk);
+	host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(host->clk_ipg)) {
+		ret = PTR_ERR(host->clk_ipg);
 		goto out_iounmap;
 	}
-	clk_enable(host->clk);
+
+	host->clk_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(host->clk_per)) {
+		ret = PTR_ERR(host->clk_per);
+		goto out_iounmap;
+	}
+
+	clk_prepare_enable(host->clk_per);
+	clk_prepare_enable(host->clk_ipg);
 
 	mxcmci_softreset(host);
 
@@ -917,8 +926,8 @@ static int mxcmci_probe(struct platform_device *pdev)
 		goto out_clk_put;
 	}
 
-	mmc->f_min = clk_get_rate(host->clk) >> 16;
-	mmc->f_max = clk_get_rate(host->clk) >> 1;
+	mmc->f_min = clk_get_rate(host->clk_per) >> 16;
+	mmc->f_max = clk_get_rate(host->clk_per) >> 1;
 
 	/* recommended in data sheet */
 	writew(0x2db4, host->base + MMC_REG_READ_TO);
@@ -967,8 +976,8 @@ out_free_dma:
 	if (host->dma)
 		dma_release_channel(host->dma);
 out_clk_put:
-	clk_disable(host->clk);
-	clk_put(host->clk);
+	clk_disable_unprepare(host->clk_per);
+	clk_disable_unprepare(host->clk_ipg);
 out_iounmap:
 	iounmap(host->base);
 out_free:
@@ -999,8 +1008,8 @@ static int mxcmci_remove(struct platform_device *pdev)
 	if (host->dma)
 		dma_release_channel(host->dma);
 
-	clk_disable(host->clk);
-	clk_put(host->clk);
+	clk_disable_unprepare(host->clk_per);
+	clk_disable_unprepare(host->clk_ipg);
 
 	release_mem_region(host->res->start, resource_size(host->res));
 
@@ -1018,7 +1027,8 @@ static int mxcmci_suspend(struct device *dev)
 
 	if (mmc)
 		ret = mmc_suspend_host(mmc);
-	clk_disable(host->clk);
+	clk_disable_unprepare(host->clk_per);
+	clk_disable_unprepare(host->clk_ipg);
 
 	return ret;
 }
@@ -1029,7 +1039,8 @@ static int mxcmci_resume(struct device *dev)
 	struct mxcmci_host *host = mmc_priv(mmc);
 	int ret = 0;
 
-	clk_enable(host->clk);
+	clk_prepare_enable(host->clk_per);
+	clk_prepare_enable(host->clk_ipg);
 	if (mmc)
 		ret = mmc_resume_host(mmc);
 
-- 
1.7.9.5

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

* [PATCH 09/40] mmc sdhc i.MX: do not depend on grouped clocks
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (7 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 08/40] mmc mxcmmc: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-20  2:06   ` Richard Zhao
  2012-04-10 13:45 ` [PATCH 10/40] serial " Sascha Hauer
                   ` (30 subsequent siblings)
  39 siblings, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

the current i.MX clock support groups together unrelated clocks
to a single clock which is then used by the driver. This can't
be accomplished with the generic clock framework so we instead
request the individual clocks in the driver. For i.MX there are
generally three different clocks:

ipg: bus clock (needed to access registers)
ahb: dma relevant clock, sometimes referred to as hclk in the datasheet
per: bit clock, pixel clock

This patch changes the driver to request the individual clocks.
Currently all clk_get will get the same clock until the SoCs
are converted to the generic clock framework

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mmc/host/sdhci-esdhc-imx.c |   42 ++++++++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 6193a0d..938095a 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -69,6 +69,9 @@ struct pltfm_imx_data {
 	u32 scratchpad;
 	enum imx_esdhc_type devtype;
 	struct esdhc_platform_data boarddata;
+	struct clk *clk_ipg;
+	struct clk *clk_ahb;
+	struct clk *clk_per;
 };
 
 static struct platform_device_id imx_esdhc_devtype[] = {
@@ -437,7 +440,6 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	struct sdhci_pltfm_host *pltfm_host;
 	struct sdhci_host *host;
 	struct esdhc_platform_data *boarddata;
-	struct clk *clk;
 	int err;
 	struct pltfm_imx_data *imx_data;
 
@@ -458,14 +460,29 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	imx_data->devtype = pdev->id_entry->driver_data;
 	pltfm_host->priv = imx_data;
 
-	clk = clk_get(mmc_dev(host->mmc), NULL);
-	if (IS_ERR(clk)) {
-		dev_err(mmc_dev(host->mmc), "clk err\n");
-		err = PTR_ERR(clk);
+	imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(imx_data->clk_ipg)) {
+		err = PTR_ERR(imx_data->clk_ipg);
 		goto err_clk_get;
 	}
-	clk_prepare_enable(clk);
-	pltfm_host->clk = clk;
+
+	imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(imx_data->clk_ahb)) {
+		err = PTR_ERR(imx_data->clk_ahb);
+		goto err_clk_get;
+	}
+
+	imx_data->clk_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(imx_data->clk_per)) {
+		err = PTR_ERR(imx_data->clk_per);
+		goto err_clk_get;
+	}
+
+	pltfm_host->clk = imx_data->clk_per;
+
+	clk_prepare_enable(imx_data->clk_per);
+	clk_prepare_enable(imx_data->clk_ipg);
+	clk_prepare_enable(imx_data->clk_ahb);
 
 	if (!is_imx25_esdhc(imx_data))
 		host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
@@ -559,8 +576,9 @@ no_card_detect_irq:
 		gpio_free(boarddata->wp_gpio);
 no_card_detect_pin:
 no_board_data:
-	clk_disable_unprepare(pltfm_host->clk);
-	clk_put(pltfm_host->clk);
+	clk_disable_unprepare(imx_data->clk_per);
+	clk_disable_unprepare(imx_data->clk_ipg);
+	clk_disable_unprepare(imx_data->clk_ahb);
 err_clk_get:
 	kfree(imx_data);
 err_imx_data:
@@ -586,8 +604,10 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
 		gpio_free(boarddata->cd_gpio);
 	}
 
-	clk_disable_unprepare(pltfm_host->clk);
-	clk_put(pltfm_host->clk);
+	clk_disable_unprepare(imx_data->clk_per);
+	clk_disable_unprepare(imx_data->clk_ipg);
+	clk_disable_unprepare(imx_data->clk_ahb);
+
 	kfree(imx_data);
 
 	sdhci_pltfm_free(pdev);
-- 
1.7.9.5

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

* [PATCH 10/40] serial i.MX: do not depend on grouped clocks
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (8 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 09/40] mmc sdhc i.MX: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 11/40] mtd mxc_nand: prepare/unprepare clock Sascha Hauer
                   ` (29 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

the current i.MX clock support groups together unrelated clocks
to a single clock which is then used by the driver. This can't
be accomplished with the generic clock framework so we instead
request the individual clocks in the driver. For i.MX there are
generally three different clocks:

ipg: bus clock (needed to access registers)
ahb: dma relevant clock, sometimes referred to as hclk in the datasheet
per: bit clock, pixel clock

This patch changes the driver to request the individual clocks.
Currently all clk_get will get the same clock until the SoCs
are converted to the generic clock framework

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/tty/serial/imx.c |   38 +++++++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index e7fecee..267ec6d 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -204,7 +204,8 @@ struct imx_port {
 	unsigned int		irda_inv_rx:1;
 	unsigned int		irda_inv_tx:1;
 	unsigned short		trcv_delay; /* transceiver delay */
-	struct clk		*clk;
+	struct clk		*clk_ipg;
+	struct clk		*clk_per;
 	struct imx_uart_data	*devdata;
 };
 
@@ -672,7 +673,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
 	 * RFDIV is set such way to satisfy requested uartclk value
 	 */
 	val = TXTL << 10 | RXTL;
-	ufcr_rfdiv = (clk_get_rate(sport->clk) + sport->port.uartclk / 2)
+	ufcr_rfdiv = (clk_get_rate(sport->clk_per) + sport->port.uartclk / 2)
 			/ sport->port.uartclk;
 
 	if(!ufcr_rfdiv)
@@ -1285,7 +1286,7 @@ imx_console_get_options(struct imx_port *sport, int *baud,
 		else
 			ucfr_rfdiv = 6 - ucfr_rfdiv;
 
-		uartclk = clk_get_rate(sport->clk);
+		uartclk = clk_get_rate(sport->clk_per);
 		uartclk /= ucfr_rfdiv;
 
 		{	/*
@@ -1503,14 +1504,22 @@ static int serial_imx_probe(struct platform_device *pdev)
 	sport->timer.function = imx_timeout;
 	sport->timer.data     = (unsigned long)sport;
 
-	sport->clk = clk_get(&pdev->dev, "uart");
-	if (IS_ERR(sport->clk)) {
-		ret = PTR_ERR(sport->clk);
+	sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(sport->clk_ipg)) {
+		ret = PTR_ERR(sport->clk_ipg);
 		goto unmap;
 	}
-	clk_prepare_enable(sport->clk);
 
-	sport->port.uartclk = clk_get_rate(sport->clk);
+	sport->clk_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(sport->clk_per)) {
+		ret = PTR_ERR(sport->clk_per);
+		goto unmap;
+	}
+
+	clk_prepare_enable(sport->clk_per);
+	clk_prepare_enable(sport->clk_ipg);
+
+	sport->port.uartclk = clk_get_rate(sport->clk_per);
 
 	imx_ports[sport->port.line] = sport;
 
@@ -1531,8 +1540,8 @@ deinit:
 	if (pdata && pdata->exit)
 		pdata->exit(pdev);
 clkput:
-	clk_disable_unprepare(sport->clk);
-	clk_put(sport->clk);
+	clk_disable_unprepare(sport->clk_per);
+	clk_disable_unprepare(sport->clk_ipg);
 unmap:
 	iounmap(sport->port.membase);
 free:
@@ -1550,11 +1559,10 @@ static int serial_imx_remove(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, NULL);
 
-	if (sport) {
-		uart_remove_one_port(&imx_reg, &sport->port);
-		clk_disable_unprepare(sport->clk);
-		clk_put(sport->clk);
-	}
+	uart_remove_one_port(&imx_reg, &sport->port);
+
+	clk_disable_unprepare(sport->clk_per);
+	clk_disable_unprepare(sport->clk_ipg);
 
 	if (pdata && pdata->exit)
 		pdata->exit(pdev);
-- 
1.7.9.5

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

* [PATCH 11/40] mtd mxc_nand: prepare/unprepare clock
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (9 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 10/40] serial " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 12/40] USB ehci mxc: " Sascha Hauer
                   ` (28 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/mxc_nand.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index cc0678a..9e374e9 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -690,7 +690,7 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
 	if (chip == -1) {
 		/* Disable the NFC clock */
 		if (host->clk_act) {
-			clk_disable(host->clk);
+			clk_disable_unprepare(host->clk);
 			host->clk_act = 0;
 		}
 		return;
@@ -698,7 +698,7 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
 
 	if (!host->clk_act) {
 		/* Enable the NFC clock */
-		clk_enable(host->clk);
+		clk_prepare_enable(host->clk);
 		host->clk_act = 1;
 	}
 
@@ -1078,7 +1078,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
 		goto eclk;
 	}
 
-	clk_enable(host->clk);
+	clk_prepare_enable(host->clk);
 	host->clk_act = 1;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- 
1.7.9.5

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

* [PATCH 12/40] USB ehci mxc: prepare/unprepare clock
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (10 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 11/40] mtd mxc_nand: prepare/unprepare clock Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 13/40] w1 i.MX: " Sascha Hauer
                   ` (27 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/host/ehci-mxc.c |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index a797d51..ae16c34 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -171,7 +171,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
 		ret = PTR_ERR(priv->usbclk);
 		goto err_clk;
 	}
-	clk_enable(priv->usbclk);
+	clk_prepare_enable(priv->usbclk);
 
 	if (!cpu_is_mx35() && !cpu_is_mx25()) {
 		priv->ahbclk = clk_get(dev, "usb_ahb");
@@ -179,7 +179,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
 			ret = PTR_ERR(priv->ahbclk);
 			goto err_clk_ahb;
 		}
-		clk_enable(priv->ahbclk);
+		clk_prepare_enable(priv->ahbclk);
 	}
 
 	/* "dr" device has its own clock on i.MX51 */
@@ -189,7 +189,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
 			ret = PTR_ERR(priv->phy1clk);
 			goto err_clk_phy;
 		}
-		clk_enable(priv->phy1clk);
+		clk_prepare_enable(priv->phy1clk);
 	}
 
 
@@ -266,16 +266,16 @@ err_add:
 		pdata->exit(pdev);
 err_init:
 	if (priv->phy1clk) {
-		clk_disable(priv->phy1clk);
+		clk_disable_unprepare(priv->phy1clk);
 		clk_put(priv->phy1clk);
 	}
 err_clk_phy:
 	if (priv->ahbclk) {
-		clk_disable(priv->ahbclk);
+		clk_disable_unprepare(priv->ahbclk);
 		clk_put(priv->ahbclk);
 	}
 err_clk_ahb:
-	clk_disable(priv->usbclk);
+	clk_disable_unprepare(priv->usbclk);
 	clk_put(priv->usbclk);
 err_clk:
 	iounmap(hcd->regs);
@@ -307,14 +307,14 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
 	usb_put_hcd(hcd);
 	platform_set_drvdata(pdev, NULL);
 
-	clk_disable(priv->usbclk);
+	clk_disable_unprepare(priv->usbclk);
 	clk_put(priv->usbclk);
 	if (priv->ahbclk) {
-		clk_disable(priv->ahbclk);
+		clk_disable_unprepare(priv->ahbclk);
 		clk_put(priv->ahbclk);
 	}
 	if (priv->phy1clk) {
-		clk_disable(priv->phy1clk);
+		clk_disable_unprepare(priv->phy1clk);
 		clk_put(priv->phy1clk);
 	}
 
-- 
1.7.9.5

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

* [PATCH 13/40] w1 i.MX: prepare/unprepare clock
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (11 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 12/40] USB ehci mxc: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 14/40] watchdog imx2: prepare clk before enabling it Sascha Hauer
                   ` (26 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/w1/masters/mxc_w1.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c
index a3b6a74..1cc61a7 100644
--- a/drivers/w1/masters/mxc_w1.c
+++ b/drivers/w1/masters/mxc_w1.c
@@ -138,7 +138,7 @@ static int __devinit mxc_w1_probe(struct platform_device *pdev)
 		goto failed_ioremap;
 	}
 
-	clk_enable(mdev->clk);
+	clk_prepare_enable(mdev->clk);
 	__raw_writeb(mdev->clkdiv, mdev->regs + MXC_W1_TIME_DIVIDER);
 
 	mdev->bus_master.data = mdev;
@@ -178,7 +178,7 @@ static int __devexit mxc_w1_remove(struct platform_device *pdev)
 
 	iounmap(mdev->regs);
 	release_mem_region(res->start, resource_size(res));
-	clk_disable(mdev->clk);
+	clk_disable_unprepare(mdev->clk);
 	clk_put(mdev->clk);
 
 	platform_set_drvdata(pdev, NULL);
-- 
1.7.9.5

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

* [PATCH 14/40] watchdog imx2: prepare clk before enabling it
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (12 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 13/40] w1 i.MX: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 15/40] media mx3 camera: " Sascha Hauer
                   ` (25 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/watchdog/imx2_wdt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 7a2b734..bcfab2b 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -121,7 +121,7 @@ static void imx2_wdt_start(void)
 {
 	if (!test_and_set_bit(IMX2_WDT_STATUS_STARTED, &imx2_wdt.status)) {
 		/* at our first start we enable clock and do initialisations */
-		clk_enable(imx2_wdt.clk);
+		clk_prepare_enable(imx2_wdt.clk);
 
 		imx2_wdt_setup();
 	} else	/* delete the timer that pings the watchdog after close */
-- 
1.7.9.5

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

* [PATCH 15/40] media mx3 camera: prepare clk before enabling it
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (13 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 14/40] watchdog imx2: prepare clk before enabling it Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 16/40] dmaengine i.MX ipu: clk_prepare/unprepare clock Sascha Hauer
                   ` (24 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/media/video/mx3_camera.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 93c35ef..e2e33df 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -508,7 +508,7 @@ static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
 	/* ipu_csi_init_interface() */
 	csi_reg_write(mx3_cam, conf, CSI_SENS_CONF);
 
-	clk_enable(mx3_cam->clk);
+	clk_prepare_enable(mx3_cam->clk);
 	rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
 	dev_dbg(icd->parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
 	if (rate)
@@ -549,7 +549,7 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd)
 		*ichan = NULL;
 	}
 
-	clk_disable(mx3_cam->clk);
+	clk_disable_unprepare(mx3_cam->clk);
 
 	mx3_cam->icd = NULL;
 
-- 
1.7.9.5

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

* [PATCH 16/40] dmaengine i.MX ipu: clk_prepare/unprepare clock
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (14 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 15/40] media mx3 camera: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 17/40] ARM i.MX5: prepare gpc_dvfs_clk Sascha Hauer
                   ` (23 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/ipu/ipu_idmac.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index 62e3f8e..5ec7204 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1715,7 +1715,7 @@ static int __init ipu_probe(struct platform_device *pdev)
 	}
 
 	/* Make sure IPU HSP clock is running */
-	clk_enable(ipu_data.ipu_clk);
+	clk_prepare_enable(ipu_data.ipu_clk);
 
 	/* Disable all interrupts */
 	idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_1);
@@ -1747,7 +1747,7 @@ static int __init ipu_probe(struct platform_device *pdev)
 err_idmac_init:
 err_attach_irq:
 	ipu_irq_detach_irq(&ipu_data, pdev);
-	clk_disable(ipu_data.ipu_clk);
+	clk_disable_unprepare(ipu_data.ipu_clk);
 	clk_put(ipu_data.ipu_clk);
 err_clk_get:
 	iounmap(ipu_data.reg_ic);
@@ -1765,7 +1765,7 @@ static int __exit ipu_remove(struct platform_device *pdev)
 
 	ipu_idmac_exit(ipu);
 	ipu_irq_detach_irq(ipu, pdev);
-	clk_disable(ipu->ipu_clk);
+	clk_disable_unprepare(ipu->ipu_clk);
 	clk_put(ipu->ipu_clk);
 	iounmap(ipu->reg_ic);
 	iounmap(ipu->reg_ipu);
-- 
1.7.9.5

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

* [PATCH 17/40] ARM i.MX5: prepare gpc_dvfs_clk
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (15 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 16/40] dmaengine i.MX ipu: clk_prepare/unprepare clock Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 18/40] ARM i.MX: prepare for common clock framework Sascha Hauer
                   ` (22 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/mm-imx5.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index 05250ae..d9936ce 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -32,6 +32,7 @@ static void imx5_idle(void)
 		gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
 		if (IS_ERR(gpc_dvfs_clk))
 			return;
+		clk_prepare(gpc_dvfs_clk);
 	}
 	clk_enable(gpc_dvfs_clk);
 	mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
-- 
1.7.9.5

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

* [PATCH 18/40] ARM i.MX: prepare for common clock framework
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (16 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 17/40] ARM i.MX5: prepare gpc_dvfs_clk Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 19/40] ARM i.MX timer: request correct clock Sascha Hauer
                   ` (21 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

- Add necessary #ifdefs for CONFIG_COMMON_CLOCK
- Add a global spinlock to protect the CCM registers

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/clk.h                |   44 ++++++++++++++++++++++++++++++++
 arch/arm/plat-mxc/clock.c              |   11 ++++++++
 arch/arm/plat-mxc/include/mach/clock.h |    4 +++
 3 files changed, 59 insertions(+)
 create mode 100644 arch/arm/mach-imx/clk.h

diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
new file mode 100644
index 0000000..2f1a7b2
--- /dev/null
+++ b/arch/arm/mach-imx/clk.h
@@ -0,0 +1,44 @@
+#ifndef __MACH_IMX_CLK_H
+#define __MACH_IMX_CLK_H
+
+#include <linux/spinlock.h>
+#include <linux/clk-provider.h>
+#include <mach/clock.h>
+
+struct clk *imx_clk_pllv1(const char *name, char *parent,
+		void __iomem *base);
+
+static inline struct clk *imx_clk_fixed(const char *name, int rate)
+{
+	return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
+}
+
+static inline struct clk *imx_clk_divider(const char *name, const char *parent,
+		void __iomem *reg, u8 shift, u8 width)
+{
+	return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
+			reg, shift, width, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_gate(const char *name, const char *parent,
+		void __iomem *reg, u8 shift)
+{
+	return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+			shift, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
+		u8 shift, u8 width, char **parents, int num_parents)
+{
+	return clk_register_mux(NULL, name, parents, num_parents, 0, reg, shift,
+			width, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_fixed_factor(const char *name,
+		const char *parent, unsigned int mult, unsigned int div)
+{
+	return clk_register_fixed_factor(NULL, name, parent,
+			CLK_SET_RATE_PARENT, mult, div);
+}
+
+#endif
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 2ed3ab1..5079787 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -41,6 +41,7 @@
 #include <mach/clock.h>
 #include <mach/hardware.h>
 
+#ifndef CONFIG_COMMON_CLK
 static LIST_HEAD(clocks);
 static DEFINE_MUTEX(clocks_mutex);
 
@@ -200,6 +201,16 @@ struct clk *clk_get_parent(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_get_parent);
 
+#else
+
+/*
+ * Lock to protect the clock module (ccm) registers. Used
+ * on all i.MXs
+ */
+DEFINE_SPINLOCK(imx_ccm_lock);
+
+#endif /* CONFIG_COMMON_CLK */
+
 /*
  * Get the resulting clock rate from a PLL register value and the input
  * frequency. PLLs with this register layout can at least be found on
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
index 753a598..bd940c7 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -23,6 +23,7 @@
 #ifndef __ASSEMBLY__
 #include <linux/list.h>
 
+#ifndef CONFIG_COMMON_CLK
 struct module;
 
 struct clk {
@@ -59,6 +60,9 @@ struct clk {
 
 int clk_register(struct clk *clk);
 void clk_unregister(struct clk *clk);
+#endif /* CONFIG_COMMON_CLK */
+
+extern spinlock_t imx_ccm_lock;
 
 unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref);
 
-- 
1.7.9.5

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

* [PATCH 19/40] ARM i.MX timer: request correct clock
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (17 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 18/40] ARM i.MX: prepare for common clock framework Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 20/40] ARM i.MX: Add common clock support for pllv1 Sascha Hauer
                   ` (20 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

We used to pass the timer clock directly to mxc_timer_init. We
should instead request the correct clock. This is an intermediate
step: For now we request the clock in the timer code when NULL
is passed as clock.
Also, the gpt on some i.MX have an additional ipg clock which can
be gated. Request and enable this.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/plat-mxc/time.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 7daf7c9..99f958c 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -25,6 +25,7 @@
 #include <linux/irq.h>
 #include <linux/clockchips.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 
 #include <mach/hardware.h>
 #include <asm/sched_clock.h>
@@ -282,6 +283,19 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
 void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
 {
 	uint32_t tctl_val;
+	struct clk *timer_ipg_clk;
+
+	if (!timer_clk) {
+		timer_clk = clk_get_sys("imx-gpt.0", "per");
+		if (IS_ERR(timer_clk)) {
+			pr_err("i.MX timer: unable to get clk\n");
+			return;
+		}
+
+		timer_ipg_clk = clk_get_sys("imx-gpt.0", "ipg");
+		if (!IS_ERR(timer_ipg_clk))
+			clk_prepare_enable(timer_ipg_clk);
+	}
 
 	clk_prepare_enable(timer_clk);
 
-- 
1.7.9.5

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

* [PATCH 20/40] ARM i.MX: Add common clock support for pllv1
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (18 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 19/40] ARM i.MX timer: request correct clock Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 21/40] ARM i.MX: Add common clock support for pllv2 Sascha Hauer
                   ` (19 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

The pllv1 is found on i.MX1, i.M25, i.MX27, i.MX31 and i.MX35.
Currently only reading the rate is supported.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/Makefile    |    2 ++
 arch/arm/mach-imx/clk-pllv1.c |   59 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)
 create mode 100644 arch/arm/mach-imx/clk-pllv1.c

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index ab939c5..7e71b39 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -11,6 +11,8 @@ obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-i
 
 obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
 
+obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o
+
 # Support for CMOS sensor interface
 obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
 
diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c
new file mode 100644
index 0000000..afbd95f
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv1.c
@@ -0,0 +1,59 @@
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include "clk.h"
+
+/**
+ * pll v1
+ *
+ * @clk_hw	clock source
+ * @parent	the parent clock name
+ * @base	base address of pll registers
+ *
+ * PLL clock version 1, found on i.MX1/21/25/27/31/35
+ */
+struct clk_pllv1 {
+	struct clk_hw	hw;
+	void __iomem	*base;
+	char		*parent;
+};
+
+#define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk))
+
+static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_pllv1 *pll = to_clk_pllv1(hw);
+
+	return mxc_decode_pll(readl(pll->base), parent_rate);
+}
+
+struct clk_ops clk_pllv1_ops = {
+	.recalc_rate = clk_pllv1_recalc_rate,
+};
+
+struct clk *imx_clk_pllv1(const char *name, char *parent,
+		void __iomem *base)
+{
+	struct clk_pllv1 *pll;
+	struct clk *clk;
+
+	pll = kmalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return NULL;
+
+	pll->base = base;
+	pll->parent = parent;
+
+	clk = clk_register(NULL, name, &clk_pllv1_ops, &pll->hw, &pll->parent,
+			1, 0);
+	if (!clk)
+		kfree(pll);
+
+	return clk;
+}
-- 
1.7.9.5

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

* [PATCH 21/40] ARM i.MX: Add common clock support for pllv2
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (19 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 20/40] ARM i.MX: Add common clock support for pllv1 Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 22/40] ARM: imx: add common clock support for pllv3 Sascha Hauer
                   ` (18 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

This PLL is found on i.MX51 and i.MX53

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/Makefile    |    2 +-
 arch/arm/mach-imx/clk-pllv2.c |  243 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/clk.h       |    3 +
 3 files changed, 247 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-pllv2.c

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 7e71b39..0c0e5c4 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-i
 
 obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
 
-obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o
+obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o
 
 # Support for CMOS sensor interface
 obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c
new file mode 100644
index 0000000..30f7941
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv2.c
@@ -0,0 +1,243 @@
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+
+#include <asm/div64.h>
+
+#include "clk.h"
+
+#define to_clk_pllv2(clk) (container_of(clk, struct clk_pllv2, clk))
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL			0x00
+#define MXC_PLL_DP_CONFIG		0x04
+#define MXC_PLL_DP_OP			0x08
+#define MXC_PLL_DP_MFD			0x0C
+#define MXC_PLL_DP_MFN			0x10
+#define MXC_PLL_DP_MFNMINUS		0x14
+#define MXC_PLL_DP_MFNPLUS		0x18
+#define MXC_PLL_DP_HFS_OP		0x1C
+#define MXC_PLL_DP_HFS_MFD		0x20
+#define MXC_PLL_DP_HFS_MFN		0x24
+#define MXC_PLL_DP_MFN_TOGC		0x28
+#define MXC_PLL_DP_DESTAT		0x2c
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_MUL_CTRL		0x2000
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN	0x1000
+#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET	12
+#define MXC_PLL_DP_CTL_ADE		0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV	0x400
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK	(3 << 8)
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET	8
+#define MXC_PLL_DP_CTL_HFSM		0x80
+#define MXC_PLL_DP_CTL_PRE		0x40
+#define MXC_PLL_DP_CTL_UPEN		0x20
+#define MXC_PLL_DP_CTL_RST		0x10
+#define MXC_PLL_DP_CTL_RCP		0x8
+#define MXC_PLL_DP_CTL_PLM		0x4
+#define MXC_PLL_DP_CTL_BRM0		0x2
+#define MXC_PLL_DP_CTL_LRF		0x1
+
+#define MXC_PLL_DP_CONFIG_BIST		0x8
+#define MXC_PLL_DP_CONFIG_SJC_CE	0x4
+#define MXC_PLL_DP_CONFIG_AREN		0x2
+#define MXC_PLL_DP_CONFIG_LDREQ		0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET	4
+#define MXC_PLL_DP_OP_MFI_MASK		(0xF << 4)
+#define MXC_PLL_DP_OP_PDF_OFFSET	0
+#define MXC_PLL_DP_OP_PDF_MASK		0xF
+
+#define MXC_PLL_DP_MFD_OFFSET		0
+#define MXC_PLL_DP_MFD_MASK		0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET		0x0
+#define MXC_PLL_DP_MFN_MASK		0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_TOGC_TOG_DIS	(1 << 17)
+#define MXC_PLL_DP_MFN_TOGC_TOG_EN	(1 << 16)
+#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET	0x0
+#define MXC_PLL_DP_MFN_TOGC_CNT_MASK	0xFFFF
+
+#define MXC_PLL_DP_DESTAT_TOG_SEL	(1 << 31)
+#define MXC_PLL_DP_DESTAT_MFN		0x07FFFFFF
+
+#define MAX_DPLL_WAIT_TRIES	1000 /* 1000 * udelay(1) = 1ms */
+
+struct clk_pllv2 {
+	struct clk_hw	hw;
+	void __iomem	*base;
+	char		*parent;
+};
+
+static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+	unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+	void __iomem *pllbase;
+	s64 temp;
+	struct clk_pllv2 *pll = to_clk_pllv2(hw);
+
+	pllbase = pll->base;
+
+	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+	dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+	if (pll_hfsm == 0) {
+		dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+	} else {
+		dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+	}
+	pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+	mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+	mfi = (mfi <= 5) ? 5 : mfi;
+	mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+	mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+	/* Sign extend to 32-bits */
+	if (mfn >= 0x04000000) {
+		mfn |= 0xFC000000;
+		mfn_abs = -mfn;
+	}
+
+	ref_clk = 2 * parent_rate;
+	if (dbl != 0)
+		ref_clk *= 2;
+
+	ref_clk /= (pdf + 1);
+	temp = (u64) ref_clk * mfn_abs;
+	do_div(temp, mfd + 1);
+	if (mfn < 0)
+		temp = -temp;
+	temp = (ref_clk * mfi) + temp;
+
+	return temp;
+}
+
+static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate)
+{
+	struct clk_pllv2 *pll = to_clk_pllv2(hw);
+	u32 reg;
+	void __iomem *pllbase;
+	long mfi, pdf, mfn, mfd = 999999;
+	s64 temp64;
+	unsigned long quad_parent_rate;
+	unsigned long pll_hfsm, dp_ctl;
+	unsigned long parent_rate;
+
+	parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+
+	pllbase = pll->base;
+
+	quad_parent_rate = 4 * parent_rate;
+	pdf = mfi = -1;
+	while (++pdf < 16 && mfi < 5)
+		mfi = rate * (pdf+1) / quad_parent_rate;
+	if (mfi > 15)
+		return -EINVAL;
+	pdf--;
+
+	temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
+	do_div(temp64, quad_parent_rate/1000000);
+	mfn = (long)temp64;
+
+	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+	/* use dpdck0_2 */
+	__raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+	if (pll_hfsm == 0) {
+		reg = mfi << 4 | pdf;
+		__raw_writel(reg, pllbase + MXC_PLL_DP_OP);
+		__raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
+		__raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
+	} else {
+		reg = mfi << 4 | pdf;
+		__raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
+		__raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
+		__raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
+	}
+
+	return 0;
+}
+
+static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long *prate)
+{
+	return rate;
+}
+
+static int clk_pllv2_prepare(struct clk_hw *hw)
+{
+	struct clk_pllv2 *pll = to_clk_pllv2(hw);
+	u32 reg;
+	void __iomem *pllbase;
+	int i = 0;
+
+	pllbase = pll->base;
+	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
+	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+
+	/* Wait for lock */
+	do {
+		reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+		if (reg & MXC_PLL_DP_CTL_LRF)
+			break;
+
+		udelay(1);
+	} while (++i < MAX_DPLL_WAIT_TRIES);
+
+	if (i == MAX_DPLL_WAIT_TRIES) {
+		pr_err("MX5: pll locking failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void clk_pllv2_unprepare(struct clk_hw *hw)
+{
+	struct clk_pllv2 *pll = to_clk_pllv2(hw);
+	u32 reg;
+	void __iomem *pllbase;
+
+	pllbase = pll->base;
+	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+}
+
+struct clk_ops clk_pllv2_ops = {
+	.prepare = clk_pllv2_prepare,
+	.unprepare = clk_pllv2_unprepare,
+	.recalc_rate = clk_pllv2_recalc_rate,
+	.round_rate = clk_pllv2_round_rate,
+	.set_rate = clk_pllv2_set_rate,
+};
+
+struct clk *imx_clk_pllv2(const char *name, char *parent,
+		void __iomem *base)
+{
+	struct clk_pllv2 *pll;
+	struct clk *clk;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return NULL;
+
+	pll->base = base;
+	pll->parent = parent;
+
+	clk = clk_register(NULL, name, &clk_pllv2_ops, &pll->hw, &pll->parent, 1, 0);
+	if (!clk)
+		kfree(pll);
+
+	return clk;
+}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 2f1a7b2..7897d5b 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -8,6 +8,9 @@
 struct clk *imx_clk_pllv1(const char *name, char *parent,
 		void __iomem *base);
 
+struct clk *imx_clk_pllv2(const char *name, char *parent,
+		void __iomem *base);
+
 static inline struct clk *imx_clk_fixed(const char *name, int rate)
 {
 	return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
-- 
1.7.9.5

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

* [PATCH 22/40] ARM: imx: add common clock support for pllv3
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (20 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 21/40] ARM i.MX: Add common clock support for pllv2 Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 23/40] ARM i.MX: Add common clock support for 2bit gate Sascha Hauer
                   ` (17 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

This PLL is found on i.MX6 SoCs

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/Makefile    |    2 +-
 arch/arm/mach-imx/clk-pllv3.c |  408 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/clk.h       |   13 ++
 3 files changed, 422 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-pllv3.c

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 0c0e5c4..66bc6be 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-i
 
 obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
 
-obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o
+obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o
 
 # Support for CMOS sensor interface
 obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
new file mode 100644
index 0000000..6f328f1
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv3.c
@@ -0,0 +1,408 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include "clk.h"
+
+#define PLL_NUM_OFFSET		0x10
+#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)
+
+/**
+ * struct clk_pllv3 - IMX PLL clock version 3
+ * @clk_hw:	 clock source
+ * @base:	 base address of PLL registers
+ * @powerup_set: set POWER bit to power up the PLL
+ * @gate_mask:	 mask of gate bits
+ * @div_mask:	 mask of divider bits
+ *
+ * IMX PLL clock version 3, found on i.MX6 series.  Divider for pllv3
+ * is actually a multiplier, and always sits@bit 0.
+ */
+struct clk_pllv3 {
+	struct clk_hw	hw;
+	void __iomem	*base;
+	bool		powerup_set;
+	u32		gate_mask;
+	u32		div_mask;
+};
+
+#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
+
+static int clk_pllv3_prepare(struct clk_hw *hw)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+	unsigned long timeout = jiffies + msecs_to_jiffies(10);
+	u32 val;
+
+	val = readl_relaxed(pll->base);
+	val &= ~BM_PLL_BYPASS;
+	if (pll->powerup_set)
+		val |= BM_PLL_POWER;
+	else
+		val &= ~BM_PLL_POWER;
+	writel_relaxed(val, pll->base);
+
+	/* Wait for PLL to lock */
+	while (!(readl_relaxed(pll->base) & BM_PLL_LOCK))
+		if (time_after(jiffies, timeout))
+			return -ETIMEDOUT;
+
+	return 0;
+}
+
+static void clk_pllv3_unprepare(struct clk_hw *hw)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+	u32 val;
+
+	val = readl_relaxed(pll->base);
+	val |= BM_PLL_BYPASS;
+	if (pll->powerup_set)
+		val &= ~BM_PLL_POWER;
+	else
+		val |= BM_PLL_POWER;
+	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 |= pll->gate_mask;
+	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 &= ~pll->gate_mask;
+	writel_relaxed(val, pll->base);
+}
+
+static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
+					   unsigned long parent_rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+	u32 div = readl_relaxed(pll->base)  & pll->div_mask;
+
+	return (div == 1) ? parent_rate * 22 : parent_rate * 20;
+}
+
+static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
+				 unsigned long *prate)
+{
+	unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+
+	return (rate >= parent_rate * 22) ? parent_rate * 22 :
+					    parent_rate * 20;
+}
+
+static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+	unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+	u32 val, div;
+
+	if (rate == parent_rate * 22)
+		div = 1;
+	else if (rate == parent_rate * 20)
+		div = 0;
+	else
+		return -EINVAL;
+
+	val = readl_relaxed(pll->base);
+	val &= ~pll->div_mask;
+	val |= div;
+	writel_relaxed(val, pll->base);
+
+	return 0;
+}
+
+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,
+};
+
+static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+	u32 div = readl_relaxed(pll->base) & pll->div_mask;
+
+	return parent_rate * div / 2;
+}
+
+static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long *prate)
+{
+	unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+	unsigned long min_rate = parent_rate * 54 / 2;
+	unsigned long max_rate = parent_rate * 108 / 2;
+	u32 div;
+
+	if (rate > max_rate)
+		rate = max_rate;
+	else if (rate < min_rate)
+		rate = min_rate;
+	div = rate * 2 / parent_rate;
+
+	return parent_rate * div / 2;
+}
+
+static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+	unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+	unsigned long min_rate = parent_rate * 54 / 2;
+	unsigned long max_rate = parent_rate * 108 / 2;
+	u32 val, div;
+
+	if (rate < min_rate || rate > max_rate)
+		return -EINVAL;
+
+	div = rate * 2 / parent_rate;
+	val = readl_relaxed(pll->base);
+	val &= ~pll->div_mask;
+	val |= div;
+	writel_relaxed(val, pll->base);
+
+	return 0;
+}
+
+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,
+};
+
+static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+	u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
+	u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
+	u32 div = readl_relaxed(pll->base) & pll->div_mask;
+
+	return (parent_rate * div) + ((parent_rate / mfd) * mfn);
+}
+
+static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long *prate)
+{
+	unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+	unsigned long min_rate = parent_rate * 27;
+	unsigned long max_rate = parent_rate * 54;
+	u32 div;
+	u32 mfn, mfd = 1000000;
+	s64 temp64;
+
+	if (rate > max_rate)
+		rate = max_rate;
+	else if (rate < min_rate)
+		rate = min_rate;
+
+	div = rate / parent_rate;
+	temp64 = (u64) (parent_rate - div * parent_rate);
+	temp64 *= mfd;
+	do_div(temp64, parent_rate);
+	mfn = temp64;
+
+	return parent_rate * div + parent_rate / mfd * mfn;
+}
+
+static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+	unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+	unsigned long min_rate = parent_rate * 27;
+	unsigned long max_rate = parent_rate * 54;
+	u32 val, div;
+	u32 mfn, mfd = 1000000;
+	s64 temp64;
+
+	if (rate < min_rate || rate > max_rate)
+		return -EINVAL;
+
+	div = rate / parent_rate;
+	temp64 = (u64) (rate - div * parent_rate);
+	temp64 *= mfd;
+	do_div(temp64, parent_rate);
+	mfn = temp64;
+
+	val = readl_relaxed(pll->base);
+	val &= ~pll->div_mask;
+	val |= div;
+	writel_relaxed(val, pll->base);
+	writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
+	writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
+
+	return 0;
+}
+
+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,
+};
+
+static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+	u32 div = readl_relaxed(pll->base) & pll->div_mask;
+
+	switch (div) {
+	case 0:
+		return 25000000;
+	case 1:
+		return 50000000;
+	case 2:
+		return 100000000;
+	case 3:
+		return 125000000;
+	}
+
+	return 0;
+}
+
+static long clk_pllv3_enet_round_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *prate)
+{
+	if (rate >= 125000000)
+		rate = 125000000;
+	else if (rate >= 100000000)
+		rate = 100000000;
+	else if (rate >= 50000000)
+		rate = 50000000;
+	else
+		rate = 25000000;
+	return rate;
+}
+
+static int clk_pllv3_enet_set_rate(struct clk_hw *hw, unsigned long rate)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+	u32 val, div;
+
+	switch (rate) {
+	case 25000000:
+		div = 0;
+		break;
+	case 50000000:
+		div = 1;
+		break;
+	case 100000000:
+		div = 2;
+		break;
+	case 125000000:
+		div = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	val = readl_relaxed(pll->base);
+	val &= ~pll->div_mask;
+	val |= div;
+	writel_relaxed(val, pll->base);
+
+	return 0;
+}
+
+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,
+	.round_rate	= clk_pllv3_enet_round_rate,
+	.set_rate	= clk_pllv3_enet_set_rate,
+};
+
+static const struct clk_ops clk_pllv3_mlb_ops = {
+	.prepare	= clk_pllv3_prepare,
+	.unprepare	= clk_pllv3_unprepare,
+	.enable		= clk_pllv3_enable,
+	.disable	= clk_pllv3_disable,
+};
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+			  char *parent_name, void __iomem *base,
+			  u32 gate_mask, u32 div_mask)
+{
+	struct clk_pllv3 *pll;
+	const struct clk_ops *ops;
+	struct clk *clk;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return NULL;
+
+	switch (type) {
+	case IMX_PLLV3_SYS:
+		ops = &clk_pllv3_sys_ops;
+		break;
+	case IMX_PLLV3_USB:
+		ops = &clk_pllv3_ops;
+		pll->powerup_set = true;
+		break;
+	case IMX_PLLV3_AV:
+		ops = &clk_pllv3_av_ops;
+		break;
+	case IMX_PLLV3_ENET:
+		ops = &clk_pllv3_enet_ops;
+		break;
+	case IMX_PLLV3_MLB:
+		ops = &clk_pllv3_mlb_ops;
+		break;
+	default:
+		ops = &clk_pllv3_ops;
+	}
+	pll->base = base;
+	pll->gate_mask = gate_mask;
+	pll->div_mask = div_mask;
+
+	clk = clk_register(NULL, name, ops, &pll->hw, &parent_name, 1, 0);
+	if (!clk)
+		kfree(pll);
+
+	return clk;
+}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 7897d5b..96ac3b1 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -5,12 +5,25 @@
 #include <linux/clk-provider.h>
 #include <mach/clock.h>
 
+enum imx_pllv3_type {
+	IMX_PLLV3_GENERIC,
+	IMX_PLLV3_SYS,
+	IMX_PLLV3_USB,
+	IMX_PLLV3_AV,
+	IMX_PLLV3_ENET,
+	IMX_PLLV3_MLB,
+};
+
 struct clk *imx_clk_pllv1(const char *name, char *parent,
 		void __iomem *base);
 
 struct clk *imx_clk_pllv2(const char *name, char *parent,
 		void __iomem *base);
 
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+		char *parent_name, void __iomem *base, u32 gate_mask,
+		u32 div_mask);
+
 static inline struct clk *imx_clk_fixed(const char *name, int rate)
 {
 	return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
-- 
1.7.9.5

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

* [PATCH 23/40] ARM i.MX: Add common clock support for 2bit gate
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (21 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 22/40] ARM: imx: add common clock support for pllv3 Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-19  7:00   ` Shawn Guo
  2012-04-10 13:45 ` [PATCH 24/40] ARM: imx: add common clock support for pfd Sascha Hauer
                   ` (16 subsequent siblings)
  39 siblings, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

This gate consists of two bits:

0b00: clk disabled
0b01: clk enabled in run mode and disabled in sleep mode
0b11: clk enabled

Currently only disabled and enabled are supported. As it's unlikely
that we find something like this in another SoC create a i.MX specific
clk helper for this.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/Makefile    |    2 +-
 arch/arm/mach-imx/clk-gate2.c |  125 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/clk.h       |   12 ++++
 3 files changed, 138 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-gate2.c

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 66bc6be..1b3f2ae 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-i
 
 obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
 
-obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o
+obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o
 
 # Support for CMOS sensor interface
 obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
new file mode 100644
index 0000000..1ce9f44
--- /dev/null
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ * 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.
+ *
+ * Gated clock implementation
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/string.h>
+
+/**
+ * DOC: basic gatable clock which can gate and ungate it's ouput
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parent is (un)prepared
+ * enable - clk_enable and clk_disable are functional & control gating
+ * rate - inherits rate from parent.  No clk_set_rate support
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
+
+static int clk_gate2_enable(struct clk_hw *hw)
+{
+	struct clk_gate *gate = to_clk_gate(hw);
+	u32 reg;
+	unsigned long flags = 0;
+
+	if (gate->lock)
+		spin_lock_irqsave(gate->lock, flags);
+
+	reg = readl(gate->reg);
+	reg |= 3 << gate->bit_idx;
+	writel(reg, gate->reg);
+
+	if (gate->lock)
+		spin_unlock_irqrestore(gate->lock, flags);
+
+	return 0;
+}
+
+static void clk_gate2_disable(struct clk_hw *hw)
+{
+	struct clk_gate *gate = to_clk_gate(hw);
+	u32 reg;
+	unsigned long flags = 0;
+
+	if (gate->lock)
+		spin_lock_irqsave(gate->lock, flags);
+
+	reg = readl(gate->reg);
+	reg &= ~(3 << gate->bit_idx);
+	writel(reg, gate->reg);
+
+	if (gate->lock)
+		spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int clk_gate2_is_enabled(struct clk_hw *hw)
+{
+	u32 reg;
+	struct clk_gate *gate = to_clk_gate(hw);
+
+	reg = readl(gate->reg);
+
+	if (((reg >> gate->bit_idx) & 3) == 3)
+		return 1;
+
+	return 0;
+}
+
+static struct clk_ops clk_gate2_ops = {
+	.enable = clk_gate2_enable,
+	.disable = clk_gate2_disable,
+	.is_enabled = clk_gate2_is_enabled,
+};
+
+struct clk *clk_register_gate2(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 bit_idx,
+		u8 clk_gate2_flags, spinlock_t *lock)
+{
+	struct clk_gate *gate;
+	struct clk *clk;
+
+	gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+
+	if (!gate) {
+		pr_err("%s: could not allocate gated clk\n", __func__);
+		return NULL;
+	}
+
+	/* struct clk_gate assignments */
+	gate->reg = reg;
+	gate->bit_idx = bit_idx;
+	gate->flags = clk_gate2_flags;
+	gate->lock = lock;
+
+	if (parent_name) {
+		gate->parent[0] = kstrdup(parent_name, GFP_KERNEL);
+		if (!gate->parent[0])
+			goto out;
+	}
+
+	clk = clk_register(dev, name,
+			&clk_gate2_ops, &gate->hw,
+			gate->parent,
+			(parent_name ? 1 : 0),
+			flags);
+	if (clk)
+		return clk;
+out:
+	kfree(gate->parent[0]);
+	kfree(gate);
+
+	return NULL;
+}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 96ac3b1..fb44f03 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -5,6 +5,11 @@
 #include <linux/clk-provider.h>
 #include <mach/clock.h>
 
+struct clk *clk_register_gate2(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 bit_idx,
+		u8 clk_gate_flags, spinlock_t *lock);
+
 enum imx_pllv3_type {
 	IMX_PLLV3_GENERIC,
 	IMX_PLLV3_SYS,
@@ -43,6 +48,13 @@ static inline struct clk *imx_clk_gate(const char *name, const char *parent,
 			shift, 0, &imx_ccm_lock);
 }
 
+static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
+		void __iomem *reg, u8 shift)
+{
+	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+			shift, 0, &imx_ccm_lock);
+}
+
 static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
 		u8 shift, u8 width, char **parents, int num_parents)
 {
-- 
1.7.9.5

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

* [PATCH 24/40] ARM: imx: add common clock support for pfd
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (22 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 23/40] ARM i.MX: Add common clock support for 2bit gate Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 25/40] ARM: imx: add common clock support for clk busy Sascha Hauer
                   ` (15 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/Makefile  |    3 +-
 arch/arm/mach-imx/clk-pfd.c |  138 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/clk.h     |    3 +
 3 files changed, 143 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-pfd.c

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 1b3f2ae..4d6be8d 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -11,7 +11,8 @@ obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-i
 
 obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
 
-obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o
+obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
+			    clk-pfd.o
 
 # Support for CMOS sensor interface
 obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
diff --git a/arch/arm/mach-imx/clk-pfd.c b/arch/arm/mach-imx/clk-pfd.c
new file mode 100644
index 0000000..3cd2a0c
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pfd.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include "clk.h"
+
+/**
+ * struct clk_pfd - IMX PFD clock
+ * @clk_hw:	clock source
+ * @reg:	PFD register address
+ * @idx:	the index of PFD encoded in the register
+ *
+ * PFD clock found on i.MX6 series.  Each register for PFD has 4 clk_pfd
+ * data encoded, and member idx is used to specify the one.  And each
+ * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc.
+ */
+struct clk_pfd {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	u8		idx;
+};
+
+#define to_clk_pfd(_hw) container_of(_hw, struct clk_pfd, hw)
+
+#define SET	0x4
+#define CLR	0x8
+#define OTG	0xc
+
+static int clk_pfd_enable(struct clk_hw *hw)
+{
+	struct clk_pfd *pfd = to_clk_pfd(hw);
+
+	writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
+
+	return 0;
+}
+
+static void clk_pfd_disable(struct clk_hw *hw)
+{
+	struct clk_pfd *pfd = to_clk_pfd(hw);
+
+	writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
+}
+
+static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct clk_pfd *pfd = to_clk_pfd(hw);
+	u64 tmp = parent_rate;
+	u8 frac = (readl_relaxed(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
+
+	tmp *= 18;
+	do_div(tmp, frac);
+
+	return tmp;
+}
+
+static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *prate)
+{
+	unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+	u64 tmp = parent_rate;
+	u8 frac;
+
+	tmp = tmp * 18 + rate / 2;
+	do_div(tmp, rate);
+	frac = tmp;
+	if (frac < 12)
+		frac = 12;
+	else if (frac > 35)
+		frac = 35;
+	tmp = parent_rate;
+	tmp *= 18;
+	do_div(tmp, frac);
+
+	return tmp;
+}
+
+static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate)
+{
+	struct clk_pfd *pfd = to_clk_pfd(hw);
+	unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+	u64 tmp = parent_rate;
+	u8 frac;
+
+	tmp = tmp * 18 + rate / 2;
+	do_div(tmp, rate);
+	frac = tmp;
+	if (frac < 12)
+		frac = 12;
+	else if (frac > 35)
+		frac = 35;
+
+	writel_relaxed(0x3f << (pfd->idx * 8), pfd->reg + CLR);
+	writel_relaxed(frac << (pfd->idx * 8), pfd->reg + SET);
+
+	return 0;
+}
+
+static const struct clk_ops clk_pfd_ops = {
+	.enable		= clk_pfd_enable,
+	.disable	= clk_pfd_disable,
+	.recalc_rate	= clk_pfd_recalc_rate,
+	.round_rate	= clk_pfd_round_rate,
+	.set_rate	= clk_pfd_set_rate,
+};
+
+struct clk *imx_clk_pfd(const char *name, char *parent_name,
+			void __iomem *reg, u8 idx)
+{
+	struct clk_pfd *pfd;
+	struct clk *clk;
+
+	pfd = kzalloc(sizeof(*pfd), GFP_KERNEL);
+	if (!pfd)
+		return NULL;
+	pfd->reg = reg;
+	pfd->idx = idx;
+
+	clk = clk_register(NULL, name, &clk_pfd_ops, &pfd->hw,
+			   &parent_name, 1, 0);
+	if (!clk)
+		kfree(pfd);
+
+	return clk;
+}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index fb44f03..50f5638 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -29,6 +29,9 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 		char *parent_name, void __iomem *base, u32 gate_mask,
 		u32 div_mask);
 
+struct clk *imx_clk_pfd(const char *name, char *parent_name,
+		void __iomem *reg, u8 idx);
+
 static inline struct clk *imx_clk_fixed(const char *name, int rate)
 {
 	return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
-- 
1.7.9.5

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

* [PATCH 25/40] ARM: imx: add common clock support for clk busy
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (23 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 24/40] ARM: imx: add common clock support for pfd Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 18:59   ` Stephen Boyd
                     ` (2 more replies)
  2012-04-10 13:45 ` [PATCH 26/40] ARM i.MX3: Make ccm base address a variable Sascha Hauer
                   ` (14 subsequent siblings)
  39 siblings, 3 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/Makefile   |    2 +-
 arch/arm/mach-imx/clk-busy.c |  167 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/clk.h      |    8 ++
 3 files changed, 176 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-busy.c

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 4d6be8d..ae0a779 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-i
 obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
 
 obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
-			    clk-pfd.o
+			    clk-pfd.o clk-busy.o
 
 # Support for CMOS sensor interface
 obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c
new file mode 100644
index 0000000..9450f0b
--- /dev/null
+++ b/arch/arm/mach-imx/clk-busy.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include "clk.h"
+
+static int clk_busy_wait(void __iomem *reg, u8 shift)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(10);
+
+	while (readl_relaxed(reg) & (1 << shift))
+		if (time_after(jiffies, timeout))
+			return -ETIMEDOUT;
+
+	return 0;
+}
+
+struct clk_busy_divider {
+	struct clk_hw hw;
+	void __iomem *reg;
+	u8 shift;
+	struct clk_divider div;
+	const struct clk_ops *div_ops;
+};
+
+#define to_clk_busy_divider(_hw) container_of(_hw, struct clk_busy_divider, hw)
+
+static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct clk_busy_divider *busy = to_clk_busy_divider(hw);
+
+	return busy->div_ops->recalc_rate(&busy->div.hw, parent_rate);
+}
+
+static long clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long *prate)
+{
+	struct clk_busy_divider *busy = to_clk_busy_divider(hw);
+
+	return busy->div_ops->round_rate(&busy->div.hw, rate, prate);
+}
+
+static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate)
+{
+	struct clk_busy_divider *busy = to_clk_busy_divider(hw);
+	int ret;
+
+	ret = busy->div_ops->set_rate(&busy->div.hw, rate);
+	if (!ret)
+		ret = clk_busy_wait(busy->reg, busy->shift);
+
+	return ret;
+}
+
+static struct clk_ops clk_busy_divider_ops = {
+	.recalc_rate = clk_busy_divider_recalc_rate,
+	.round_rate = clk_busy_divider_round_rate,
+	.set_rate = clk_busy_divider_set_rate,
+};
+
+struct clk *imx_clk_busy_divider(const char *name, char *parent_name,
+				 void __iomem *reg, u8 shift, u8 width,
+				 void __iomem *busy_reg, u8 busy_shift)
+{
+	struct clk_busy_divider *busy;
+	struct clk *clk;
+
+	busy = kzalloc(sizeof(*busy), GFP_KERNEL);
+	if (!busy)
+		return NULL;
+
+	busy->reg = busy_reg;
+	busy->shift = busy_shift;
+
+	busy->div.reg = reg;
+	busy->div.shift = shift;
+	busy->div.width = width;
+	busy->div.lock = &imx_ccm_lock;
+	busy->div_ops = &clk_divider_ops;
+
+	clk = clk_register(NULL, name, &clk_busy_divider_ops, &busy->hw,
+			   &parent_name, 1, CLK_SET_RATE_PARENT);
+	if (!clk)
+		kfree(busy);
+
+	busy->div.hw.clk = clk;
+
+	return clk;
+}
+
+struct clk_busy_mux {
+	struct clk_hw hw;
+	void __iomem *reg;
+	u8 shift;
+	struct clk_mux mux;
+	const struct clk_ops *mux_ops;
+};
+
+#define to_clk_busy_mux(_hw) container_of(_hw, struct clk_busy_mux, hw)
+
+static u8 clk_busy_mux_get_parent(struct clk_hw *hw)
+{
+	struct clk_busy_mux *busy = to_clk_busy_mux(hw);
+
+	return busy->mux_ops->get_parent(&busy->mux.hw);
+}
+
+static int clk_busy_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_busy_mux *busy = to_clk_busy_mux(hw);
+	int ret;
+
+	ret = busy->mux_ops->set_parent(&busy->mux.hw, index);
+	if (!ret)
+		ret = clk_busy_wait(busy->reg, busy->shift);
+
+	return ret;
+}
+
+struct clk_ops clk_busy_mux_ops = {
+	.get_parent = clk_busy_mux_get_parent,
+	.set_parent = clk_busy_mux_set_parent,
+};
+
+struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
+			     u8 width, void __iomem *busy_reg, u8 busy_shift,
+			     char **parent_names, int num_parents)
+{
+	struct clk_busy_mux *busy;
+	struct clk *clk;
+
+	busy = kzalloc(sizeof(*busy), GFP_KERNEL);
+	if (!busy)
+		return NULL;
+
+	busy->reg = busy_reg;
+	busy->shift = busy_shift;
+
+	busy->mux.reg = reg;
+	busy->mux.shift = shift;
+	busy->mux.width = width;
+	busy->mux.lock = &imx_ccm_lock;
+	busy->mux_ops = &clk_mux_ops;
+
+	clk = clk_register(NULL, name, &clk_busy_mux_ops, &busy->hw,
+			   parent_names, num_parents, 0);
+	if (!clk)
+		kfree(busy);
+
+	busy->mux.hw.clk = clk;
+
+	return clk;
+}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 50f5638..53ab2f5 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -44,6 +44,10 @@ static inline struct clk *imx_clk_divider(const char *name, const char *parent,
 			reg, shift, width, 0, &imx_ccm_lock);
 }
 
+struct clk *imx_clk_busy_divider(const char *name, char *parent_name,
+				 void __iomem *reg, u8 shift, u8 width,
+				 void __iomem *busy_reg, u8 busy_shift);
+
 static inline struct clk *imx_clk_gate(const char *name, const char *parent,
 		void __iomem *reg, u8 shift)
 {
@@ -65,6 +69,10 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
 			width, 0, &imx_ccm_lock);
 }
 
+struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
+			     u8 width, void __iomem *busy_reg, u8 busy_shift,
+			     char **parent_names, int num_parents);
+
 static inline struct clk *imx_clk_fixed_factor(const char *name,
 		const char *parent, unsigned int mult, unsigned int div)
 {
-- 
1.7.9.5

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

* [PATCH 26/40] ARM i.MX3: Make ccm base address a variable
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (24 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 25/40] ARM: imx: add common clock support for clk busy Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 27/40] ARM i.MX25: implement clocks using common clock framework Sascha Hauer
                   ` (13 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Instead of having a cpu_is_* in each ccm register access it
is mor efficient to make it a variable.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/crmregs-imx3.h |   79 +++++++++++++++++++-------------------
 arch/arm/mach-imx/mm-imx3.c      |    6 +++
 arch/arm/mach-imx/pm-imx3.c      |    4 +-
 3 files changed, 47 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-imx/crmregs-imx3.h b/arch/arm/mach-imx/crmregs-imx3.h
index 5314127..a1dfde5 100644
--- a/arch/arm/mach-imx/crmregs-imx3.h
+++ b/arch/arm/mach-imx/crmregs-imx3.h
@@ -24,48 +24,47 @@
 #define CKIH_CLK_FREQ_27MHZ     27000000
 #define CKIL_CLK_FREQ           32768
 
-#define MXC_CCM_BASE		(cpu_is_mx31() ? \
-MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR) : MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR))
+extern void __iomem *mx3_ccm_base;
 
 /* Register addresses */
-#define MXC_CCM_CCMR		(MXC_CCM_BASE + 0x00)
-#define MXC_CCM_PDR0		(MXC_CCM_BASE + 0x04)
-#define MXC_CCM_PDR1		(MXC_CCM_BASE + 0x08)
-#define MX35_CCM_PDR2		(MXC_CCM_BASE + 0x0C)
-#define MXC_CCM_RCSR		(MXC_CCM_BASE + 0x0C)
-#define MX35_CCM_PDR3		(MXC_CCM_BASE + 0x10)
-#define MXC_CCM_MPCTL		(MXC_CCM_BASE + 0x10)
-#define MX35_CCM_PDR4		(MXC_CCM_BASE + 0x14)
-#define MXC_CCM_UPCTL		(MXC_CCM_BASE + 0x14)
-#define MX35_CCM_RCSR		(MXC_CCM_BASE + 0x18)
-#define MXC_CCM_SRPCTL		(MXC_CCM_BASE + 0x18)
-#define MX35_CCM_MPCTL		(MXC_CCM_BASE + 0x1C)
-#define MXC_CCM_COSR		(MXC_CCM_BASE + 0x1C)
-#define MX35_CCM_PPCTL		(MXC_CCM_BASE + 0x20)
-#define MXC_CCM_CGR0		(MXC_CCM_BASE + 0x20)
-#define MX35_CCM_ACMR		(MXC_CCM_BASE + 0x24)
-#define MXC_CCM_CGR1		(MXC_CCM_BASE + 0x24)
-#define MX35_CCM_COSR		(MXC_CCM_BASE + 0x28)
-#define MXC_CCM_CGR2		(MXC_CCM_BASE + 0x28)
-#define MX35_CCM_CGR0		(MXC_CCM_BASE + 0x2C)
-#define MXC_CCM_WIMR		(MXC_CCM_BASE + 0x2C)
-#define MX35_CCM_CGR1		(MXC_CCM_BASE + 0x30)
-#define MXC_CCM_LDC		(MXC_CCM_BASE + 0x30)
-#define MX35_CCM_CGR2		(MXC_CCM_BASE + 0x34)
-#define MXC_CCM_DCVR0		(MXC_CCM_BASE + 0x34)
-#define MX35_CCM_CGR3		(MXC_CCM_BASE + 0x38)
-#define MXC_CCM_DCVR1		(MXC_CCM_BASE + 0x38)
-#define MXC_CCM_DCVR2		(MXC_CCM_BASE + 0x3C)
-#define MXC_CCM_DCVR3		(MXC_CCM_BASE + 0x40)
-#define MXC_CCM_LTR0		(MXC_CCM_BASE + 0x44)
-#define MXC_CCM_LTR1		(MXC_CCM_BASE + 0x48)
-#define MXC_CCM_LTR2		(MXC_CCM_BASE + 0x4C)
-#define MXC_CCM_LTR3		(MXC_CCM_BASE + 0x50)
-#define MXC_CCM_LTBR0		(MXC_CCM_BASE + 0x54)
-#define MXC_CCM_LTBR1		(MXC_CCM_BASE + 0x58)
-#define MXC_CCM_PMCR0		(MXC_CCM_BASE + 0x5C)
-#define MXC_CCM_PMCR1		(MXC_CCM_BASE + 0x60)
-#define MXC_CCM_PDR2		(MXC_CCM_BASE + 0x64)
+#define MXC_CCM_CCMR		0x00
+#define MXC_CCM_PDR0		0x04
+#define MXC_CCM_PDR1		0x08
+#define MX35_CCM_PDR2		0x0C
+#define MXC_CCM_RCSR		0x0C
+#define MX35_CCM_PDR3		0x10
+#define MXC_CCM_MPCTL		0x10
+#define MX35_CCM_PDR4		0x14
+#define MXC_CCM_UPCTL		0x14
+#define MX35_CCM_RCSR		0x18
+#define MXC_CCM_SRPCTL		0x18
+#define MX35_CCM_MPCTL		0x1C
+#define MXC_CCM_COSR		0x1C
+#define MX35_CCM_PPCTL		0x20
+#define MXC_CCM_CGR0		0x20
+#define MX35_CCM_ACMR		0x24
+#define MXC_CCM_CGR1		0x24
+#define MX35_CCM_COSR		0x28
+#define MXC_CCM_CGR2		0x28
+#define MX35_CCM_CGR0		0x2C
+#define MXC_CCM_WIMR		0x2C
+#define MX35_CCM_CGR1		0x30
+#define MXC_CCM_LDC		0x30
+#define MX35_CCM_CGR2		0x34
+#define MXC_CCM_DCVR0		0x34
+#define MX35_CCM_CGR3		0x38
+#define MXC_CCM_DCVR1		0x38
+#define MXC_CCM_DCVR2		0x3C
+#define MXC_CCM_DCVR3		0x40
+#define MXC_CCM_LTR0		0x44
+#define MXC_CCM_LTR1		0x48
+#define MXC_CCM_LTR2		0x4C
+#define MXC_CCM_LTR3		0x50
+#define MXC_CCM_LTBR0		0x54
+#define MXC_CCM_LTBR1		0x58
+#define MXC_CCM_PMCR0		0x5C
+#define MXC_CCM_PMCR1		0x60
+#define MXC_CCM_PDR2		0x64
 
 /* Register bit definitions */
 #define MXC_CCM_CCMR_WBEN                       (1 << 27)
diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c
index 7412738..57b39f8 100644
--- a/arch/arm/mach-imx/mm-imx3.c
+++ b/arch/arm/mach-imx/mm-imx3.c
@@ -31,6 +31,10 @@
 #include <mach/iomux-v3.h>
 #include <mach/irqs.h>
 
+#include "crmregs-imx3.h"
+
+void __iomem *mx3_ccm_base;
+
 static void imx3_idle(void)
 {
 	unsigned long reg = 0;
@@ -137,6 +141,7 @@ void __init imx31_init_early(void)
 	mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
 	arch_ioremap_caller = imx3_ioremap_caller;
 	arm_pm_idle = imx3_idle;
+	mx3_ccm_base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
 }
 
 void __init mx31_init_irq(void)
@@ -210,6 +215,7 @@ void __init imx35_init_early(void)
 	mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
 	arm_pm_idle = imx3_idle;
 	arch_ioremap_caller = imx3_ioremap_caller;
+	mx3_ccm_base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
 }
 
 void __init mx35_init_irq(void)
diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c
index b375243..822103b 100644
--- a/arch/arm/mach-imx/pm-imx3.c
+++ b/arch/arm/mach-imx/pm-imx3.c
@@ -21,14 +21,14 @@
  */
 void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode)
 {
-	int reg = __raw_readl(MXC_CCM_CCMR);
+	int reg = __raw_readl(mx3_ccm_base + MXC_CCM_CCMR);
 	reg &= ~MXC_CCM_CCMR_LPM_MASK;
 
 	switch (mode) {
 	case MX3_WAIT:
 		if (cpu_is_mx35())
 			reg |= MXC_CCM_CCMR_LPM_WAIT_MX35;
-		__raw_writel(reg, MXC_CCM_CCMR);
+		__raw_writel(reg, mx3_ccm_base + MXC_CCM_CCMR);
 		break;
 	default:
 		pr_err("Unknown cpu power mode: %d\n", mode);
-- 
1.7.9.5

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

* [PATCH 27/40] ARM i.MX25: implement clocks using common clock framework
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (25 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 26/40] ARM i.MX3: Make ccm base address a variable Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 20:10   ` Roberto Nibali
  2012-04-10 13:45 ` [PATCH 28/40] ARM i.MX1: " Sascha Hauer
                   ` (12 subsequent siblings)
  39 siblings, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/Kconfig     |    1 +
 arch/arm/mach-imx/Makefile    |    2 +-
 arch/arm/mach-imx/clk-imx25.c |  232 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 234 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-imx25.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 7561eca..0b832b1 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -48,6 +48,7 @@ config SOC_IMX21
 config SOC_IMX25
 	bool
 	select ARCH_MX25
+	select COMMON_CLK
 	select CPU_ARM926T
 	select ARCH_MXC_IOMUX_V3
 	select MXC_AVIC
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index ae0a779..173e869 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,7 +1,7 @@
 obj-$(CONFIG_SOC_IMX1) += clock-imx1.o mm-imx1.o
 obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o
 
-obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
+obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
 
 obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
 obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
new file mode 100644
index 0000000..717b8a0
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx25.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/mx25.h>
+#include "clk.h"
+
+#define CRM_BASE	MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
+
+#define CCM_MPCTL	0x00
+#define CCM_UPCTL	0x04
+#define CCM_CCTL	0x08
+#define CCM_CGCR0	0x0C
+#define CCM_CGCR1	0x10
+#define CCM_CGCR2	0x14
+#define CCM_PCDR0	0x18
+#define CCM_PCDR1	0x1C
+#define CCM_PCDR2	0x20
+#define CCM_PCDR3	0x24
+#define CCM_RCSR	0x28
+#define CCM_CRDR	0x2C
+#define CCM_DCVR0	0x30
+#define CCM_DCVR1	0x34
+#define CCM_DCVR2	0x38
+#define CCM_DCVR3	0x3c
+#define CCM_LTR0	0x40
+#define CCM_LTR1	0x44
+#define CCM_LTR2	0x48
+#define CCM_LTR3	0x4c
+#define CCM_MCR		0x64
+
+#define ccm(x)	(CRM_BASE + (x))
+
+#define clkdev(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clkname = c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	/* i.mx25 has the i.mx21 type uart */
+	clkdev("imx21-uart.0", "ipg", "uart1_ipg")
+	clkdev("imx21-uart.0", "per", "uart_ipg_per")
+	clkdev("imx21-uart.1", "ipg", "uart2_ipg")
+	clkdev("imx21-uart.1", "per", "uart_ipg_per")
+	clkdev("imx21-uart.2", "ipg", "uart3_ipg")
+	clkdev("imx21-uart.2", "per", "uart_ipg_per")
+	clkdev("imx21-uart.3", "ipg", "uart4_ipg")
+	clkdev("imx21-uart.3", "per", "uart_ipg_per")
+	clkdev("imx21-uart.4", "ipg", "uart5_ipg")
+	clkdev("imx21-uart.4", "per", "uart_ipg_per")
+	clkdev("imx-gpt.0", "ipg", "ipg")
+	clkdev("imx-gpt.0", "per", "gpt_ipg_per")
+	clkdev("mxc-ehci.0", "ipg", "ipg")
+	clkdev("mxc-ehci.0", "ahb", "usbotg_ahb")
+	clkdev("mxc-ehci.0", "per", "usbdiv")
+	clkdev("mxc-ehci.1", "ipg", "ipg")
+	clkdev("mxc-ehci.1", "ahb", "usbotg_ahb")
+	clkdev("mxc-ehci.1", "per", "usbdiv")
+	clkdev("mxc-ehci.2", "ipg", "ipg")
+	clkdev("mxc-ehci.2", "ahb", "usbotg_ahb")
+	clkdev("mxc-ehci.2", "per", "usbdiv")
+	clkdev("fsl-usb2-udc", "ipg", "ipg")
+	clkdev("fsl-usb2-udc", "ahb", "usbotg_ahb")
+	clkdev("fsl-usb2-udc", "per", "usbdiv")
+	clkdev("mxc_nand.0", NULL, "nfc_ipg_per")
+	/* i.mx25 has the i.mx35 type cspi */
+	clkdev("imx35-cspi.0", NULL, "cspi1_ipg")
+	clkdev("imx35-cspi.1", NULL, "cspi2_ipg")
+	clkdev("imx35-cspi.2", NULL, "cspi3_ipg")
+	clkdev("mxc_pwm.0", "ipg", "pwm1_ipg")
+	clkdev("mxc_pwm.0", "per", "per10")
+	clkdev("mxc_pwm.1", "ipg", "pwm1_ipg")
+	clkdev("mxc_pwm.1", "per", "per10")
+	clkdev("mxc_pwm.2", "ipg", "pwm1_ipg")
+	clkdev("mxc_pwm.2", "per", "per10")
+	clkdev("mxc_pwm.3", "ipg", "pwm1_ipg")
+	clkdev("mxc_pwm.3", "per", "per10")
+	clkdev("imx-keypad", NULL, "kpp_ipg")
+	clkdev("mx25-adc", NULL, "tsc_ipg")
+	clkdev("imx-i2c.0", NULL, "i2c_ipg_per")
+	clkdev("imx-i2c.1", NULL, "i2c_ipg_per")
+	clkdev("imx-i2c.2", NULL, "i2c_ipg_per")
+	clkdev("imx25-fec.0", "ipg", "fec_ipg")
+	clkdev("imx25-fec.0", "ahb", "fec_ahb")
+	clkdev("imxdi_rtc.0", NULL, "dryice_ipg")
+	clkdev("imx-fb.0", "per", "lcdc_ipg_per")
+	clkdev("imx-fb.0", "ipg", "lcdc_ipg")
+	clkdev("imx-fb.0", "ahb", "lcdc_ahb")
+	clkdev("imx2-wdt.0", NULL, "wdt_ipg")
+	clkdev("imx-ssi.0", "per", "ssi1_ipg_per")
+	clkdev("imx-ssi.0", "ipg", "ssi1_ipg")
+	clkdev("imx-ssi.1", "per", "ssi2_ipg_per")
+	clkdev("imx-ssi.1", "ipg", "ssi2_ipg")
+	clkdev("sdhci-esdhc-imx25.0", "per", "esdhc1_ipg_per")
+	clkdev("sdhci-esdhc-imx25.0", "ipg", "esdhc1_ipg")
+	clkdev("sdhci-esdhc-imx25.0", "ahb", "esdhc1_ahb")
+	clkdev("sdhci-esdhc-imx25.1", "per", "esdhc2_ipg_per")
+	clkdev("sdhci-esdhc-imx25.1", "ipg", "esdhc2_ipg")
+	clkdev("sdhci-esdhc-imx25.1", "ahb", "esdhc2_ahb")
+	clkdev("mx2-camera.0", "per", "csi_ipg_per")
+	clkdev("mx2-camera.0", "ipg", "csi_ipg")
+	clkdev("mx2-camera.0", "ahb", "csi_ahb")
+	clkdev(NULL, "audmux", "dummy")
+	clkdev("flexcan.0", NULL, "can1_ipg")
+	clkdev("flexcan.1", NULL, "can2_ipg")
+	/* i.mx25 has the i.mx35 type sdma */
+	clkdev("imx35-sdma", "ipg", "sdma_ipg")
+	clkdev("imx35-sdma", "ahb", "sdma_ahb")
+	clkdev(NULL, "iim", "iim_ipg")
+};
+
+static char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", };
+static char *per_sel_clks[] = { "ahb", "upll", };
+
+int __init mx25_clocks_init(void)
+{
+	imx_clk_fixed("dummy", 0);
+	imx_clk_fixed("osc", 24000000);
+	imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL));
+	imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL));
+	imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
+	imx_clk_mux("cpu_sel", ccm(CCM_CCTL), 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
+	imx_clk_divider("cpu", "cpu_sel", ccm(CCM_CCTL), 30, 2);
+	imx_clk_divider("ahb", "cpu", ccm(CCM_CCTL), 28, 2);
+	imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+	imx_clk_mux("per0_sel", ccm(CCM_MCR), 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per1_sel", ccm(CCM_MCR), 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per2_sel", ccm(CCM_MCR), 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per3_sel", ccm(CCM_MCR), 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per4_sel", ccm(CCM_MCR), 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per5_sel", ccm(CCM_MCR), 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per6_sel", ccm(CCM_MCR), 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per7_sel", ccm(CCM_MCR), 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per8_sel", ccm(CCM_MCR), 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per9_sel", ccm(CCM_MCR), 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per10_sel", ccm(CCM_MCR), 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per11_sel", ccm(CCM_MCR), 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per12_sel", ccm(CCM_MCR), 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per13_sel", ccm(CCM_MCR), 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per14_sel", ccm(CCM_MCR), 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_mux("per15_sel", ccm(CCM_MCR), 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+	imx_clk_divider("per0", "per0_sel", ccm(CCM_PCDR0), 0, 6);
+	imx_clk_divider("per1", "per1_sel", ccm(CCM_PCDR0), 8, 6);
+	imx_clk_divider("per2", "per2_sel", ccm(CCM_PCDR0), 16, 6);
+	imx_clk_divider("per3", "per3_sel", ccm(CCM_PCDR0), 24, 6);
+	imx_clk_divider("per4", "per4_sel", ccm(CCM_PCDR1), 0, 6);
+	imx_clk_divider("per5", "per5_sel", ccm(CCM_PCDR1), 8, 6);
+	imx_clk_divider("per6", "per6_sel", ccm(CCM_PCDR1), 16, 6);
+	imx_clk_divider("per7", "per7_sel", ccm(CCM_PCDR1), 24, 6);
+	imx_clk_divider("per8", "per8_sel", ccm(CCM_PCDR2), 0, 6);
+	imx_clk_divider("per9", "per9_sel", ccm(CCM_PCDR2), 8, 6);
+	imx_clk_divider("per10", "per10_sel", ccm(CCM_PCDR2), 16, 6);
+	imx_clk_divider("per11", "per11_sel", ccm(CCM_PCDR2), 24, 6);
+	imx_clk_divider("per12", "per12_sel", ccm(CCM_PCDR3), 0, 6);
+	imx_clk_divider("per13", "per13_sel", ccm(CCM_PCDR3), 8, 6);
+	imx_clk_divider("per14", "per14_sel", ccm(CCM_PCDR3), 16, 6);
+	imx_clk_divider("per15", "per15_sel", ccm(CCM_PCDR3), 24, 6);
+	imx_clk_gate("csi_ipg_per", "per0", ccm(CCM_CGCR0), 0);
+	imx_clk_gate("esdhc1_ipg_per", "per3", ccm(CCM_CGCR0),  3);
+	imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0),  4);
+	imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0),  5);
+	imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0),  6);
+	imx_clk_gate("lcdc_ipg_per", "per8", ccm(CCM_CGCR0),  7);
+	imx_clk_gate("nfc_ipg_per", "ipg_per", ccm(CCM_CGCR0),  8);
+	imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13);
+	imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14);
+	imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15);
+	imx_clk_gate("csi_ahb", "ahb", ccm(CCM_CGCR0), 18);
+	imx_clk_gate("esdhc1_ahb", "ahb", ccm(CCM_CGCR0), 21);
+	imx_clk_gate("esdhc2_ahb", "ahb", ccm(CCM_CGCR0), 22);
+	imx_clk_gate("fec_ahb", "ahb", ccm(CCM_CGCR0), 23);
+	imx_clk_gate("lcdc_ahb", "ahb", ccm(CCM_CGCR0), 24);
+	imx_clk_gate("sdma_ahb", "ahb", ccm(CCM_CGCR0), 26);
+	imx_clk_gate("usbotg_ahb", "ahb", ccm(CCM_CGCR0), 28);
+	imx_clk_gate("can1_ipg", "ipg", ccm(CCM_CGCR1),  2);
+	imx_clk_gate("can2_ipg", "ipg", ccm(CCM_CGCR1),  3);
+	imx_clk_gate("csi_ipg", "ipg", ccm(CCM_CGCR1),  4);
+	imx_clk_gate("cspi1_ipg", "ipg", ccm(CCM_CGCR1),  5);
+	imx_clk_gate("cspi2_ipg", "ipg", ccm(CCM_CGCR1),  6);
+	imx_clk_gate("cspi3_ipg", "ipg", ccm(CCM_CGCR1),  7);
+	imx_clk_gate("dryice_ipg", "ipg", ccm(CCM_CGCR1),  8);
+	imx_clk_gate("esdhc1_ipg", "ipg", ccm(CCM_CGCR1), 13);
+	imx_clk_gate("esdhc2_ipg", "ipg", ccm(CCM_CGCR1), 14);
+	imx_clk_gate("fec_ipg", "ipg", ccm(CCM_CGCR1), 15);
+	imx_clk_gate("iim_ipg", "ipg", ccm(CCM_CGCR1), 26);
+	imx_clk_gate("kpp_ipg", "ipg", ccm(CCM_CGCR1), 28);
+	imx_clk_gate("lcdc_ipg", "ipg", ccm(CCM_CGCR1), 29);
+	imx_clk_gate("pwm1_ipg", "ipg", ccm(CCM_CGCR1), 31);
+	imx_clk_gate("pwm2_ipg", "ipg", ccm(CCM_CGCR2),  0);
+	imx_clk_gate("pwm3_ipg", "ipg", ccm(CCM_CGCR2),  1);
+	imx_clk_gate("pwm4_ipg", "ipg", ccm(CCM_CGCR2),  2);
+	imx_clk_gate("sdma_ipg", "ipg", ccm(CCM_CGCR2),  6);
+	imx_clk_gate("ssi1_ipg", "ipg", ccm(CCM_CGCR2), 11);
+	imx_clk_gate("ssi2_ipg", "ipg", ccm(CCM_CGCR2), 12);
+	imx_clk_gate("tsc_ipg", "ipg", ccm(CCM_CGCR2), 13);
+	imx_clk_gate("uart1_ipg", "ipg", ccm(CCM_CGCR2), 14);
+	imx_clk_gate("uart2_ipg", "ipg", ccm(CCM_CGCR2), 15);
+	imx_clk_gate("uart3_ipg", "ipg", ccm(CCM_CGCR2), 16);
+	imx_clk_gate("uart4_ipg", "ipg", ccm(CCM_CGCR2), 17);
+	imx_clk_gate("uart5_ipg", "ipg", ccm(CCM_CGCR2), 18);
+	imx_clk_gate("wdt_ipg", "ipg", ccm(CCM_CGCR2), 19);
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	mxc_timer_init(NULL, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+	return 0;
+}
-- 
1.7.9.5

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

* [PATCH 28/40] ARM i.MX1: implement clocks using common clock framework
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (26 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 27/40] ARM i.MX25: implement clocks using common clock framework Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-16 21:07   ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 29/40] ARM i.MX21: " Sascha Hauer
                   ` (11 subsequent siblings)
  39 siblings, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/Kconfig    |    1 +
 arch/arm/mach-imx/Makefile   |    2 +-
 arch/arm/mach-imx/clk-imx1.c |  109 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 111 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-imx1.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 0b832b1..c03920a 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -34,6 +34,7 @@ config ARCH_MX53
 config SOC_IMX1
 	bool
 	select ARCH_MX1
+	select COMMON_CLK
 	select CPU_ARM920T
 	select IMX_HAVE_IOMUX_V1
 	select MXC_AVIC
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 173e869..52b3af4 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_SOC_IMX1) += clock-imx1.o mm-imx1.o
+obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o
 obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o
 
 obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c
new file mode 100644
index 0000000..60f1801
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx1.c
@@ -0,0 +1,109 @@
+/*
+ *  Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include "clk.h"
+
+/* CCM register addresses */
+#define IO_ADDR_CCM(off)	(MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
+
+#define CCM_CSCR	IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0	IO_ADDR_CCM(0x4)
+#define CCM_SPCTL0	IO_ADDR_CCM(0xc)
+#define CCM_PCDR	IO_ADDR_CCM(0x20)
+
+/* SCM register addresses */
+#define IO_ADDR_SCM(off)	(MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
+
+#define SCM_GCCR	IO_ADDR_SCM(0xc)
+
+#define clkdev(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clkname = c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	clkdev(NULL, "dma", "dma_gate")
+	clkdev("mx1-camera.0", NULL, "csi_gate")
+	clkdev(NULL, "mma", "mma_gate")
+	clkdev("imx_udc.0", NULL, "usbd_gate")
+	clkdev("imx-gpt.0", "per", "per1")
+	clkdev("imx-gpt.0", "ipg", "hclk")
+	clkdev("imx1-uart.0", "per", "per1")
+	clkdev("imx1-uart.0", "ipg", "hclk")
+	clkdev("imx1-uart.1", "per", "per1")
+	clkdev("imx1-uart.1", "ipg", "hclk")
+	clkdev("imx1-uart.2", "per", "per1")
+	clkdev("imx1-uart.2", "ipg", "hclk")
+	clkdev("imx-i2c.0", NULL, "hclk")
+	clkdev("imx1-cspi.0", "per", "per2")
+	clkdev("imx1-cspi.0", "ipg", "dummy")
+	clkdev("imx1-cspi.1", "per", "per2")
+	clkdev("imx1-cspi.1", "ipg", "dummy")
+	clkdev("imx-mmc.0", NULL, "per2")
+	clkdev("imx-fb.0", "per", "per2")
+	clkdev("imx-fb.0", "ipg", "dummy")
+	clkdev("imx-fb.0", "ahb", "dummy")
+	clkdev(NULL, "mshc", "hclk")
+	clkdev(NULL, "ssi", "per3")
+	clkdev("mxc_rtc.0", NULL, "clk32")
+	clkdev(NULL, "clko", "clko")
+};
+
+static char *prem_sel_clks[] = { "clk32_premult", "clk16m", };
+static char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m", "prem",
+				"fclk", };
+
+int __init mx1_clocks_init(unsigned long fref)
+{
+	imx_clk_fixed("dummy", 0);
+	imx_clk_fixed("clk32", fref);
+	imx_clk_fixed("clk16m_ext", 16000000);
+	imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17);
+	imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
+	imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks, ARRAY_SIZE(prem_sel_clks));
+	imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0);
+	imx_clk_pllv1("spll", "prem", CCM_SPCTL0);
+	imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1);
+	imx_clk_divider("fclk", "mpll", CCM_CSCR, 15, 1);
+	imx_clk_divider("hclk", "spll", CCM_CSCR, 10, 4);
+	imx_clk_divider("clk48m", "spll", CCM_CSCR, 26, 3);
+	imx_clk_divider("per1", "spll", CCM_PCDR, 0, 4);
+	imx_clk_divider("per2", "spll", CCM_PCDR, 4, 4);
+	imx_clk_divider("per3", "spll", CCM_PCDR, 16, 7);
+	imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
+	imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 4);
+	imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2);
+	imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1);
+	imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0);
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	mxc_timer_init(NULL, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
+			MX1_TIM1_INT);
+
+	return 0;
+}
-- 
1.7.9.5

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

* [PATCH 29/40] ARM i.MX21: implement clocks using common clock framework
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (27 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 28/40] ARM i.MX1: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 30/40] ARM i.MX27: " Sascha Hauer
                   ` (10 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/Kconfig     |    1 +
 arch/arm/mach-imx/Makefile    |    2 +-
 arch/arm/mach-imx/clk-imx21.c |  173 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 175 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-imx21.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index c03920a..d23cebd 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -43,6 +43,7 @@ config SOC_IMX21
 	bool
 	select MACH_MX21
 	select CPU_ARM926T
+	select COMMON_CLK
 	select IMX_HAVE_IOMUX_V1
 	select MXC_AVIC
 
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 52b3af4..a2efb79 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,5 +1,5 @@
 obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o
-obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o
+obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o
 
 obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
 
diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c
new file mode 100644
index 0000000..c4779a0
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx21.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ * Copyright 2008 Martin Fuzzey, mfuzzey at gmail.com
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include "clk.h"
+
+#define IO_ADDR_CCM(off)	(MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
+
+/* Register offsets */
+#define CCM_CSCR		IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0		IO_ADDR_CCM(0x4)
+#define CCM_MPCTL1		IO_ADDR_CCM(0x8)
+#define CCM_SPCTL0		IO_ADDR_CCM(0xc)
+#define CCM_SPCTL1		IO_ADDR_CCM(0x10)
+#define CCM_OSC26MCTL		IO_ADDR_CCM(0x14)
+#define CCM_PCDR0		IO_ADDR_CCM(0x18)
+#define CCM_PCDR1		IO_ADDR_CCM(0x1c)
+#define CCM_PCCR0		IO_ADDR_CCM(0x20)
+#define CCM_PCCR1		IO_ADDR_CCM(0x24)
+#define CCM_CCSR		IO_ADDR_CCM(0x28)
+#define CCM_PMCTL		IO_ADDR_CCM(0x2c)
+#define CCM_PMCOUNT		IO_ADDR_CCM(0x30)
+#define CCM_WKGDCTL		IO_ADDR_CCM(0x34)
+
+static char *mpll_sel_clks[] = { "fpm", "ckih", };
+static char *spll_sel_clks[] = { "fpm", "ckih", };
+
+#define clkdev(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clkname = c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	clkdev(NULL, "per1", "per1")
+	clkdev(NULL, "per2", "per2")
+	clkdev(NULL, "per3", "per3")
+	clkdev(NULL, "per4", "per4")
+	clkdev("imx21-uart.0", "per", "per1")
+	clkdev("imx21-uart.0", "ipg", "uart1_ipg_gate")
+	clkdev("imx21-uart.1", "per", "per1")
+	clkdev("imx21-uart.1", "ipg", "uart2_ipg_gate")
+	clkdev("imx21-uart.2", "per", "per1")
+	clkdev("imx21-uart.2", "ipg", "uart3_ipg_gate")
+	clkdev("imx21-uart.3", "per", "per1")
+	clkdev("imx21-uart.3", "ipg", "uart4_ipg_gate")
+	clkdev("imx-gpt.0", "ipg", "gpt1_ipg_gate")
+	clkdev("imx-gpt.0", "per", "per1")
+	clkdev("imx-gpt.1", "ipg", "gpt2_ipg_gate")
+	clkdev("imx-gpt.1", "per", "per1")
+	clkdev("imx-gpt.2", "ipg", "gpt3_ipg_gate")
+	clkdev("imx-gpt.2", "per", "per1")
+	clkdev("mxc_pwm.0", "pwm", "pwm_ipg_gate")
+	clkdev("imx21-cspi.0", "per", "per2")
+	clkdev("imx21-cspi.0", "ipg", "cspi1_ipg_gate")
+	clkdev("imx21-cspi.1", "per", "per2")
+	clkdev("imx21-cspi.1", "ipg", "cspi2_ipg_gate")
+	clkdev("imx21-cspi.2", "per", "per2")
+	clkdev("imx21-cspi.2", "ipg", "cspi3_ipg_gate")
+	clkdev("imx-fb.0", "per", "per3")
+	clkdev("imx-fb.0", "ipg", "lcdc_ipg_gate")
+	clkdev("imx-fb.0", "ahb", "lcdc_hclk_gate")
+	clkdev("imx21-hcd.0", "per", "usb_gate")
+	clkdev("imx21-hcd.0", "ahb", "usb_hclk_gate")
+	clkdev("mxc_nand.0", NULL, "nfc_gate")
+	clkdev("imx-dma", "ahb", "dma_hclk_gate")
+	clkdev("imx-dma", "ipg", "dma_gate")
+	clkdev("imx2-wdt.0", NULL, "wdog_gate")
+	clkdev("imx-i2c.0", NULL, "i2c_gate")
+	clkdev("mxc-keypad", NULL, "kpp_gate")
+	clkdev("mxc_w1.0", NULL, "owire_gate")
+	clkdev(NULL, "brom", "brom_gate")
+	clkdev(NULL, "emma", "emma_gate")
+	clkdev(NULL, "slcdc", "slcdc_gate")
+	clkdev(NULL, "gpio", "gpio_gate")
+	clkdev(NULL, "rtc", "rtc_gate")
+	clkdev(NULL, "csi", "csi")
+	clkdev(NULL, "ssi1", "ssi1_gate")
+	clkdev(NULL, "ssi2", "ssi2_gate")
+	clkdev(NULL, "sdhc1", "sdhc1")
+	clkdev(NULL, "sdhc2", "sdhc2")
+};
+
+/*
+ * must be called very early to get information about the
+ * available clock rate when the timer framework starts
+ */
+int __init mx21_clocks_init(unsigned long lref, unsigned long href)
+{
+	imx_clk_fixed("ckil", lref);
+	imx_clk_fixed("ckih", href);
+	imx_clk_fixed_factor("fpm", "ckil", 512, 1);
+	imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks));
+	imx_clk_mux("spll_sel", CCM_CSCR, 17, 1, spll_sel_clks, ARRAY_SIZE(spll_sel_clks));
+	imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0);
+	imx_clk_pllv1("spll", "spll_sel", CCM_SPCTL0);
+	imx_clk_divider("fclk", "mpll", CCM_CSCR, 29, 3);
+	imx_clk_divider("hclk", "fclk", CCM_CSCR, 10, 4);
+	imx_clk_divider("ipg", "hclk", CCM_CSCR, 9, 1);
+	imx_clk_divider("per1", "mpll", CCM_PCDR1, 0, 6);
+	imx_clk_divider("per2", "mpll", CCM_PCDR1, 8, 6);
+	imx_clk_divider("per3", "mpll", CCM_PCDR1, 16, 6);
+	imx_clk_divider("per4", "mpll", CCM_PCDR1, 24, 6);
+	imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR0, 0);
+	imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR0, 1);
+	imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR0, 2);
+	imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR0, 3);
+	imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR1, 25);
+	imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR1, 26);
+	imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR1, 27);
+	imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR1, 28);
+	imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 9);
+	imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 10);
+	imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 18);
+	imx_clk_gate("lcdc_hclk_gate", "hclk", CCM_PCCR0, 26);
+	imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR1, 23);
+	imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 5);
+	imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 4);
+	imx_clk_gate("per4_gate", "per4", CCM_PCCR0, 22);
+	imx_clk_gate("csi_hclk_gate", "hclk", CCM_PCCR0, 31);
+	imx_clk_divider("usb_div", "spll", CCM_CSCR, 26, 3);
+	imx_clk_gate("usb_gate", "usb_div", CCM_PCCR0, 14);
+	imx_clk_gate("usb_hclk_gate", "hclk", CCM_PCCR0, 24);
+	imx_clk_gate("ssi1_gate", "ipg", CCM_PCCR0, 6);
+	imx_clk_gate("ssi2_gate", "ipg", CCM_PCCR0, 7);
+	imx_clk_divider("nfc_div", "ipg", CCM_PCDR0, 12, 4);
+	imx_clk_gate("nfc_gate", "nfc_div", CCM_PCCR0, 19);
+	imx_clk_gate("dma_gate", "ipg", CCM_PCCR0, 13);
+	imx_clk_gate("dma_hclk_gate", "hclk", CCM_PCCR0, 30);
+	imx_clk_gate("brom_gate", "hclk", CCM_PCCR0, 28);
+	imx_clk_gate("emma_gate", "ipg", CCM_PCCR0, 15);
+	imx_clk_gate("emma_hclk_gate", "hclk", CCM_PCCR0, 27);
+	imx_clk_gate("slcdc_gate", "ipg", CCM_PCCR0, 25);
+	imx_clk_gate("slcdc_hclk_gate", "hclk", CCM_PCCR0, 21);
+	imx_clk_gate("wdog_gate", "ipg", CCM_PCCR1, 24);
+	imx_clk_gate("gpio_gate", "ipg", CCM_PCCR0, 11);
+	imx_clk_gate("i2c_gate", "ipg", CCM_PCCR0, 12);
+	imx_clk_gate("kpp_gate", "ipg", CCM_PCCR1, 30);
+	imx_clk_gate("owire_gate", "ipg", CCM_PCCR1, 31);
+	imx_clk_gate("rtc_gate", "ipg", CCM_PCCR1, 29);
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	mxc_timer_init(NULL, MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
+			MX21_INT_GPT1);
+	return 0;
+}
-- 
1.7.9.5

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

* [PATCH 30/40] ARM i.MX27: implement clocks using common clock framework
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (28 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 29/40] ARM i.MX21: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 31/40] ARM i.MX31: " Sascha Hauer
                   ` (9 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/Kconfig     |    1 +
 arch/arm/mach-imx/Makefile    |    2 +-
 arch/arm/mach-imx/clk-imx27.c |  255 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 257 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-imx27.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index d23cebd..efed8f9 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -59,6 +59,7 @@ config SOC_IMX27
 	bool
 	select MACH_MX27
 	select CPU_ARM926T
+	select COMMON_CLK
 	select IMX_HAVE_IOMUX_V1
 	select MXC_AVIC
 
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index a2efb79..c4ab418 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o
 obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
 
 obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
-obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o
+obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
 
 obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
 obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
new file mode 100644
index 0000000..3a1e965
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -0,0 +1,255 @@
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/clk-provider.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include "clk.h"
+
+#define IO_ADDR_CCM(off)	(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
+
+/* Register offsets */
+#define CCM_CSCR		IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0		IO_ADDR_CCM(0x4)
+#define CCM_MPCTL1		IO_ADDR_CCM(0x8)
+#define CCM_SPCTL0		IO_ADDR_CCM(0xc)
+#define CCM_SPCTL1		IO_ADDR_CCM(0x10)
+#define CCM_OSC26MCTL		IO_ADDR_CCM(0x14)
+#define CCM_PCDR0		IO_ADDR_CCM(0x18)
+#define CCM_PCDR1		IO_ADDR_CCM(0x1c)
+#define CCM_PCCR0		IO_ADDR_CCM(0x20)
+#define CCM_PCCR1		IO_ADDR_CCM(0x24)
+#define CCM_CCSR		IO_ADDR_CCM(0x28)
+#define CCM_PMCTL		IO_ADDR_CCM(0x2c)
+#define CCM_PMCOUNT		IO_ADDR_CCM(0x30)
+#define CCM_WKGDCTL		IO_ADDR_CCM(0x34)
+
+#define CCM_CSCR_UPDATE_DIS	(1 << 31)
+#define CCM_CSCR_SSI2		(1 << 23)
+#define CCM_CSCR_SSI1		(1 << 22)
+#define CCM_CSCR_VPU		(1 << 21)
+#define CCM_CSCR_MSHC           (1 << 20)
+#define CCM_CSCR_SPLLRES        (1 << 19)
+#define CCM_CSCR_MPLLRES        (1 << 18)
+#define CCM_CSCR_SP             (1 << 17)
+#define CCM_CSCR_MCU            (1 << 16)
+#define CCM_CSCR_OSC26MDIV      (1 << 4)
+#define CCM_CSCR_OSC26M         (1 << 3)
+#define CCM_CSCR_FPM            (1 << 2)
+#define CCM_CSCR_SPEN           (1 << 1)
+#define CCM_CSCR_MPEN           (1 << 0)
+
+/* i.MX27 TO 2+ */
+#define CCM_CSCR_ARM_SRC        (1 << 15)
+
+#define CCM_SPCTL1_LF           (1 << 15)
+#define CCM_SPCTL1_BRMO         (1 << 6)
+
+#define clkdev(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clkname = c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	clkdev("imx21-uart.0", "ipg", "uart1_ipg_gate")
+	clkdev("imx21-uart.0", "per", "per1_gate")
+	clkdev("imx21-uart.1", "ipg", "uart2_ipg_gate")
+	clkdev("imx21-uart.1", "per", "per1_gate")
+	clkdev("imx21-uart.2", "ipg", "uart3_ipg_gate")
+	clkdev("imx21-uart.2", "per", "per1_gate")
+	clkdev("imx21-uart.3", "ipg", "uart4_ipg_gate")
+	clkdev("imx21-uart.3", "per", "per1_gate")
+	clkdev("imx21-uart.4", "ipg", "uart5_ipg_gate")
+	clkdev("imx21-uart.4", "per", "per1_gate")
+	clkdev("imx21-uart.5", "ipg", "uart6_ipg_gate")
+	clkdev("imx21-uart.5", "per", "per1_gate")
+	clkdev("imx-gpt.0", "ipg", "gpt1_ipg_gate")
+	clkdev("imx-gpt.0", "per", "per1_gate")
+	clkdev("imx-gpt.1", "ipg", "gpt2_ipg_gate")
+	clkdev("imx-gpt.1", "per", "per1_gate")
+	clkdev("imx-gpt.2", "ipg", "gpt3_ipg_gate")
+	clkdev("imx-gpt.2", "per", "per1_gate")
+	clkdev("imx-gpt.3", "ipg", "gpt4_ipg_gate")
+	clkdev("imx-gpt.3", "per", "per1_gate")
+	clkdev("imx-gpt.4", "ipg", "gpt5_ipg_gate")
+	clkdev("imx-gpt.4", "per", "per1_gate")
+	clkdev("imx-gpt.5", "ipg", "gpt6_ipg_gate")
+	clkdev("imx-gpt.5", "per", "per1_gate")
+	clkdev("mxc_pwm.0", NULL, "pwm")
+	clkdev("mxc-mmc.0", "per", "per2_gate")
+	clkdev("mxc-mmc.0", "ipg", "sdhc1_ipg_gate")
+	clkdev("mxc-mmc.1", "per", "per2_gate")
+	clkdev("mxc-mmc.1", "ipg", "sdhc2_ipg_gate")
+	clkdev("mxc-mmc.2", "per", "per2_gate")
+	clkdev("mxc-mmc.2", "ipg", "sdhc2_ipg_gate")
+	clkdev("imx27-cspi.0", NULL, "cspi1")
+	clkdev("imx27-cspi.1", NULL, "cspi2")
+	clkdev("imx27-cspi.2", NULL, "cspi3")
+	clkdev("imx-fb.0", "per", "per3_gate")
+	clkdev("imx-fb.0", "ipg", "lcdc_ipg_gate")
+	clkdev("imx-fb.0", "ahb", "lcdc_ahb_gate")
+	clkdev("mx2-camera.0", NULL, "csi")
+	clkdev("fsl-usb2-udc", "per", "usb")
+	clkdev("fsl-usb2-udc", "ipg", "usb_ipg_gate")
+	clkdev("fsl-usb2-udc", "ahb", "usb_ahb_gate")
+	clkdev("mxc-ehci.0", "per", "usb")
+	clkdev("mxc-ehci.0", "ipg", "usb_ipg_gate")
+	clkdev("mxc-ehci.0", "ahb", "usb_ahb_gate")
+	clkdev("mxc-ehci.1", "per", "usb")
+	clkdev("mxc-ehci.1", "ipg", "usb_ipg_gate")
+	clkdev("mxc-ehci.1", "ahb", "usb_ahb_gate")
+	clkdev("mxc-ehci.2", "per", "usb")
+	clkdev("mxc-ehci.2", "ipg", "usb_ipg_gate")
+	clkdev("mxc-ehci.2", "ahb", "usb_ahb_gate")
+	clkdev("imx-ssi.0", NULL, "ssi1_ipg_gate")
+	clkdev("imx-ssi.1", NULL, "ssi2_ipg_gate")
+	clkdev("mxc_nand.0", NULL, "nfc_baud_gate")
+	clkdev("imx-vpu", "per", "vpu_baud_gate")
+	clkdev("imx-vpu", "ahb", "vpu_ahb_gate")
+	clkdev("imx-dma", "ahb", "dma_ahb_gate")
+	clkdev("imx-dma", "ipg", "dma_ipg_gate")
+	clkdev("imx27-fec.0", "ipg", "fec_ipg_gate")
+	clkdev("imx27-fec.0", "ahb", "fec_ahb_gate")
+	clkdev("imx2-wdt.0", NULL, "wdog_ipg_gate")
+	clkdev("imx-i2c.0", NULL, "i2c1_ipg_gate")
+	clkdev("imx-i2c.1", NULL, "i2c2_ipg_gate")
+	clkdev("mxc_w1.0", NULL, "owire_ipg_gate")
+	clkdev("imx-keypad", NULL, "kpp_ipg_gate")
+	clkdev("imx-emma", "ahb", "emma_ahb_gate")
+	clkdev("imx-emma", "ipg", "emma_ipg_gate")
+	clkdev(NULL, "iim", "iim_ipg_gate")
+	clkdev(NULL, "gpio", "gpio_ipg_gate")
+	clkdev(NULL, "brom", "brom_ahb_gate")
+	clkdev(NULL, "ata", "ata_ahb_gate")
+	clkdev(NULL, "rtc", "rtc_ipg_gate")
+	clkdev(NULL, "scc", "scc_ipg_gate")
+	clkdev(NULL, "cpu", "cpu_div")
+	clkdev(NULL, "emi_ahb" , "emi_ahb_gate")
+	clkdev("imx-ssi.0", "bitrate" , "ssi1_baud_gate")
+	clkdev("imx-ssi.1", "bitrate" , "ssi2_baud_gate")
+};
+
+static char *vpu_sel_clks[] = { "spll", "mpll_main2", };
+static char *cpu_sel_clks[] = { "mpll_main2", "mpll", };
+static char *clko_sel_clks[] = {
+	"ckil", "prem", "ckih", "ckih",
+	"ckih", "mpll", "spll", "cpu_div",
+	"ahb", "ipg", "per1_div", "per2_div",
+	"per3_div", "per4_div", "ssi1_div", "ssi2_div",
+	"nfc_div", "mshc_div", "vpu_div", "60m",
+	"32k", "usb_div", "dptc",
+};
+
+static char *ssi_sel_clks[] = { "spll", "mpll", };
+
+int __init mx27_clocks_init(unsigned long fref)
+{
+	struct clk *emi_ahb;
+
+	imx_clk_fixed("dummy", 0);
+	imx_clk_fixed("ckih", fref);
+	imx_clk_fixed("ckil", 32768);
+	imx_clk_pllv1("mpll", "ckih", CCM_MPCTL0);
+	imx_clk_pllv1("spll", "ckih", CCM_SPCTL0);
+	imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
+
+	if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
+		imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 8, 2);
+		imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+	} else {
+		imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 9, 4);
+		imx_clk_divider("ipg", "ahb", CCM_CSCR, 8, 1);
+	}
+
+	imx_clk_divider("nfc_div", "ahb", CCM_PCDR0, 6, 4);
+	imx_clk_divider("per1_div", "mpll_main2", CCM_PCDR1, 0, 6);
+	imx_clk_divider("per2_div", "mpll_main2", CCM_PCDR1, 8, 6);
+	imx_clk_divider("per3_div", "mpll_main2", CCM_PCDR1, 16, 6);
+	imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6);
+	imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks));
+	imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 3);
+	imx_clk_divider("usb_div", "spll", CCM_CSCR, 28, 3);
+	imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
+	imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
+	if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
+		imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 12, 2);
+	else
+		imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 13, 3);
+	imx_clk_divider("clko_div", "clko_sel", CCM_PCDR0, 22, 3);
+	imx_clk_mux("ssi1_sel", CCM_CSCR, 22, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
+	imx_clk_mux("ssi2_sel", CCM_CSCR, 23, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
+	imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
+	imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 3);
+	imx_clk_gate("clko_en", "clko_div", CCM_PCCR0, 0);
+	imx_clk_gate("ssi2_ipg_gate", "ipg", CCM_PCCR0, 0);
+	imx_clk_gate("ssi1_ipg_gate", "ipg", CCM_PCCR0, 1);
+	imx_clk_gate("slcdc_ipg_gate", "ipg", CCM_PCCR0, 2);
+	imx_clk_gate("sdhc3_ipg_gate", "ipg", CCM_PCCR0, 3);
+	imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 4);
+	imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 5);
+	imx_clk_gate("scc_ipg_gate", "ipg", CCM_PCCR0, 6);
+	imx_clk_gate("sahara_ipg_gate", "ipg", CCM_PCCR0, 7);
+	imx_clk_gate("rtc_ipg_gate", "ipg", CCM_PCCR0, 9);
+	imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR0, 11);
+	imx_clk_gate("owire_ipg_gate", "ipg", CCM_PCCR0, 12);
+	imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 14);
+	imx_clk_gate("kpp_ipg_gate", "ipg", CCM_PCCR0, 15);
+	imx_clk_gate("iim_ipg_gate", "ipg", CCM_PCCR0, 16);
+	imx_clk_gate("i2c2_ipg_gate", "ipg", CCM_PCCR0, 17);
+	imx_clk_gate("i2c1_ipg_gate", "ipg", CCM_PCCR0, 18);
+	imx_clk_gate("gpt6_ipg_gate", "ipg", CCM_PCCR0, 19);
+	imx_clk_gate("gpt5_ipg_gate", "ipg", CCM_PCCR0, 20);
+	imx_clk_gate("gpt4_ipg_gate", "ipg", CCM_PCCR0, 21);
+	imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR0, 22);
+	imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR0, 23);
+	imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR0, 24);
+	imx_clk_gate("gpio_ipg_gate", "ipg", CCM_PCCR0, 25);
+	imx_clk_gate("fec_ipg_gate", "ipg", CCM_PCCR0, 26);
+	imx_clk_gate("emma_ipg_gate", "ipg", CCM_PCCR0, 27);
+	imx_clk_gate("dma_ipg_gate", "ipg", CCM_PCCR0, 28);
+	imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR0, 29);
+	imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 30);
+	imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 31);
+	imx_clk_gate("nfc_baud_gate", "nfc_div", CCM_PCCR1,  3);
+	imx_clk_gate("ssi2_baud_gate", "ssi2_div", CCM_PCCR1,  4);
+	imx_clk_gate("ssi1_baud_gate", "ssi1_div", CCM_PCCR1,  5);
+	imx_clk_gate("vpu_baud_gate", "vpu_div", CCM_PCCR1,  6);
+	imx_clk_gate("per4_gate", "per4_div", CCM_PCCR1,  7);
+	imx_clk_gate("per3_gate", "per3_div", CCM_PCCR1,  8);
+	imx_clk_gate("per2_gate", "per2_div", CCM_PCCR1,  9);
+	imx_clk_gate("per1_gate", "per1_div", CCM_PCCR1, 10);
+	imx_clk_gate("usb_ahb_gate", "ahb", CCM_PCCR1, 11);
+	imx_clk_gate("slcdc_ahb_gate", "ahb", CCM_PCCR1, 12);
+	imx_clk_gate("sahara_ahb_gate", "ahb", CCM_PCCR1, 13);
+	imx_clk_gate("lcdc_ahb_gate", "ahb", CCM_PCCR1, 15);
+	imx_clk_gate("vpu_ahb_gate", "ahb", CCM_PCCR1, 16);
+	imx_clk_gate("fec_ahb_gate", "ahb", CCM_PCCR1, 17);
+	imx_clk_gate("emma_ahb_gate", "ahb", CCM_PCCR1, 18);
+	emi_ahb = imx_clk_gate("emi_ahb_gate", "ahb", CCM_PCCR1, 19);
+	imx_clk_gate("dma_ahb_gate", "ahb", CCM_PCCR1, 20);
+	imx_clk_gate("csi_ahb_gate", "ahb", CCM_PCCR1, 21);
+	imx_clk_gate("brom_ahb_gate", "ahb", CCM_PCCR1, 22);
+	imx_clk_gate("ata_ahb_gate", "ahb", CCM_PCCR1, 23);
+	imx_clk_gate("wdog_ipg_gate", "ipg", CCM_PCCR1, 24);
+	imx_clk_gate("usb_ipg_gate", "ipg", CCM_PCCR1, 25);
+	imx_clk_gate("uart6_ipg_gate", "ipg", CCM_PCCR1, 26);
+	imx_clk_gate("uart5_ipg_gate", "ipg", CCM_PCCR1, 27);
+	imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR1, 28);
+	imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR1, 29);
+	imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR1, 30);
+	imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR1, 31);
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	mxc_timer_init(NULL, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
+			MX27_INT_GPT1);
+
+	clk_prepare_enable(emi_ahb);
+
+	return 0;
+}
-- 
1.7.9.5

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

* [PATCH 31/40] ARM i.MX31: implement clocks using common clock framework
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (29 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 30/40] ARM i.MX27: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 32/40] ARM i.MX5: " Sascha Hauer
                   ` (8 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/Kconfig     |    1 +
 arch/arm/mach-imx/Makefile    |    2 +-
 arch/arm/mach-imx/clk-imx31.c |  168 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 170 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-imx31.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index efed8f9..692de7b 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -68,6 +68,7 @@ config SOC_IMX31
 	select CPU_V6
 	select IMX_HAVE_PLATFORM_MXC_RNGA
 	select MXC_AVIC
+	select COMMON_CLK
 	select SMP_ON_UP if SMP
 
 config SOC_IMX35
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index c4ab418..fdad8f4 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
 obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
 obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
 
-obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
+obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
 obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o
 
 obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c
new file mode 100644
index 0000000..de3addb
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx31.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2012 Sascha Hauer <kernel@pengutronix.de>
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mx31.h>
+#include <mach/common.h>
+
+#include "clk.h"
+#include "crmregs-imx3.h"
+
+static char *mcu_main_sel[] = { "spll", "mpll", };
+static char *per_sel[] = { "per_div", "ipg", };
+static char *csi_sel[] = { "upll", "spll", };
+
+#define clkdev(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clkname = c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	clkdev("imx-gpt.0", "per", "gpt_gate")
+	clkdev("imx-gpt.0", "ipg", "ipg")
+	clkdev("imx31-cspi.0", NULL, "cspi1_gate")
+	clkdev("imx31-cspi.1", NULL, "cspi2_gate")
+	clkdev("imx31-cspi.2", NULL, "cspi3_gate")
+	clkdev(NULL, "pwm", "pwm_gate")
+	clkdev("imx2-wdt.0", NULL, "wdog_gate")
+	clkdev(NULL, "rtc", "rtc_gate")
+	clkdev(NULL, "epit", "epit1_gate")
+	clkdev(NULL, "epit", "epit2_gate")
+	clkdev("mxc_nand.0", NULL, "nfc")
+	clkdev("ipu-core", NULL, "ipu_gate")
+	clkdev("mx3_sdc_fb", NULL, "ipu_gate")
+	clkdev(NULL, "kpp", "kpp_gate")
+	clkdev("mxc-ehci.0", "per", "usb_div_post")
+	clkdev("mxc-ehci.0", "ahb", "usb_gate")
+	clkdev("mxc-ehci.0", "ipg", "ipg")
+	clkdev("mxc-ehci.1", "per", "usb_div_post")
+	clkdev("mxc-ehci.1", "ahb", "usb_gate")
+	clkdev("mxc-ehci.1", "ipg", "ipg")
+	clkdev("mxc-ehci.2", "per", "usb_div_post")
+	clkdev("mxc-ehci.2", "ahb", "usb_gate")
+	clkdev("mxc-ehci.2", "ipg", "ipg")
+	clkdev("fsl-usb2-udc", "per", "usb_div_post")
+	clkdev("fsl-usb2-udc", "ahb", "usb_gate")
+	clkdev("fsl-usb2-udc", "ipg", "ipg")
+	clkdev("mx3-camera.0", NULL, "csi_gate")
+	/* i.mx31 has the i.mx21 type uart */
+	clkdev("imx21-uart.0", "per", "uart1_gate")
+	clkdev("imx21-uart.0", "ipg", "ipg")
+	clkdev("imx21-uart.1", "per", "uart2_gate")
+	clkdev("imx21-uart.1", "ipg", "ipg")
+	clkdev("imx21-uart.2", "per", "uart3_gate")
+	clkdev("imx21-uart.2", "ipg", "ipg")
+	clkdev("imx21-uart.3", "per", "uart4_gate")
+	clkdev("imx21-uart.3", "ipg", "ipg")
+	clkdev("imx21-uart.4", "per", "uart5_gate")
+	clkdev("imx21-uart.4", "ipg", "ipg")
+	clkdev("imx-i2c.0", NULL, "i2c1_gate")
+	clkdev("imx-i2c.1", NULL, "i2c2_gate")
+	clkdev("imx-i2c.2", NULL, "i2c3_gate")
+	clkdev("mxc_w1.0", NULL, "owire_gate")
+	clkdev("mxc-mmc.0", NULL, "sdhc1_gate")
+	clkdev("mxc-mmc.1", NULL, "sdhc2_gate")
+	clkdev("imx-ssi.0", NULL, "ssi1_gate")
+	clkdev("imx-ssi.1", NULL, "ssi2_gate")
+	clkdev(NULL, "firi", "firi_gate")
+	clkdev("pata_imx", NULL, "pata_gate")
+	clkdev(NULL, "rtic", "rtic_gate")
+	clkdev(NULL, "rng", "rng_gate")
+	clkdev("imx31-sdma", NULL, "sdma_gate")
+	clkdev(NULL, "iim", "iim_gate")
+};
+
+int __init mx31_clocks_init(unsigned long fref)
+{
+	struct clk *emi, *upll, *csisel, *iim;
+	void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
+
+	imx_clk_fixed("ckih", fref);
+	imx_clk_fixed("ckil", 32768);
+	imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL);
+	imx_clk_pllv1("spll", "ckih", base + MXC_CCM_SRPCTL);
+	upll = imx_clk_pllv1("upll", "ckih", base + MXC_CCM_UPCTL);
+	imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
+	imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3);
+	imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3);
+	imx_clk_divider("nfc", "ahb", base + MXC_CCM_PDR0, 8, 3);
+	imx_clk_divider("ipg", "ahb", base + MXC_CCM_PDR0, 6, 2);
+	imx_clk_divider("per_div", "upll", base + MXC_CCM_PDR0, 16, 5);
+	imx_clk_mux("per", base + MXC_CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel));
+	csisel = imx_clk_mux("csi_sel", base + MXC_CCM_CCMR, 25, 1, csi_sel, ARRAY_SIZE(csi_sel));
+	imx_clk_divider("csi_div", "csi_sel", base + MXC_CCM_PDR0, 23, 9);
+	imx_clk_divider("usb_div_pre", "upll", base + MXC_CCM_PDR1, 30, 2);
+	imx_clk_divider("usb_div_post", "usb_div_pre", base + MXC_CCM_PDR1, 27, 3);
+	imx_clk_gate2("sdhc1_gate", "per", base + MXC_CCM_CGR0, 0);
+	imx_clk_gate2("sdhc2_gate", "per", base + MXC_CCM_CGR0, 2);
+	imx_clk_gate2("gpt_gate", "per", base + MXC_CCM_CGR0, 4);
+	imx_clk_gate2("epit1_gate", "per", base + MXC_CCM_CGR0, 6);
+	imx_clk_gate2("epit2_gate", "per", base + MXC_CCM_CGR0, 8);
+	iim = imx_clk_gate2("iim_gate", "ipg", base + MXC_CCM_CGR0, 10);
+	imx_clk_gate2("ata_gate", "ipg", base + MXC_CCM_CGR0, 12);
+	imx_clk_gate2("sdma_gate", "ahb", base + MXC_CCM_CGR0, 14);
+	imx_clk_gate2("cspi3_gate", "ipg", base + MXC_CCM_CGR0, 16);
+	imx_clk_gate2("rng_gate", "ipg", base + MXC_CCM_CGR0, 18);
+	imx_clk_gate2("uart1_gate", "per", base + MXC_CCM_CGR0, 20);
+	imx_clk_gate2("uart2_gate", "per", base + MXC_CCM_CGR0, 22);
+	imx_clk_gate2("ssi1_gate", "spll", base + MXC_CCM_CGR0, 24);
+	imx_clk_gate2("i2c1_gate", "per", base + MXC_CCM_CGR0, 26);
+	imx_clk_gate2("i2c2_gate", "per", base + MXC_CCM_CGR0, 28);
+	imx_clk_gate2("i2c3_gate", "per", base + MXC_CCM_CGR0, 30);
+	imx_clk_gate2("hantro_gate", "per", base + MXC_CCM_CGR1, 0);
+	imx_clk_gate2("mstick1_gate", "per", base + MXC_CCM_CGR1, 2);
+	imx_clk_gate2("mstick2_gate", "per", base + MXC_CCM_CGR1, 4);
+	imx_clk_gate2("csi_gate", "csi_div", base + MXC_CCM_CGR1, 6);
+	imx_clk_gate2("rtc_gate", "ipg", base + MXC_CCM_CGR1, 8);
+	imx_clk_gate2("wdog_gate", "ipg", base + MXC_CCM_CGR1, 10);
+	imx_clk_gate2("pwm_gate", "per", base + MXC_CCM_CGR1, 12);
+	imx_clk_gate2("sim_gate", "per", base + MXC_CCM_CGR1, 14);
+	imx_clk_gate2("ect_gate", "per", base + MXC_CCM_CGR1, 16);
+	imx_clk_gate2("usb_gate", "ahb", base + MXC_CCM_CGR1, 18);
+	imx_clk_gate2("kpp_gate", "ipg", base + MXC_CCM_CGR1, 20);
+	imx_clk_gate2("ipu_gate", "hsp", base + MXC_CCM_CGR1, 22);
+	imx_clk_gate2("uart3_gate", "per", base + MXC_CCM_CGR1, 24);
+	imx_clk_gate2("uart4_gate", "per", base + MXC_CCM_CGR1, 26);
+	imx_clk_gate2("uart5_gate", "per", base + MXC_CCM_CGR1, 28);
+	imx_clk_gate2("owire_gate", "per", base + MXC_CCM_CGR1, 30);
+	imx_clk_gate2("ssi2_gate", "spll", base + MXC_CCM_CGR2, 0);
+	imx_clk_gate2("cspi1_gate", "ipg", base + MXC_CCM_CGR2, 2);
+	imx_clk_gate2("cspi2_gate", "ipg", base + MXC_CCM_CGR2, 4);
+	imx_clk_gate2("gacc_gate", "per", base + MXC_CCM_CGR2, 6);
+	emi = imx_clk_gate2("emi_gate", "ahb", base + MXC_CCM_CGR2, 8);
+	imx_clk_gate2("rtic_gate", "ahb", base + MXC_CCM_CGR2, 10);
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	clk_set_parent(csisel, upll);
+	clk_prepare_enable(emi);
+	clk_prepare_enable(iim);
+	mx31_revision();
+	clk_disable_unprepare(iim);
+
+	mxc_timer_init(NULL, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR),
+			MX31_INT_GPT);
+
+	return 0;
+}
-- 
1.7.9.5

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

* [PATCH 32/40] ARM i.MX5: implement clocks using common clock framework
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (30 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 31/40] ARM i.MX31: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-23  6:39   ` Richard Zhao
  2012-04-10 13:45 ` [PATCH 33/40] ARM i.MX35: " Sascha Hauer
                   ` (7 subsequent siblings)
  39 siblings, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/Kconfig           |    1 +
 arch/arm/mach-imx/Makefile          |    2 +-
 arch/arm/mach-imx/clk-imx51-imx53.c |  414 +++++++++++++++++++++++++++++++++++
 3 files changed, 416 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-imx51-imx53.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 692de7b..eb14ae9 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -82,6 +82,7 @@ config SOC_IMX35
 config SOC_IMX5
 	select CPU_V7
 	select MXC_TZIC
+	select COMMON_CLK
 	select ARCH_MXC_IOMUX_V3
 	select ARCH_HAS_CPUFREQ
 	select ARCH_MX5
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index fdad8f4..adf2e4f 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
 obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
 obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o
 
-obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
+obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
 
 obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
 			    clk-pfd.o clk-busy.o
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
new file mode 100644
index 0000000..5b5d7a0
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * 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/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#include "crm-regs-imx5.h"
+#include "clk.h"
+
+/* Low-power Audio Playback Mode clock */
+static char *lp_apm_sel[] = { "osc", };
+
+/* This is used multiple times */
+static char *standard_pll_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "lp_apm", };
+static char *periph_apm_sel[] = { "pll1_sw", "pll3_sw", "lp_apm", };
+static char *main_bus_sel[] = { "pll2_sw", "periph_apm", };
+static char *esdhc_c_sel[] = { "esdhc_a_podf", "esdhc_b_podf", };
+static char *esdhc_d_sel[] = { "esdhc_a_podf", "esdhc_b_podf", };
+static char *emi_slow_sel[] = { "main_bus", "ahb", };
+static char *usb_phy_sel[] = { "osc", "usb_phy_podf", };
+static char *mx51_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "tve_di", };
+static char *mx53_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "di_pll4_podf", "dummy", "ldb_di0", };
+static char *mx53_ldb_di0_sel[] = { "pll3_sw", "pll4_sw", };
+static char *mx51_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", };
+static char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", "ldb_di1", };
+static char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", };
+static char *mx51_tve_ext_sel[] = { "osc", "ckih1", };
+static char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", };
+static char *tve_sel[] = { "tve_pred", "tve_ext_sel", };
+static char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
+static char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
+
+#define clkdev(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clkname = c, \
+	},
+
+static struct clk_lookup mx5_lookups[] = {
+	clkdev("imx-gpt.0", "per", "gpt_gate")
+	clkdev("imx-gpt.0", "ipg", "gpt_ipg_gate")
+	clkdev("imx21-uart.0", "per", "uart1_per_gate")
+	clkdev("imx21-uart.0", "ipg", "uart1_ipg_gate")
+	clkdev("imx21-uart.1", "per", "uart2_per_gate")
+	clkdev("imx21-uart.1", "ipg", "uart2_ipg_gate")
+	clkdev("imx21-uart.2", "per", "uart3_per_gate")
+	clkdev("imx21-uart.2", "ipg", "uart3_ipg_gate")
+	clkdev("imx21-uart.3", "per", "uart4_per_gate")
+	clkdev("imx21-uart.3", "ipg", "uart4_ipg_gate")
+	clkdev("imx21-uart.4", "per", "uart5_per_gate")
+	clkdev("imx21-uart.4", "ipg", "uart5_ipg_gate")
+	clkdev("imx51-ecspi.0", "per", "ecspi1_per_gate")
+	clkdev("imx51-ecspi.0", "ipg", "ecspi1_ipg_gate")
+	clkdev("imx51-ecspi.1", "per", "ecspi2_per_gate")
+	clkdev("imx51-ecspi.1", "ipg", "ecspi2_ipg_gate")
+	clkdev("imx51-cspi.0", NULL, "cspi_ipg_gate")
+	clkdev("mxc_pwm.0", "pwm", "pwm1_ipg_gate")
+	clkdev("mxc_pwm.1", "pwm", "pwm2_ipg_gate")
+	clkdev("imx-i2c.0", NULL, "i2c1_gate")
+	clkdev("imx-i2c.1", NULL, "i2c2_gate")
+	clkdev("mxc-ehci.0", "per", "usboh3_per_gate")
+	clkdev("mxc-ehci.0", "ipg", "usboh3_gate")
+	clkdev("mxc-ehci.0", "ahb", "usboh3_gate")
+	clkdev("mxc-ehci.1", "per", "usboh3_per_gate")
+	clkdev("mxc-ehci.1", "ipg", "usboh3_gate")
+	clkdev("mxc-ehci.1", "ahb", "usboh3_gate")
+	clkdev("mxc-ehci.2", "per", "usboh3_per_gate")
+	clkdev("mxc-ehci.2", "ipg", "usboh3_gate")
+	clkdev("mxc-ehci.2", "ahb", "usboh3_gate")
+	clkdev("fsl-usb2-udc", "per", "usboh3_per_gate")
+	clkdev("fsl-usb2-udc", "ipg", "usboh3_gate")
+	clkdev("fsl-usb2-udc", "ahb", "usboh3_gate")
+	clkdev("mxc_nand", NULL, "nfc_gate")
+	clkdev("imx-ssi.0", NULL, "ssi1_ipg_gate")
+	clkdev("imx-ssi.1", NULL, "ssi1_ipg_gate")
+	clkdev("imx-ssi.2", NULL, "ssi1_ipg_gate")
+	clkdev("imx35-sdma", NULL, "sdma_gate")
+	clkdev(NULL, "cpu", "cpu_podf")
+	clkdev(NULL, "iim", "iim_gate")
+	clkdev("imx2-wdt.0", NULL, "dummy")
+	clkdev("imx2-wdt.1", NULL, "dummy")
+	clkdev("imx-keypad", NULL, "dummy")
+	clkdev("imx-tve.0", NULL, "tve_gate")
+	clkdev("imx-tve.0", "di1", "ipu_di1_gate")
+};
+
+static struct clk_lookup mx51_lookups[] = {
+	clkdev("imx-i2c.2", NULL, "hsi2c_gate")
+	clkdev(NULL, "mipi_hsp", "mx51_mipi")
+	clkdev("imx51-vpu.0", NULL, "vpu")
+	clkdev("imx27-fec.0", NULL, "fec_gate")
+	clkdev(NULL, "gpc_dvfs", "gpc_dvfs")
+	clkdev("imx51-ipu", NULL, "ipu")
+	clkdev("imx51-ipu", "di0", "ipu_di0_gate")
+	clkdev("imx51-ipu", "di1", "ipu_di1_gate")
+	clkdev("imx51-ipu", "hsp", "ipu_gate")
+	clkdev("mxc-ehci.0", "usb_phy1", "usb_phy_gate")
+	clkdev("sdhci-esdhc-imx51.0", "ipg", "esdhc1_ipg_gate")
+	clkdev("sdhci-esdhc-imx51.0", "ahb", "dummy")
+	clkdev("sdhci-esdhc-imx51.0", "per", "esdhc1_per_gate")
+	clkdev("sdhci-esdhc-imx51.1", "ipg", "esdhc2_ipg_gate")
+	clkdev("sdhci-esdhc-imx51.1", "ahb", "dummy")
+	clkdev("sdhci-esdhc-imx51.1", "per", "esdhc2_per_gate")
+	clkdev("sdhci-esdhc-imx51.2", "ipg", "esdhc3_ipg_gate")
+	clkdev("sdhci-esdhc-imx51.2", "ahb", "dummy")
+	clkdev("sdhci-esdhc-imx51.2", "per", "esdhc3_per_gate")
+	clkdev("sdhci-esdhc-imx51.3", "ipg", "esdhc4_ipg_gate")
+	clkdev("sdhci-esdhc-imx51.3", "ahb", "dummy")
+	clkdev("sdhci-esdhc-imx51.3", "per", "esdhc4_per_gate")
+};
+
+static struct clk_lookup mx53_lookups[] = {
+	clkdev("imx53-vpu.0", NULL, "vpu")
+	clkdev("imx-i2c.2", NULL, "i2c3_gate")
+	clkdev("imx25-fec.0", NULL, "fec_gate")
+	clkdev("imx53-ipu", NULL, "ipu")
+	clkdev("imx53-ipu", "di0", "ipu_di0_gate")
+	clkdev("imx53-ipu", "di1", "ipu_di1_gate")
+	clkdev("imx53-ipu", "hsp", "ipu_gate")
+	clkdev("mxc-ehci.0", "usb_phy1", "usb_phy1_gate")
+	clkdev("sdhci-esdhc-imx53.0", "ipg", "esdhc1_ipg_gate")
+	clkdev("sdhci-esdhc-imx53.0", "ahb", "dummy")
+	clkdev("sdhci-esdhc-imx53.0", "per", "esdhc1_per_gate")
+	clkdev("sdhci-esdhc-imx53.1", "ipg", "esdhc2_ipg_gate")
+	clkdev("sdhci-esdhc-imx53.1", "ahb", "dummy")
+	clkdev("sdhci-esdhc-imx53.1", "per", "esdhc2_per_gate")
+	clkdev("sdhci-esdhc-imx53.2", "ipg", "esdhc3_ipg_gate")
+	clkdev("sdhci-esdhc-imx53.2", "ahb", "dummy")
+	clkdev("sdhci-esdhc-imx53.2", "per", "esdhc3_per_gate")
+	clkdev("sdhci-esdhc-imx53.3", "ipg", "esdhc4_ipg_gate")
+	clkdev("sdhci-esdhc-imx53.3", "ahb", "dummy")
+	clkdev("sdhci-esdhc-imx53.3", "per", "esdhc4_per_gate")
+};
+
+static struct clk *pll1, *pll2, *pll3, *pll4, *iim,
+		  *emi_fast, *ahb_max, *aips_tz1, *aips_tz2,
+		  *spba, *tmax1, *tmax2, *tmax3, *esdhc_a_sel, *esdhc_b_sel,
+		  *esdhc_a_podf, *esdhc_b_podf;
+
+static void __init mx5_clocks_common_init(unsigned long rate_ckil,
+		unsigned long rate_osc, unsigned long rate_ckih1,
+		unsigned long rate_ckih2)
+{
+	imx_clk_fixed("dummy", 0);
+	imx_clk_fixed("ckil", rate_ckil);
+	imx_clk_fixed("osc", rate_osc);
+	imx_clk_fixed("ckih1", rate_ckih1);
+	imx_clk_fixed("ckih2", rate_ckih2);
+
+	imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1, lp_apm_sel,
+			ARRAY_SIZE(lp_apm_sel));
+	imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2, periph_apm_sel,
+			ARRAY_SIZE(periph_apm_sel));
+	imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1, main_bus_sel,
+			ARRAY_SIZE(main_bus_sel));
+	imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3);
+	ahb_max = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28);
+	aips_tz1 = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24);
+	aips_tz2 = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26);
+	tmax1 = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0);
+	tmax2 = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2);
+	tmax3 = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4);
+	spba = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0);
+	imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2);
+	imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3);
+	imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3);
+	imx_clk_mux("uart_sel", MXC_CCM_CSCMR1, 24, 2, standard_pll_sel,
+			ARRAY_SIZE(standard_pll_sel));
+	imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3);
+	imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3);
+
+	esdhc_a_sel = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2, standard_pll_sel,
+			ARRAY_SIZE(standard_pll_sel));
+	esdhc_b_sel = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2, standard_pll_sel,
+			ARRAY_SIZE(standard_pll_sel));
+	imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3);
+	esdhc_a_podf = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3);
+	imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3);
+	esdhc_b_podf = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3);
+	imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
+	imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
+
+	imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1, emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
+	imx_clk_divider("emi_slow_podf", "emi_sel", MXC_CCM_CBCDR, 22, 3);
+	imx_clk_divider("nfc_podf", "emi_slow_podf", MXC_CCM_CBCDR, 13, 3);
+	imx_clk_mux("ecspi_sel", MXC_CCM_CSCMR1, 4, 2, standard_pll_sel,
+			ARRAY_SIZE(standard_pll_sel));
+	imx_clk_divider("ecspi_pred", "ecspi_sel", MXC_CCM_CSCDR2, 25, 3);
+	imx_clk_divider("ecspi_podf", "ecspi_pred", MXC_CCM_CSCDR2, 19, 6);
+	imx_clk_mux("usboh3_sel", MXC_CCM_CSCMR1, 22, 2, standard_pll_sel,
+			ARRAY_SIZE(standard_pll_sel));
+	imx_clk_divider("usboh3_pred", "usboh3_sel", MXC_CCM_CSCDR1, 8, 3);
+	imx_clk_divider("usboh3_podf", "usboh3_pred", MXC_CCM_CSCDR1, 6, 2);
+	imx_clk_divider("usb_phy_pred", "pll3_sw", MXC_CCM_CDCDR, 3, 3);
+	imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3);
+	imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1, usb_phy_sel,
+			ARRAY_SIZE(usb_phy_sel));
+	imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3);
+	imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
+	imx_clk_fixed("tve_di", 65000000); /* FIXME */
+	imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, tve_sel, ARRAY_SIZE(tve_sel));
+	iim = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
+	imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
+	imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8);
+	imx_clk_gate2("uart2_ipg_gate", "ipg", MXC_CCM_CCGR1, 10);
+	imx_clk_gate2("uart2_per_gate", "uart_root", MXC_CCM_CCGR1, 12);
+	imx_clk_gate2("uart3_ipg_gate", "ipg", MXC_CCM_CCGR1, 14);
+	imx_clk_gate2("uart3_per_gate", "uart_root", MXC_CCM_CCGR1, 16);
+	imx_clk_gate2("i2c1_gate", "ipg", MXC_CCM_CCGR1, 18);
+	imx_clk_gate2("i2c2_gate", "ipg", MXC_CCM_CCGR1, 20);
+	imx_clk_gate2("gpt_ipg_gate", "ipg", MXC_CCM_CCGR2, 20);
+	imx_clk_gate2("pwm1_ipg_gate", "ipg", MXC_CCM_CCGR2, 10);
+	imx_clk_gate2("pwm1_hf_gate", "ipg", MXC_CCM_CCGR2, 12);
+	imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14);
+	imx_clk_gate2("pwm2_hf_gate", "ipg", MXC_CCM_CCGR2, 16);
+	imx_clk_gate2("gpt_gate", "ipg", MXC_CCM_CCGR2, 18);
+	imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24);
+	imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26);
+	imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28);
+	imx_clk_gate2("esdhc1_ipg_gate", "ipg", MXC_CCM_CCGR3, 0);
+	imx_clk_gate2("esdhc2_ipg_gate", "ipg", MXC_CCM_CCGR3, 4);
+	imx_clk_gate2("esdhc3_ipg_gate", "ipg", MXC_CCM_CCGR3, 8);
+	imx_clk_gate2("esdhc4_ipg_gate", "ipg", MXC_CCM_CCGR3, 12);
+	imx_clk_gate2("ssi1_ipg_gate", "ipg", MXC_CCM_CCGR3, 16);
+	imx_clk_gate2("ssi2_ipg_gate", "ipg", MXC_CCM_CCGR3, 18);
+	imx_clk_gate2("ssi3_ipg_gate", "ipg", MXC_CCM_CCGR3, 20);
+	imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6);
+	imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8);
+	imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10);
+	imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12);
+	imx_clk_gate2("ecspi1_ipg_gate", "ipg", MXC_CCM_CCGR4, 18);
+	imx_clk_gate2("ecspi1_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 20);
+	imx_clk_gate2("ecspi2_ipg_gate", "ipg", MXC_CCM_CCGR4, 22);
+	imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24);
+	imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26);
+	imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30);
+	emi_fast = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14);
+	imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16);
+	imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel));
+	imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10);
+	imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20);
+	imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10);
+	imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12);
+	imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
+	imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
+	imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
+	imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
+	imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
+	imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
+	imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
+	imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24);
+
+	clkdev_add_table(mx5_lookups, ARRAY_SIZE(mx5_lookups));
+
+	/* Set SDHC parents to be PLL2 */
+	clk_set_parent(esdhc_a_sel, pll2);
+	clk_set_parent(esdhc_b_sel, pll2);
+
+	clk_prepare_enable(ahb_max); /* esdhc3 */
+	clk_prepare_enable(aips_tz1);
+	clk_prepare_enable(aips_tz2); /* fec */
+	clk_prepare_enable(spba);
+	clk_prepare_enable(emi_fast); /* fec */
+	clk_prepare_enable(tmax1);
+	clk_prepare_enable(tmax2); /* esdhc2, fec */
+	clk_prepare_enable(tmax3); /* esdhc1, esdhc4 */
+}
+
+int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
+			unsigned long rate_ckih1, unsigned long rate_ckih2)
+{
+	pll1 = imx_clk_pllv2("pll1_sw", "osc", MX51_DPLL1_BASE);
+	pll2 = imx_clk_pllv2("pll2_sw", "osc", MX51_DPLL2_BASE);
+	pll3 = imx_clk_pllv2("pll3_sw", "osc", MX51_DPLL3_BASE);
+	imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, mx51_ipu_di0_sel,
+			ARRAY_SIZE(mx51_ipu_di0_sel));
+	imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, mx51_ipu_di1_sel,
+			ARRAY_SIZE(mx51_ipu_di1_sel));
+	imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, mx51_tve_ext_sel,
+			ARRAY_SIZE(mx51_tve_ext_sel));
+	imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
+	imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
+	imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
+	imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6);
+	imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10);
+	imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
+	imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0);
+	imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22);
+
+	mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2);
+
+	clkdev_add_table(mx51_lookups, ARRAY_SIZE(mx51_lookups));
+
+	/* set SDHC root clock to 166.25MHZ*/
+	clk_set_rate(esdhc_a_podf, 166250000);
+	clk_set_rate(esdhc_b_podf, 166250000);
+
+	/* System timer */
+	mxc_timer_init(NULL, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
+		MX51_INT_GPT);
+
+	clk_prepare_enable(iim);
+	imx_print_silicon_rev("i.MX51", mx51_revision());
+	clk_disable_unprepare(iim);
+
+	return 0;
+}
+
+int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
+			unsigned long rate_ckih1, unsigned long rate_ckih2)
+{
+	pll1 = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE);
+	pll2 = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE);
+	pll3 = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE);
+	pll4 = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE);
+
+	imx_clk_mux("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1, mx53_ldb_di1_sel,
+			ARRAY_SIZE(mx53_ldb_di1_sel));
+	imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+	imx_clk_divider("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1);
+	imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3);
+	imx_clk_mux("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1, mx53_ldb_di0_sel,
+			ARRAY_SIZE(mx53_ldb_di0_sel));
+	imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+	imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1);
+	imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
+	imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
+	imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, mx53_ipu_di0_sel,
+			ARRAY_SIZE(mx53_ipu_di0_sel));
+	imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, mx53_ipu_di1_sel,
+			ARRAY_SIZE(mx53_ipu_di1_sel));
+	imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, mx53_tve_ext_sel,
+			ARRAY_SIZE(mx53_tve_ext_sel));
+	imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
+	imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
+	imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
+	imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
+	imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
+	imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
+	imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
+	imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
+	imx_clk_gate2("i2c3_gate", "ipg", MXC_CCM_CCGR1, 22);
+
+	mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2);
+
+	clkdev_add_table(mx53_lookups, ARRAY_SIZE(mx53_lookups));
+
+	/* set SDHC root clock to 200MHZ*/
+	clk_set_rate(esdhc_a_podf, 200000000);
+	clk_set_rate(esdhc_b_podf, 200000000);
+
+	/* System timer */
+	mxc_timer_init(NULL, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
+		MX53_INT_GPT);
+
+	clk_prepare_enable(iim);
+	imx_print_silicon_rev("i.MX53", mx53_revision());
+	clk_disable_unprepare(iim);
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
+				   unsigned long *ckih1, unsigned long *ckih2)
+{
+	struct device_node *np;
+
+	/* retrieve the freqency of fixed clocks from device tree */
+	for_each_compatible_node(np, NULL, "fixed-clock") {
+		u32 rate;
+		if (of_property_read_u32(np, "clock-frequency", &rate))
+			continue;
+
+		if (of_device_is_compatible(np, "fsl,imx-ckil"))
+			*ckil = rate;
+		else if (of_device_is_compatible(np, "fsl,imx-osc"))
+			*osc = rate;
+		else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
+			*ckih1 = rate;
+		else if (of_device_is_compatible(np, "fsl,imx-ckih2"))
+			*ckih2 = rate;
+	}
+}
+
+int __init mx51_clocks_init_dt(void)
+{
+	unsigned long ckil, osc, ckih1, ckih2;
+
+	clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
+	return mx51_clocks_init(ckil, osc, ckih1, ckih2);
+}
+
+int __init mx53_clocks_init_dt(void)
+{
+	unsigned long ckil, osc, ckih1, ckih2;
+
+	clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
+	return mx53_clocks_init(ckil, osc, ckih1, ckih2);
+}
+#endif
-- 
1.7.9.5

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

* [PATCH 33/40] ARM i.MX35: implement clocks using common clock framework
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (31 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 32/40] ARM i.MX5: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 34/40] ARM: imx6: " Sascha Hauer
                   ` (6 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/Kconfig     |    1 +
 arch/arm/mach-imx/Makefile    |    2 +-
 arch/arm/mach-imx/clk-imx35.c |  259 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 261 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-imx35.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index eb14ae9..a8b3738 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -75,6 +75,7 @@ config SOC_IMX35
 	bool
 	select CPU_V6
 	select ARCH_MXC_IOMUX_V3
+	select COMMON_CLK
 	select HAVE_EPIT
 	select MXC_AVIC
 	select SMP_ON_UP if SMP
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index adf2e4f..38811ad 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
 obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
 
 obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
-obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o
+obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
 
 obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
 
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
new file mode 100644
index 0000000..7d26ae8
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx35.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * 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/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#include "crmregs-imx3.h"
+#include "clk.h"
+
+#define clkdev(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clkname = c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	clkdev("pata_imx", NULL, "pata_gate")
+	clkdev("flexcan.0", NULL, "can1_gate")
+	clkdev("flexcan.1", NULL, "can2_gate")
+	clkdev("imx35-cspi.0", "per", "cspi1_gate")
+	clkdev("imx35-cspi.0", "ipg", "cspi1_gate")
+	clkdev("imx35-cspi.1", "per", "cspi2_gate")
+	clkdev("imx35-cspi.1", "ipg", "cspi2_gate")
+	clkdev("imx-epit.0", NULL, "epit1_gate")
+	clkdev("imx-epit.1", NULL, "epit2_gate")
+	clkdev("sdhci-esdhc-imx35.0", "per", "esdhc1_gate")
+	clkdev("sdhci-esdhc-imx35.0", "ipg", "ipg")
+	clkdev("sdhci-esdhc-imx35.0", "ahb", "ahb")
+	clkdev("sdhci-esdhc-imx35.1", "per", "esdhc2_gate")
+	clkdev("sdhci-esdhc-imx35.1", "ipg", "ipg")
+	clkdev("sdhci-esdhc-imx35.1", "ahb", "ahb")
+	clkdev("sdhci-esdhc-imx35.2", "per", "esdhc3_gate")
+	clkdev("sdhci-esdhc-imx35.2", "ipg", "ipg")
+	clkdev("sdhci-esdhc-imx35.2", "ahb", "ahb")
+	/* i.mx35 has the i.mx27 type fec */
+	clkdev("imx27-fec.0", NULL, "fec_gate")
+	clkdev("imx-gpt.0", "per", "gpt_gate")
+	clkdev("imx-gpt.0", "ipg", "ipg")
+	clkdev("imx-i2c.0", NULL, "i2c1_gate")
+	clkdev("imx-i2c.1", NULL, "i2c2_gate")
+	clkdev("imx-i2c.2", NULL, "i2c3_gate")
+	clkdev("ipu-core", NULL, "ipu_gate")
+	clkdev("mx3_sdc_fb", NULL, "ipu_gate")
+	clkdev("mxc_w1", NULL, "owire_gate")
+	clkdev("imx35-sdma", NULL, "sdma_gate")
+	clkdev("imx-ssi.0", "ipg", "ipg")
+	clkdev("imx-ssi.0", "per", "ssi1_div_post")
+	clkdev("imx-ssi.1", "ipg", "ipg")
+	clkdev("imx-ssi.1", "per", "ssi2_div_post")
+	/* i.mx35 has the i.mx21 type uart */
+	clkdev("imx21-uart.0", "per", "uart1_gate")
+	clkdev("imx21-uart.0", "ipg", "ipg")
+	clkdev("imx21-uart.1", "per", "uart2_gate")
+	clkdev("imx21-uart.1", "ipg", "ipg")
+	clkdev("imx21-uart.2", "per", "uart3_gate")
+	clkdev("imx21-uart.2", "ipg", "ipg")
+	clkdev("mxc-ehci.0", "per", "usb_div")
+	clkdev("mxc-ehci.0", "ipg", "ipg")
+	clkdev("mxc-ehci.0", "ahb", "usbotg_gate")
+	clkdev("mxc-ehci.1", "per", "usb_div")
+	clkdev("mxc-ehci.1", "ipg", "ipg")
+	clkdev("mxc-ehci.1", "ahb", "usbotg_gate")
+	clkdev("mxc-ehci.2", "per", "usb_div")
+	clkdev("mxc-ehci.2", "ipg", "ipg")
+	clkdev("mxc-ehci.2", "ahb", "usbotg_gate")
+	clkdev("fsl-usb2-udc", "per", "usb_div")
+	clkdev("fsl-usb2-udc", "ipg", "ipg")
+	clkdev("fsl-usb2-udc", "ahb", "usbahb_gate")
+	clkdev("imx2-wdt.0", NULL, "wdog_gate")
+	clkdev("mxc_nand.0", NULL, "nfc_div")
+};
+
+struct arm_ahb_div {
+	unsigned char arm, ahb, sel;
+};
+
+static struct arm_ahb_div clk_consumer[] = {
+	{ .arm = 1, .ahb = 4, .sel = 0},
+	{ .arm = 1, .ahb = 3, .sel = 1},
+	{ .arm = 2, .ahb = 2, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 4, .ahb = 1, .sel = 0},
+	{ .arm = 1, .ahb = 5, .sel = 0},
+	{ .arm = 1, .ahb = 8, .sel = 0},
+	{ .arm = 1, .ahb = 6, .sel = 1},
+	{ .arm = 2, .ahb = 4, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 4, .ahb = 2, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static char hsp_div_532[] = { 4, 8, 3, 0 };
+static char hsp_div_400[] = { 3, 6, 3, 0 };
+
+static char *std_sel[] = {"ppll", "arm"};
+static char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
+
+int __init mx35_clocks_init()
+{
+	void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
+	u32 pdr0, consumer_sel, hsp_sel;
+	struct arm_ahb_div *aad;
+	struct clk *spba, *gpio1, *gpio2, *gpio3, *arm, *iim, *emi;
+	unsigned char *hsp_div;
+
+	pdr0 = __raw_readl(base + MXC_CCM_PDR0);
+	consumer_sel = (pdr0 >> 16) & 0xf;
+	aad = &clk_consumer[consumer_sel];
+	if (!aad->arm) {
+		pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel);
+		/*
+		 * We are basically stuck. Continue with a default entry and hope we
+		 * get far enough to actually show the above message
+		 */
+		aad = &clk_consumer[0];
+	}
+
+	imx_clk_fixed("ckih", 24000000);
+	imx_clk_pllv1("mpll", "ckih", base + MX35_CCM_MPCTL);
+	imx_clk_pllv1("ppll", "ckih", base + MX35_CCM_PPCTL);
+
+	imx_clk_fixed_factor("mpll", "mpll_075", 3, 4);
+
+	if (aad->sel)
+		arm = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm);
+	else
+		arm = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm);
+
+	if (clk_get_rate(arm) > 400000000)
+		hsp_div = hsp_div_532;
+	else
+		hsp_div = hsp_div_400;
+
+	hsp_sel = (pdr0 >> 20) & 0x3;
+	if (!hsp_div[hsp_sel]) {
+		pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel);
+		hsp_sel = 0;
+	}
+
+	imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]);
+
+	imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb);
+	imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+
+	imx_clk_divider("arm_per_div", "arm", base + MX35_CCM_PDR4, 16, 6);
+	imx_clk_divider("ahb_per_div", "ahb", base + MXC_CCM_PDR0, 12, 3);
+	imx_clk_mux("ipg_per", base + MXC_CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel));
+
+	imx_clk_mux("uart_sel", base + MX35_CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel));
+	imx_clk_divider("uart_div", "uart_sel", base + MX35_CCM_PDR4, 10, 6);
+
+	imx_clk_mux("esdhc_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
+	imx_clk_divider("esdhc1_div", "esdhc_sel", base + MX35_CCM_PDR3, 0, 6);
+	imx_clk_divider("esdhc2_div", "esdhc_sel", base + MX35_CCM_PDR3, 8, 6);
+	imx_clk_divider("esdhc3_div", "esdhc_sel", base + MX35_CCM_PDR3, 16, 6);
+
+	imx_clk_mux("ssi_sel", base + MX35_CCM_PDR2, 6, 1, std_sel, ARRAY_SIZE(std_sel));
+	imx_clk_divider("ssi1_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 24, 3);
+	imx_clk_divider("ssi1_div_post", "ssi1_div_pre", base + MX35_CCM_PDR2, 0, 6);
+	imx_clk_divider("ssi2_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 27, 3);
+	imx_clk_divider("ssi2_div_post", "ssi2_div_pre", base + MX35_CCM_PDR2, 8, 6);
+
+	imx_clk_mux("usb_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
+	imx_clk_divider("usb_div", "usb_sel", base + MX35_CCM_PDR4, 22, 6);
+
+	imx_clk_divider("nfc_div", "ahb", base + MX35_CCM_PDR4, 28, 4);
+
+	imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0,  0);
+	imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0,  2);
+	imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0,  4);
+	imx_clk_gate2("can1_gate", "ipg", base + MX35_CCM_CGR0,  6);
+	imx_clk_gate2("can2_gate", "ipg", base + MX35_CCM_CGR0,  8);
+	imx_clk_gate2("cspi1_gate", "ipg", base + MX35_CCM_CGR0, 10);
+	imx_clk_gate2("cspi2_gate", "ipg", base + MX35_CCM_CGR0, 12);
+	imx_clk_gate2("ect_gate", "ipg", base + MX35_CCM_CGR0, 14);
+	imx_clk_gate2("edio_gate",   "ipg", base + MX35_CCM_CGR0, 16);
+	emi = imx_clk_gate2("emi_gate", "ipg", base + MX35_CCM_CGR0, 18);
+	imx_clk_gate2("epit1_gate", "ipg", base + MX35_CCM_CGR0, 20);
+	imx_clk_gate2("epit2_gate", "ipg", base + MX35_CCM_CGR0, 22);
+	imx_clk_gate2("esai_gate",   "ipg", base + MX35_CCM_CGR0, 24);
+	imx_clk_gate2("esdhc1_gate", "esdhc1_div", base + MX35_CCM_CGR0, 26);
+	imx_clk_gate2("esdhc2_gate", "esdhc2_div", base + MX35_CCM_CGR0, 28);
+	imx_clk_gate2("esdhc3_gate", "esdhc3_div", base + MX35_CCM_CGR0, 30);
+
+	imx_clk_gate2("fec_gate", "ipg", base + MX35_CCM_CGR1,  0);
+	gpio1 = imx_clk_gate2("gpio1_gate", "ipg", base + MX35_CCM_CGR1,  2);
+	gpio2 = imx_clk_gate2("gpio2_gate", "ipg", base + MX35_CCM_CGR1,  4);
+	gpio3 = imx_clk_gate2("gpio3_gate", "ipg", base + MX35_CCM_CGR1,  6);
+	imx_clk_gate2("gpt_gate", "ipg", base + MX35_CCM_CGR1,  8);
+	imx_clk_gate2("i2c1_gate", "ipg_per", base + MX35_CCM_CGR1, 10);
+	imx_clk_gate2("i2c2_gate", "ipg_per", base + MX35_CCM_CGR1, 12);
+	imx_clk_gate2("i2c3_gate", "ipg_per", base + MX35_CCM_CGR1, 14);
+	imx_clk_gate2("iomuxc_gate", "ipg", base + MX35_CCM_CGR1, 16);
+	imx_clk_gate2("ipu_gate", "hsp", base + MX35_CCM_CGR1, 18);
+	imx_clk_gate2("kpp_gate", "ipg", base + MX35_CCM_CGR1, 20);
+	imx_clk_gate2("mlb_gate", "ahb", base + MX35_CCM_CGR1, 22);
+	imx_clk_gate2("mshc_gate", "dummy", base + MX35_CCM_CGR1, 24);
+	imx_clk_gate2("owire_gate", "ipg_per", base + MX35_CCM_CGR1, 26);
+	imx_clk_gate2("pwm_gate", "ipg_per", base + MX35_CCM_CGR1, 28);
+	imx_clk_gate2("rngc_gate", "ipg", base + MX35_CCM_CGR1, 30);
+
+	imx_clk_gate2("rtc_gate", "ipg", base + MX35_CCM_CGR2,  0);
+	imx_clk_gate2("rtic_gate", "ahb", base + MX35_CCM_CGR2,  2);
+	imx_clk_gate2("scc_gate", "ipg", base + MX35_CCM_CGR2,  4);
+	imx_clk_gate2("sdma_gate", "ahb", base + MX35_CCM_CGR2,  6);
+	spba = imx_clk_gate2("spba_gate", "ipg", base + MX35_CCM_CGR2,  8);
+	imx_clk_gate2("spdif_gate", "spdif_div_post", base + MX35_CCM_CGR2, 10);
+	imx_clk_gate2("ssi1_gate", "ssi1_div_post", base + MX35_CCM_CGR2, 12);
+	imx_clk_gate2("ssi2_gate", "ssi2_div_post", base + MX35_CCM_CGR2, 14);
+	imx_clk_gate2("uart1_gate", "uart_div", base + MX35_CCM_CGR2, 16);
+	imx_clk_gate2("uart2_gate", "uart_div", base + MX35_CCM_CGR2, 18);
+	imx_clk_gate2("uart3_gate", "uart_div", base + MX35_CCM_CGR2, 20);
+	imx_clk_gate2("usbotg_gate", "ahb", base + MX35_CCM_CGR2, 22);
+	imx_clk_gate2("wdog_gate", "ipg", base + MX35_CCM_CGR2, 24);
+	imx_clk_gate2("max_gate", "dummy", base + MX35_CCM_CGR2, 26);
+	imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR2, 30);
+
+	imx_clk_gate2("csi_gate", "ipg", base + MX35_CCM_CGR3,  0);
+	iim = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3,  2);
+	imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3,  4);
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	clk_prepare_enable(spba);
+	clk_prepare_enable(gpio1);
+	clk_prepare_enable(gpio2);
+	clk_prepare_enable(gpio3);
+	clk_prepare_enable(iim);
+	clk_prepare_enable(emi);
+
+	imx_print_silicon_rev("i.MX35", mx35_revision());
+
+#ifdef CONFIG_MXC_USE_EPIT
+	epit_timer_init(&epit1_clk,
+			MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
+#else
+	mxc_timer_init(NULL, MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR),
+			MX35_INT_GPT);
+#endif
+
+	return 0;
+}
-- 
1.7.9.5

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

* [PATCH 34/40] ARM: imx6: implement clocks using common clock framework
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (32 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 33/40] ARM i.MX35: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-18 11:33   ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 35/40] ARM i.MX: remove now unused old clock support Sascha Hauer
                   ` (5 subsequent siblings)
  39 siblings, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/Kconfig     |    1 +
 arch/arm/mach-imx/Makefile    |    2 +-
 arch/arm/mach-imx/clk-imx6q.c |  407 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 409 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-imx6q.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index a8b3738..c8e4ec1 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -843,6 +843,7 @@ config SOC_IMX6Q
 	bool "i.MX6 Quad support"
 	select ARM_CPU_SUSPEND if PM
 	select ARM_GIC
+	select COMMON_CLK
 	select CPU_V7
 	select HAVE_ARM_SCU
 	select HAVE_IMX_GPC
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 38811ad..629a339 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -73,7 +73,7 @@ obj-$(CONFIG_CPU_V7) += head-v7.o
 AFLAGS_head-v7.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SMP) += platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
-obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o
+obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
 
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
new file mode 100644
index 0000000..f379fa6
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <mach/common.h>
+#include "clk.h"
+
+#define CCGR0				0x68
+#define CCGR1				0x6c
+#define CCGR2				0x70
+#define CCGR3				0x74
+#define CCGR4				0x78
+#define CCGR5				0x7c
+#define CCGR6				0x80
+#define CCGR7				0x84
+
+#define CLPCR				0x54
+#define BP_CLPCR_LPM			0
+#define BM_CLPCR_LPM			(0x3 << 0)
+#define BM_CLPCR_BYPASS_PMIC_READY	(0x1 << 2)
+#define BM_CLPCR_ARM_CLK_DIS_ON_LPM	(0x1 << 5)
+#define BM_CLPCR_SBYOS			(0x1 << 6)
+#define BM_CLPCR_DIS_REF_OSC		(0x1 << 7)
+#define BM_CLPCR_VSTBY			(0x1 << 8)
+#define BP_CLPCR_STBY_COUNT		9
+#define BM_CLPCR_STBY_COUNT		(0x3 << 9)
+#define BM_CLPCR_COSC_PWRDOWN		(0x1 << 11)
+#define BM_CLPCR_WB_PER_AT_LPM		(0x1 << 16)
+#define BM_CLPCR_WB_CORE_AT_LPM		(0x1 << 17)
+#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS	(0x1 << 19)
+#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS	(0x1 << 21)
+#define BM_CLPCR_MASK_CORE0_WFI		(0x1 << 22)
+#define BM_CLPCR_MASK_CORE1_WFI		(0x1 << 23)
+#define BM_CLPCR_MASK_CORE2_WFI		(0x1 << 24)
+#define BM_CLPCR_MASK_CORE3_WFI		(0x1 << 25)
+#define BM_CLPCR_MASK_SCU_IDLE		(0x1 << 26)
+#define BM_CLPCR_MASK_L2CC_IDLE		(0x1 << 27)
+
+static void __iomem *ccm_base;
+
+void __init imx6q_clock_map_io(void) { }
+
+int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
+{
+	u32 val = readl_relaxed(ccm_base + CLPCR);
+
+	val &= ~BM_CLPCR_LPM;
+	switch (mode) {
+	case WAIT_CLOCKED:
+		break;
+	case WAIT_UNCLOCKED:
+		val |= 0x1 << BP_CLPCR_LPM;
+		break;
+	case STOP_POWER_ON:
+		val |= 0x2 << BP_CLPCR_LPM;
+		break;
+	case WAIT_UNCLOCKED_POWER_OFF:
+		val |= 0x1 << BP_CLPCR_LPM;
+		val &= ~BM_CLPCR_VSTBY;
+		val &= ~BM_CLPCR_SBYOS;
+		break;
+	case STOP_POWER_OFF:
+		val |= 0x2 << BP_CLPCR_LPM;
+		val |= 0x3 << BP_CLPCR_STBY_COUNT;
+		val |= BM_CLPCR_VSTBY;
+		val |= BM_CLPCR_SBYOS;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	writel_relaxed(val, ccm_base + CLPCR);
+
+	return 0;
+}
+
+#define clkdev(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clkname = c, \
+	}
+
+static struct clk_lookup lookups[] = {
+	clkdev("mmdc_ch0_axi", NULL, "mmdc_ch0_axi"),
+	clkdev("mmdc_ch1_axi", NULL, "mmdc_ch1_axi"),
+	clkdev("uart_ipg", NULL, "uart_ipg"),
+	clkdev("uart_serial", NULL, "uart_serial"),
+	clkdev("imx-gpt.0", "ipg", "gpt_ipg"),
+	clkdev("imx-gpt.0", "per", "gpt_ipg_per"),
+	clkdev("smp_twd", NULL, "twd"),
+	clkdev("2020000.uart", NULL, "uart_serial"),
+	clkdev("21e8000.uart", NULL, "uart_serial"),
+	clkdev("21ec000.uart", NULL, "uart_serial"),
+	clkdev("21f0000.uart", NULL, "uart_serial"),
+	clkdev("21f4000.uart", NULL, "uart_serial"),
+	clkdev("2188000.enet", NULL, "enet"),
+	clkdev("2190000.usdhc", NULL, "usdhc1"),
+	clkdev("2194000.usdhc", NULL, "usdhc2"),
+	clkdev("2198000.usdhc", NULL, "usdhc3"),
+	clkdev("219c000.usdhc", NULL, "usdhc4"),
+	clkdev("21a0000.i2c", NULL, "i2c1"),
+	clkdev("21a4000.i2c", NULL, "i2c2"),
+	clkdev("21a8000.i2c", NULL, "i2c3"),
+	clkdev("2008000.ecspi", NULL, "ecspi1"),
+	clkdev("200c000.ecspi", NULL, "ecspi2"),
+	clkdev("2010000.ecspi", NULL, "ecspi3"),
+	clkdev("2014000.ecspi", NULL, "ecspi4"),
+	clkdev("2018000.ecspi", NULL, "ecspi5"),
+	clkdev("20ec000.sdma", NULL, "sdma"),
+	clkdev("20bc000.wdog", NULL, "dummy"),
+	clkdev("20c0000.wdog", NULL, "dummy"),
+};
+
+static char *step_sels[]	= { "osc", "pll2_pfd2_396m", };
+static char *pll1_sw_sels[]	= { "pll1_sys", "step", };
+static char *periph_pre_sels[]	= { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
+static char *periph_clk2_sels[]	= { "pll3_usb_otg", "osc", };
+static char *periph_sels[]	= { "periph_pre", "periph_clk2", };
+static char *periph2_sels[]	= { "periph2_pre", "periph2_clk2", };
+static char *axi_sels[]		= { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static char *audio_sels[]	= { "pll4_audio", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
+static char *gpu_axi_sels[]	= { "axi", "ahb", };
+static char *gpu2d_core_sels[]	= { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
+static char *gpu3d_core_sels[]	= { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
+static char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", };
+static char *ipu_sels[]		= { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
+static char *ldb_di_sels[]	= { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static char *ipu_di_pre_sels[]	= { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static char *ipu1_di0_sels[]	= { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static char *ipu1_di1_sels[]	= { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static char *ipu2_di0_sels[]	= { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static char *ipu2_di1_sels[]	= { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static char *hsi_tx_sels[]	= { "pll3_120m", "pll2_pfd2_396m", };
+static char *pcie_axi_sels[]	= { "axi", "ahb", };
+static char *ssi_sels[]		= { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio", };
+static char *usdhc_sels[]	= { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static char *enfc_sels[]	= { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
+static char *emi_sels[]		= { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static char *vdo_axi_sels[]	= { "axi", "ahb", };
+static char *vpu_axi_sels[]	= { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static char *cko1_sels[]	= { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video",
+				    "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
+				    "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", };
+
+static const char * const clks_init_on[] __initconst = {
+	"mmdc_ch0_axi", "mmdc_ch1_axi", "uart_ipg", "uart_serial",
+};
+
+int __init mx6q_clocks_init(void)
+{
+	struct device_node *np;
+	struct clk *clk;
+	void __iomem *base;
+	int i, irq;
+
+	imx_clk_fixed("dummy", 0);
+
+	/* retrieve the freqency of fixed clocks from device tree */
+	for_each_compatible_node(np, NULL, "fixed-clock") {
+		u32 rate;
+		if (of_property_read_u32(np, "clock-frequency", &rate))
+			continue;
+
+		if (of_device_is_compatible(np, "fsl,imx-ckil"))
+			imx_clk_fixed("ckil", rate);
+		else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
+			imx_clk_fixed("ckih", rate);
+		else if (of_device_is_compatible(np, "fsl,imx-osc"))
+			imx_clk_fixed("osc", rate);
+	}
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
+	base = of_iomap(np, 0);
+	WARN_ON(!base);
+
+	/*            type               name         parent_name  base     gate_mask div_mask */
+	imx_clk_pllv3(IMX_PLLV3_SYS,	 "pll1_sys",	  "osc", base,	      0x2000,   0x7f);
+	imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus",	  "osc", base + 0x30, 0x2000,   0x1);
+	imx_clk_pllv3(IMX_PLLV3_USB,	 "pll3_usb_otg",  "osc", base + 0x10, 0x2000,   0x3);
+	imx_clk_pllv3(IMX_PLLV3_AV,	 "pll4_audio",	  "osc", base + 0x70, 0x2000,   0x7f);
+	imx_clk_pllv3(IMX_PLLV3_AV,	 "pll5_video",	  "osc", base + 0xa0, 0x2000,   0x7f);
+	imx_clk_pllv3(IMX_PLLV3_MLB,	 "pll6_mlb",	  "osc", base + 0xd0, 0x2000,   0x0);
+	imx_clk_pllv3(IMX_PLLV3_USB,	 "pll7_usb_host", "osc", base + 0x20, 0x2000,   0x3);
+	imx_clk_pllv3(IMX_PLLV3_ENET,	 "pll8_enet",	  "osc", base + 0xe0, 0x182000, 0x3);
+
+	/*          name              parent_name        reg       idx */
+	imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",     base + 0x100, 0);
+	imx_clk_pfd("pll2_pfd1_594m", "pll2_bus",     base + 0x100, 1);
+	imx_clk_pfd("pll2_pfd2_396m", "pll2_bus",     base + 0x100, 2);
+	imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0,  0);
+	imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0,  1);
+	imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0,  2);
+	imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0,  3);
+
+	/*                   name         parent_name     mult div */
+	imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
+	imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg",   1, 4);
+	imx_clk_fixed_factor("pll3_80m",  "pll3_usb_otg",   1, 6);
+	imx_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1, 8);
+	imx_clk_fixed_factor("twd",       "arm",            1, 2);
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
+	base = of_iomap(np, 0);
+	WARN_ON(!base);
+	ccm_base = base;
+
+	/*          name                reg       shift width parent_names     num_parents */
+	imx_clk_mux("step",	        base + 0xc,  8,  1, step_sels,	       ARRAY_SIZE(step_sels));
+	imx_clk_mux("pll1_sw",	        base + 0xc,  2,  1, pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
+	imx_clk_mux("periph_pre",       base + 0x18, 18, 2, periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));
+	imx_clk_mux("periph2_pre",      base + 0x18, 21, 2, periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));
+	imx_clk_mux("periph_clk2_sel",  base + 0x18, 12, 1, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
+	imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
+	imx_clk_mux("axi_sel",          base + 0x14, 6,  2, axi_sels,          ARRAY_SIZE(axi_sels));
+	imx_clk_mux("esai_sel",         base + 0x20, 19, 2, audio_sels,        ARRAY_SIZE(audio_sels));
+	imx_clk_mux("asrc_sel",         base + 0x30, 7,  2, audio_sels,        ARRAY_SIZE(audio_sels));
+	imx_clk_mux("spdif_sel",        base + 0x30, 20, 2, audio_sels,        ARRAY_SIZE(audio_sels));
+	imx_clk_mux("gpu2d_axi",        base + 0x18, 0,  1, gpu_axi_sels,      ARRAY_SIZE(gpu_axi_sels));
+	imx_clk_mux("gpu3d_axi",        base + 0x18, 1,  1, gpu_axi_sels,      ARRAY_SIZE(gpu_axi_sels));
+	imx_clk_mux("gpu2d_core_sel",   base + 0x18, 16, 2, gpu2d_core_sels,   ARRAY_SIZE(gpu2d_core_sels));
+	imx_clk_mux("gpu3d_core_sel",   base + 0x18, 4,  2, gpu3d_core_sels,   ARRAY_SIZE(gpu3d_core_sels));
+	imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8,  2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
+	imx_clk_mux("ipu1_sel",         base + 0x3c, 9,  2, ipu_sels,          ARRAY_SIZE(ipu_sels));
+	imx_clk_mux("ipu2_sel",         base + 0x3c, 14, 2, ipu_sels,          ARRAY_SIZE(ipu_sels));
+	imx_clk_mux("ldb_di0_sel",      base + 0x2c, 9,  3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
+	imx_clk_mux("ldb_di1_sel",      base + 0x2c, 12, 3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
+	imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	imx_clk_mux("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	imx_clk_mux("ipu1_di0_sel",     base + 0x34, 0,  3, ipu1_di0_sels,     ARRAY_SIZE(ipu1_di0_sels));
+	imx_clk_mux("ipu1_di1_sel",     base + 0x34, 9,  3, ipu1_di1_sels,     ARRAY_SIZE(ipu1_di1_sels));
+	imx_clk_mux("ipu2_di0_sel",     base + 0x38, 0,  3, ipu2_di0_sels,     ARRAY_SIZE(ipu2_di0_sels));
+	imx_clk_mux("ipu2_di1_sel",     base + 0x38, 9,  3, ipu2_di1_sels,     ARRAY_SIZE(ipu2_di1_sels));
+	imx_clk_mux("hsi_tx_sel",       base + 0x30, 28, 1, hsi_tx_sels,       ARRAY_SIZE(hsi_tx_sels));
+	imx_clk_mux("pcie_axi_sel",     base + 0x18, 10, 1, pcie_axi_sels,     ARRAY_SIZE(pcie_axi_sels));
+	imx_clk_mux("ssi1_sel",         base + 0x1c, 10, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
+	imx_clk_mux("ssi2_sel",         base + 0x1c, 12, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
+	imx_clk_mux("ssi3_sel",         base + 0x1c, 14, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
+	imx_clk_mux("usdhc1_sel",       base + 0x1c, 16, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	imx_clk_mux("usdhc2_sel",       base + 0x1c, 17, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	imx_clk_mux("usdhc3_sel",       base + 0x1c, 18, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	imx_clk_mux("usdhc4_sel",       base + 0x1c, 19, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	imx_clk_mux("enfc_sel",         base + 0x2c, 16, 2, enfc_sels,         ARRAY_SIZE(enfc_sels));
+	imx_clk_mux("emi_sel",          base + 0x1c, 27, 2, emi_sels,          ARRAY_SIZE(emi_sels));
+	imx_clk_mux("emi_slow_sel",     base + 0x1c, 29, 2, emi_sels,          ARRAY_SIZE(emi_sels));
+	imx_clk_mux("vdo_axi_sel",      base + 0x18, 11, 1, vdo_axi_sels,      ARRAY_SIZE(vdo_axi_sels));
+	imx_clk_mux("vpu_axi_sel",      base + 0x18, 14, 2, vpu_axi_sels,      ARRAY_SIZE(vpu_axi_sels));
+	imx_clk_mux("cko1_sel",         base + 0x60, 0,  4, cko1_sels,         ARRAY_SIZE(cko1_sels));
+
+	/*               name         reg      shift width busy: reg, shift parent_names  num_parents */
+	imx_clk_busy_mux("periph",  base + 0x14, 25,  1,   base + 0x48, 5,  periph_sels,  ARRAY_SIZE(periph_sels));
+	imx_clk_busy_mux("periph2", base + 0x14, 26,  1,   base + 0x48, 3,  periph2_sels, ARRAY_SIZE(periph2_sels));
+
+	/*              name                parent_name          reg       shift width */
+	imx_clk_divider("periph_clk2",      "periph_clk2_sel",   base + 0x14, 27, 3);
+	imx_clk_divider("periph2_clk2",     "periph2_clk2_sel",  base + 0x14, 0,  3);
+	imx_clk_divider("ipg",              "ahb",               base + 0x14, 8,  2);
+	imx_clk_divider("ipg_per",          "ipg",               base + 0x1c, 0,  6);
+	imx_clk_divider("esai_pred",        "esai_sel",          base + 0x28, 9,  3);
+	imx_clk_divider("esai_podf",        "esai_pred",         base + 0x28, 25, 3);
+	imx_clk_divider("asrc_pred",        "asrc_sel",          base + 0x30, 12, 3);
+	imx_clk_divider("asrc_podf",        "asrc_pred",         base + 0x30, 9,  3);
+	imx_clk_divider("spdif_pred",       "spdif_sel",         base + 0x30, 25, 3);
+	imx_clk_divider("spdif_podf",       "spdif_pred",        base + 0x30, 22, 3);
+	imx_clk_divider("can_root",         "pll3_usb_otg",      base + 0x20, 2,  6);
+	imx_clk_divider("ecspi_root",       "pll3_60m",          base + 0x38, 19, 6);
+	imx_clk_divider("gpu2d_core_podf",  "gpu2d_core_sel",    base + 0x18, 23, 3);
+	imx_clk_divider("gpu3d_core_podf",  "gpu3d_core_sel",    base + 0x18, 26, 3);
+	imx_clk_divider("gpu3d_shader",     "gpu3d_shader_sel",  base + 0x18, 29, 3);
+	imx_clk_divider("ipu1_podf",        "ipu1_sel",          base + 0x3c, 11, 3);
+	imx_clk_divider("ipu2_podf",        "ipu2_sel",          base + 0x3c, 16, 3);
+	imx_clk_divider("ldb_di0_podf",     "ldb_di0_sel",       base + 0x20, 10, 1);
+	imx_clk_divider("ldb_di1_podf",     "ldb_di1_sel",       base + 0x20, 11, 1);
+	imx_clk_divider("ipu1_di0_pre",     "ipu1_di0_pre_sel",  base + 0x34, 3,  3);
+	imx_clk_divider("ipu1_di1_pre",     "ipu1_di1_pre_sel",  base + 0x34, 12, 3);
+	imx_clk_divider("ipu2_di0_pre",     "ipu2_di0_pre_sel",  base + 0x38, 3,  3);
+	imx_clk_divider("ipu2_di1_pre",     "ipu2_di1_pre_sel",  base + 0x38, 12, 3);
+	imx_clk_divider("hsi_tx_podf",      "hsi_tx_sel",        base + 0x30, 29, 3);
+	imx_clk_divider("ssi1_pred",        "ssi1_sel",          base + 0x28, 6,  3);
+	imx_clk_divider("ssi1_podf",        "ssi1_pred",         base + 0x28, 0,  6);
+	imx_clk_divider("ssi2_pred",        "ssi2_sel",          base + 0x2c, 6,  3);
+	imx_clk_divider("ssi2_podf",        "ssi2_pred",         base + 0x2c, 0,  6);
+	imx_clk_divider("ssi3_pred",        "ssi3_sel",          base + 0x28, 22, 3);
+	imx_clk_divider("ssi3_podf",        "ssi3_pred",         base + 0x28, 16, 6);
+	imx_clk_divider("uart_serial_podf", "pll3_80m",          base + 0x24, 0,  6);
+	imx_clk_divider("usdhc1_podf",      "usdhc1_sel",        base + 0x24, 11, 3);
+	imx_clk_divider("usdhc2_podf",      "usdhc2_sel",        base + 0x24, 16, 3);
+	imx_clk_divider("usdhc3_podf",      "usdhc3_sel",        base + 0x24, 19, 3);
+	imx_clk_divider("usdhc4_podf",      "usdhc4_sel",        base + 0x24, 22, 3);
+	imx_clk_divider("enfc_pred",        "enfc_sel",          base + 0x2c, 18, 3);
+	imx_clk_divider("enfc_podf",        "enfc_pred",         base + 0x2c, 21, 6);
+	imx_clk_divider("emi_podf",         "emi_sel",           base + 0x1c, 20, 3);
+	imx_clk_divider("emi_slow_podf",    "emi_slow_sel",      base + 0x1c, 23, 3);
+	imx_clk_divider("vpu_axi_podf",     "vpu_axi_sel",       base + 0x24, 25, 3);
+	imx_clk_divider("cko1_podf",        "cko1_sel",          base + 0x60, 4,  3);
+
+	/*                   name                 parent_name    reg        shift width busy: reg, shift */
+	imx_clk_busy_divider("axi",               "axi_sel",     base + 0x14, 16,  3,   base + 0x48, 0);
+	imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph",      base + 0x14, 19,  3,   base + 0x48, 4);
+	imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2",     base + 0x14, 3,   3,   base + 0x48, 2);
+	imx_clk_busy_divider("arm",               "pll1_sw",     base + 0x10, 0,   3,   base + 0x48, 16);
+	imx_clk_busy_divider("ahb",               "periph",      base + 0x14, 10,  3,   base + 0x48, 1);
+
+	/*            name             parent_name          reg         shift */
+	imx_clk_gate2("apbh_dma",      "ahb",               base + 0x68, 4);
+	imx_clk_gate2("asrc",          "asrc_podf",         base + 0x68, 6);
+	imx_clk_gate2("can1_ipg",      "ipg",               base + 0x68, 14);
+	imx_clk_gate2("can1_serial",   "can_root",          base + 0x68, 16);
+	imx_clk_gate2("can2_ipg",      "ipg",               base + 0x68, 18);
+	imx_clk_gate2("can2_serial",   "can_root",          base + 0x68, 20);
+	imx_clk_gate2("ecspi1",        "ecspi_root",        base + 0x6c, 0);
+	imx_clk_gate2("ecspi2",        "ecspi_root",        base + 0x6c, 2);
+	imx_clk_gate2("ecspi3",        "ecspi_root",        base + 0x6c, 4);
+	imx_clk_gate2("ecspi4",        "ecspi_root",        base + 0x6c, 6);
+	imx_clk_gate2("ecspi5",        "ecspi_root",        base + 0x6c, 8);
+	imx_clk_gate2("enet",          "ipg",               base + 0x6c, 10);
+	imx_clk_gate2("esai",          "esai_podf",         base + 0x6c, 16);
+	imx_clk_gate2("gpt_ipg",       "ipg",               base + 0x6c, 20);
+	imx_clk_gate2("gpt_ipg_per",   "ipg_per",           base + 0x6c, 22);
+	imx_clk_gate2("gpu2d_core",    "gpu2d_core_podf",   base + 0x6c, 24);
+	imx_clk_gate2("gpu3d_core",    "gpu3d_core_podf",   base + 0x6c, 26);
+	imx_clk_gate2("hdmi_iahb",     "ahb",               base + 0x70, 0);
+	imx_clk_gate2("hdmi_isfr",     "pll3_pfd1_540m",    base + 0x70, 4);
+	imx_clk_gate2("i2c1",          "ipg_per",           base + 0x70, 6);
+	imx_clk_gate2("i2c2",          "ipg_per",           base + 0x70, 8);
+	imx_clk_gate2("i2c3",          "ipg_per",           base + 0x70, 10);
+	imx_clk_gate2("iim",           "ipg",               base + 0x70, 12);
+	imx_clk_gate2("enfc",          "enfc_podf",         base + 0x70, 14);
+	imx_clk_gate2("ipu1",          "ipu1_podf",         base + 0x74, 0);
+	imx_clk_gate2("ipu1_di0",      "ipu1_di0_sel",      base + 0x74, 2);
+	imx_clk_gate2("ipu1_di1",      "ipu1_di1_sel",      base + 0x74, 4);
+	imx_clk_gate2("ipu2",          "ipu2_podf",         base + 0x74, 6);
+	imx_clk_gate2("ipu2_di0",      "ipu2_di0_sel",      base + 0x74, 8);
+	imx_clk_gate2("ldb_di0",       "ldb_di0_podf",      base + 0x74, 12);
+	imx_clk_gate2("ldb_di1",       "ldb_di1_podf",      base + 0x74, 14);
+	imx_clk_gate2("ipu2_di1",      "ipu2_di1_sel",      base + 0x74, 10);
+	imx_clk_gate2("hsi_tx",        "hsi_tx_podf",       base + 0x74, 16);
+	imx_clk_gate2("mlb",           "pll6_mlb",          base + 0x74, 18);
+	imx_clk_gate2("mmdc_ch0_axi",  "mmdc_ch0_axi_podf", base + 0x74, 20);
+	imx_clk_gate2("mmdc_ch1_axi",  "mmdc_ch1_axi_podf", base + 0x74, 22);
+	imx_clk_gate2("ocram",         "ahb",               base + 0x74, 28);
+	imx_clk_gate2("openvg_axi",    "axi",               base + 0x74, 30);
+	imx_clk_gate2("pcie_axi",      "pcie_axi_sel",      base + 0x78, 0);
+	imx_clk_gate2("pwm1",          "ipg_per",           base + 0x78, 16);
+	imx_clk_gate2("pwm2",          "ipg_per",           base + 0x78, 18);
+	imx_clk_gate2("pwm3",          "ipg_per",           base + 0x78, 20);
+	imx_clk_gate2("pwm4",          "ipg_per",           base + 0x78, 22);
+	imx_clk_gate2("gpmi_bch_apb",  "usdhc3",            base + 0x78, 24);
+	imx_clk_gate2("gpmi_bch",      "usdhc4",            base + 0x78, 26);
+	imx_clk_gate2("gpmi_io",       "enfc",              base + 0x78, 28);
+	imx_clk_gate2("gpmi_apb",      "usdhc3",            base + 0x78, 30);
+	imx_clk_gate2("sata",          "ipg",               base + 0x7c, 4);
+	imx_clk_gate2("sdma",          "ahb",               base + 0x7c, 6);
+	imx_clk_gate2("spba",          "ipg",               base + 0x7c, 12);
+	imx_clk_gate2("ssi1",          "ssi1_podf",         base + 0x7c, 18);
+	imx_clk_gate2("ssi2",          "ssi2_podf",         base + 0x7c, 20);
+	imx_clk_gate2("ssi3",          "ssi3_podf",         base + 0x7c, 22);
+	imx_clk_gate2("uart_ipg",      "ipg",               base + 0x7c, 24);
+	imx_clk_gate2("uart_serial",   "uart_serial_podf",  base + 0x7c, 26);
+	imx_clk_gate2("usboh3",        "ipg",               base + 0x80, 0);
+	imx_clk_gate2("usdhc1",        "usdhc1_podf",       base + 0x80, 2);
+	imx_clk_gate2("usdhc2",        "usdhc2_podf",       base + 0x80, 4);
+	imx_clk_gate2("usdhc3",        "usdhc3_podf",       base + 0x80, 6);
+	imx_clk_gate2("usdhc4",        "usdhc4_podf",       base + 0x80, 8);
+	imx_clk_gate2("vdo_axi",       "vdo_axi_sel",       base + 0x80, 12);
+	imx_clk_gate2("vpu_axi",       "vpu_axi_podf",      base + 0x80, 14);
+	imx_clk_gate("cko1",           "cko1_podf",         base + 0x60, 7);
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) {
+		clk = clk_get_sys(clks_init_on[i], NULL);
+		if (IS_ERR(clk)) {
+			pr_err("%s: failed to get clk %s", __func__,
+			       clks_init_on[i]);
+			return PTR_ERR(clk);
+		}
+		clk_prepare_enable(clk);
+	}
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
+	base = of_iomap(np, 0);
+	WARN_ON(!base);
+	irq = irq_of_parse_and_map(np, 0);
+	mxc_timer_init(NULL, base, irq);
+
+	return 0;
+}
-- 
1.7.9.5

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

* [PATCH 35/40] ARM i.MX: remove now unused old clock support
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (33 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 34/40] ARM: imx6: " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 36/40] ARM i.MX pllv1: move mxc_decode_pll to its only user Sascha Hauer
                   ` (4 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/clock-imx1.c      |  636 -----------
 arch/arm/mach-imx/clock-imx21.c     | 1239 --------------------
 arch/arm/mach-imx/clock-imx25.c     |  346 ------
 arch/arm/mach-imx/clock-imx27.c     |  785 -------------
 arch/arm/mach-imx/clock-imx31.c     |  630 -----------
 arch/arm/mach-imx/clock-imx35.c     |  536 ---------
 arch/arm/mach-imx/clock-imx6q.c     | 2111 -----------------------------------
 arch/arm/mach-imx/clock-mx51-mx53.c | 1675 ---------------------------
 8 files changed, 7958 deletions(-)
 delete mode 100644 arch/arm/mach-imx/clock-imx1.c
 delete mode 100644 arch/arm/mach-imx/clock-imx21.c
 delete mode 100644 arch/arm/mach-imx/clock-imx25.c
 delete mode 100644 arch/arm/mach-imx/clock-imx27.c
 delete mode 100644 arch/arm/mach-imx/clock-imx31.c
 delete mode 100644 arch/arm/mach-imx/clock-imx35.c
 delete mode 100644 arch/arm/mach-imx/clock-imx6q.c
 delete mode 100644 arch/arm/mach-imx/clock-mx51-mx53.c

diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c
deleted file mode 100644
index 4aabeb2..0000000
diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c
deleted file mode 100644
index ee15d8c..0000000
diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c
deleted file mode 100644
index b0fec74c..0000000
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
deleted file mode 100644
index 98e04f5..0000000
diff --git a/arch/arm/mach-imx/clock-imx31.c b/arch/arm/mach-imx/clock-imx31.c
deleted file mode 100644
index 3a943cd..0000000
diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c
deleted file mode 100644
index e56c1a8..0000000
diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
deleted file mode 100644
index 111c328..0000000
diff --git a/arch/arm/mach-imx/clock-mx51-mx53.c b/arch/arm/mach-imx/clock-mx51-mx53.c
deleted file mode 100644
index 0847050..0000000
-- 
1.7.9.5

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

* [PATCH 36/40] ARM i.MX pllv1: move mxc_decode_pll to its only user
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (34 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 35/40] ARM i.MX: remove now unused old clock support Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 37/40] ARM i.MX: remove unused legacy clock support Sascha Hauer
                   ` (3 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/clk-pllv1.c          |   47 +++++++++++++++++++++++++++++++-
 arch/arm/plat-mxc/clock.c              |   45 ------------------------------
 arch/arm/plat-mxc/include/mach/clock.h |    2 --
 3 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c
index afbd95f..7b29f67 100644
--- a/arch/arm/mach-imx/clk-pllv1.c
+++ b/arch/arm/mach-imx/clk-pllv1.c
@@ -25,12 +25,57 @@ struct clk_pllv1 {
 
 #define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk))
 
+/*
+ * Get the resulting clock rate from a PLL register value and the input
+ * frequency. PLLs with this register layout can at least be found on
+ * MX1, MX21, MX27 and MX31
+ *
+ *                  mfi + mfn / (mfd + 1)
+ *  f = 2 * f_ref * --------------------
+ *                        pd + 1
+ */
+static unsigned long clk_pllv1_decode(unsigned int reg_val, u32 freq)
+{
+	long long ll;
+	int mfn_abs;
+	unsigned int mfi, mfn, mfd, pd;
+
+	mfi = (reg_val >> 10) & 0xf;
+	mfn = reg_val & 0x3ff;
+	mfd = (reg_val >> 16) & 0x3ff;
+	pd =  (reg_val >> 26) & 0xf;
+
+	mfi = mfi <= 5 ? 5 : mfi;
+
+	mfn_abs = mfn;
+
+	/* On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit
+	 * 2's complements number
+	 */
+	if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
+		mfn_abs = 0x400 - mfn;
+
+	freq *= 2;
+	freq /= pd + 1;
+
+	ll = (unsigned long long)freq * mfn_abs;
+
+	do_div(ll, mfd + 1);
+
+	if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
+		ll = -ll;
+
+	ll = (freq * mfi) + ll;
+
+	return ll;
+}
+
 static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
 	struct clk_pllv1 *pll = to_clk_pllv1(hw);
 
-	return mxc_decode_pll(readl(pll->base), parent_rate);
+	return clk_pllv1_decode(readl(pll->base), parent_rate);
 }
 
 struct clk_ops clk_pllv1_ops = {
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 5079787..0ed0954 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -210,48 +210,3 @@ EXPORT_SYMBOL(clk_get_parent);
 DEFINE_SPINLOCK(imx_ccm_lock);
 
 #endif /* CONFIG_COMMON_CLK */
-
-/*
- * Get the resulting clock rate from a PLL register value and the input
- * frequency. PLLs with this register layout can at least be found on
- * MX1, MX21, MX27 and MX31
- *
- *                  mfi + mfn / (mfd + 1)
- *  f = 2 * f_ref * --------------------
- *                        pd + 1
- */
-unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq)
-{
-	long long ll;
-	int mfn_abs;
-	unsigned int mfi, mfn, mfd, pd;
-
-	mfi = (reg_val >> 10) & 0xf;
-	mfn = reg_val & 0x3ff;
-	mfd = (reg_val >> 16) & 0x3ff;
-	pd =  (reg_val >> 26) & 0xf;
-
-	mfi = mfi <= 5 ? 5 : mfi;
-
-	mfn_abs = mfn;
-
-	/* On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit
-	 * 2's complements number
-	 */
-	if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
-		mfn_abs = 0x400 - mfn;
-
-	freq *= 2;
-	freq /= pd + 1;
-
-	ll = (unsigned long long)freq * mfn_abs;
-
-	do_div(ll, mfd + 1);
-
-	if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
-		ll = -ll;
-
-	ll = (freq * mfi) + ll;
-
-	return ll;
-}
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
index bd940c7..0c4ad77 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -64,7 +64,5 @@ void clk_unregister(struct clk *clk);
 
 extern spinlock_t imx_ccm_lock;
 
-unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_ARCH_MXC_CLOCK_H__ */
-- 
1.7.9.5

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

* [PATCH 37/40] ARM i.MX: remove unused legacy clock support
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (35 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 36/40] ARM i.MX pllv1: move mxc_decode_pll to its only user Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 38/40] USB gadget i.MX: fix clock handling Sascha Hauer
                   ` (2 subsequent siblings)
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/plat-mxc/clock.c              |  188 +-------------------------------
 arch/arm/plat-mxc/include/mach/clock.h |   43 --------
 2 files changed, 1 insertion(+), 230 deletions(-)

diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 0ed0954..2b73f3f 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -1,9 +1,4 @@
 /*
- * Based on arch/arm/plat-omap/clock.c
- *
- * Copyright (C) 2004 - 2005 Nokia corporation
- * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
- * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
  * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
  *
@@ -21,192 +16,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
  */
-
-/* #define DEBUG */
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/proc_fs.h>
-#include <linux/semaphore.h>
-#include <linux/string.h>
-
+#include <linux/spinlock.h>
 #include <mach/clock.h>
-#include <mach/hardware.h>
-
-#ifndef CONFIG_COMMON_CLK
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-
-/*-------------------------------------------------------------------------
- * Standard clock functions defined in include/linux/clk.h
- *-------------------------------------------------------------------------*/
-
-static void __clk_disable(struct clk *clk)
-{
-	if (clk == NULL || IS_ERR(clk))
-		return;
-	WARN_ON(!clk->usecount);
-
-	if (!(--clk->usecount)) {
-		if (clk->disable)
-			clk->disable(clk);
-		__clk_disable(clk->parent);
-		__clk_disable(clk->secondary);
-	}
-}
-
-static int __clk_enable(struct clk *clk)
-{
-	if (clk == NULL || IS_ERR(clk))
-		return -EINVAL;
-
-	if (clk->usecount++ == 0) {
-		__clk_enable(clk->parent);
-		__clk_enable(clk->secondary);
-
-		if (clk->enable)
-			clk->enable(clk);
-	}
-	return 0;
-}
-
-/* This function increments the reference count on the clock and enables the
- * clock if not already enabled. The parent clock tree is recursively enabled
- */
-int clk_enable(struct clk *clk)
-{
-	int ret = 0;
-
-	if (clk == NULL || IS_ERR(clk))
-		return -EINVAL;
-
-	mutex_lock(&clocks_mutex);
-	ret = __clk_enable(clk);
-	mutex_unlock(&clocks_mutex);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_enable);
-
-/* This function decrements the reference count on the clock and disables
- * the clock when reference count is 0. The parent clock tree is
- * recursively disabled
- */
-void clk_disable(struct clk *clk)
-{
-	if (clk == NULL || IS_ERR(clk))
-		return;
-
-	mutex_lock(&clocks_mutex);
-	__clk_disable(clk);
-	mutex_unlock(&clocks_mutex);
-}
-EXPORT_SYMBOL(clk_disable);
-
-/* Retrieve the *current* clock rate. If the clock itself
- * does not provide a special calculation routine, ask
- * its parent and so on, until one is able to return
- * a valid clock rate
- */
-unsigned long clk_get_rate(struct clk *clk)
-{
-	if (clk == NULL || IS_ERR(clk))
-		return 0UL;
-
-	if (clk->get_rate)
-		return clk->get_rate(clk);
-
-	return clk_get_rate(clk->parent);
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-/* Round the requested clock rate to the nearest supported
- * rate that is less than or equal to the requested rate.
- * This is dependent on the clock's current parent.
- */
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
-		return 0;
-
-	return clk->round_rate(clk, rate);
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-/* Set the clock to the requested clock rate. The rate must
- * match a supported rate exactly based on what clk_round_rate returns
- */
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret = -EINVAL;
-
-	if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
-		return ret;
-
-	mutex_lock(&clocks_mutex);
-	ret = clk->set_rate(clk, rate);
-	mutex_unlock(&clocks_mutex);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-/* Set the clock's parent to another clock source */
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	int ret = -EINVAL;
-	struct clk *old;
-
-	if (clk == NULL || IS_ERR(clk) || parent == NULL ||
-	    IS_ERR(parent) || clk->set_parent == NULL)
-		return ret;
-
-	if (clk->usecount)
-		clk_enable(parent);
-
-	mutex_lock(&clocks_mutex);
-	ret = clk->set_parent(clk, parent);
-	if (ret == 0) {
-		old = clk->parent;
-		clk->parent = parent;
-	} else {
-		old = parent;
-	}
-	mutex_unlock(&clocks_mutex);
-
-	if (clk->usecount)
-		clk_disable(old);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-/* Retrieve the clock's parent clock source */
-struct clk *clk_get_parent(struct clk *clk)
-{
-	struct clk *ret = NULL;
-
-	if (clk == NULL || IS_ERR(clk))
-		return ret;
-
-	return clk->parent;
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-#else
 
 /*
  * Lock to protect the clock module (ccm) registers. Used
  * on all i.MXs
  */
 DEFINE_SPINLOCK(imx_ccm_lock);
-
-#endif /* CONFIG_COMMON_CLK */
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
index 0c4ad77..76b990c 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -20,49 +20,6 @@
 #ifndef __ASM_ARCH_MXC_CLOCK_H__
 #define __ASM_ARCH_MXC_CLOCK_H__
 
-#ifndef __ASSEMBLY__
-#include <linux/list.h>
-
-#ifndef CONFIG_COMMON_CLK
-struct module;
-
-struct clk {
-	int id;
-	/* Source clock this clk depends on */
-	struct clk *parent;
-	/* Secondary clock to enable/disable with this clock */
-	struct clk *secondary;
-	/* Reference count of clock enable/disable */
-	__s8 usecount;
-	/* Register bit position for clock's enable/disable control. */
-	u8 enable_shift;
-	/* Register address for clock's enable/disable control. */
-	void __iomem *enable_reg;
-	u32 flags;
-	/* get the current clock rate (always a fresh value) */
-	unsigned long (*get_rate) (struct clk *);
-	/* Function ptr to set the clock to a new rate. The rate must match a
-	   supported rate returned from round_rate. Leave blank if clock is not
-	   programmable */
-	int (*set_rate) (struct clk *, unsigned long);
-	/* Function ptr to round the requested clock rate to the nearest
-	   supported rate that is less than or equal to the requested rate. */
-	unsigned long (*round_rate) (struct clk *, unsigned long);
-	/* Function ptr to enable the clock. Leave blank if clock can not
-	   be gated. */
-	int (*enable) (struct clk *);
-	/* Function ptr to disable the clock. Leave blank if clock can not
-	   be gated. */
-	void (*disable) (struct clk *);
-	/* Function ptr to set the parent clock of the clock. */
-	int (*set_parent) (struct clk *, struct clk *);
-};
-
-int clk_register(struct clk *clk);
-void clk_unregister(struct clk *clk);
-#endif /* CONFIG_COMMON_CLK */
-
 extern spinlock_t imx_ccm_lock;
 
-#endif /* __ASSEMBLY__ */
 #endif /* __ASM_ARCH_MXC_CLOCK_H__ */
-- 
1.7.9.5

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

* [PATCH 38/40] USB gadget i.MX: fix clock handling
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (36 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 37/40] ARM i.MX: remove unused legacy clock support Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 39/40] USB ehci i.MX: Fix " Sascha Hauer
  2012-04-10 13:45 ` [PATCH 40/40] ARM i.MX: Remove now unused struct clk argument from mxc_timer_init Sascha Hauer
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

The usbotg core generally has three different clocks:

ipg: Bus register accesses
ahb: DMA clock
per: Clock for generating the 60MHz for the phy

The old i.MX clock support messed this up completely, there
were different clocks for different SoCs, but there meaning
varied from SoC to SoC. This patch cleans up the breakage
introduced by the generic clock support. While at it, also
use the managed version of clk_get to make the error path
easier.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/gadget/fsl_mxc_udc.c |   74 ++++++++++++--------------------------
 1 file changed, 23 insertions(+), 51 deletions(-)

diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c
index dcbc0a2..cfaa40a 100644
--- a/drivers/usb/gadget/fsl_mxc_udc.c
+++ b/drivers/usb/gadget/fsl_mxc_udc.c
@@ -21,7 +21,8 @@
 #include <mach/hardware.h>
 
 static struct clk *mxc_ahb_clk;
-static struct clk *mxc_usb_clk;
+static struct clk *mxc_ipg_clk;
+static struct clk *mxc_per_clk;
 
 /* workaround ENGcm09152 for i.MX35 */
 #define USBPHYCTRL_OTGBASE_OFFSET	0x608
@@ -35,55 +36,31 @@ int fsl_udc_clk_init(struct platform_device *pdev)
 
 	pdata = pdev->dev.platform_data;
 
-	if (!cpu_is_mx35() && !cpu_is_mx25()) {
-		mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb");
-		if (IS_ERR(mxc_ahb_clk))
-			return PTR_ERR(mxc_ahb_clk);
+	mxc_ahb_clk = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(mxc_ahb_clk))
+		return PTR_ERR(mxc_ahb_clk);
 
-		ret = clk_enable(mxc_ahb_clk);
-		if (ret < 0) {
-			dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n");
-			goto eenahb;
-		}
-	}
+	mxc_per_clk = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(mxc_per_clk))
+		return PTR_ERR(mxc_per_clk);
 
-	/* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */
-	mxc_usb_clk = clk_get(&pdev->dev, "usb");
-	if (IS_ERR(mxc_usb_clk)) {
-		dev_err(&pdev->dev, "clk_get(\"usb\") failed\n");
-		ret = PTR_ERR(mxc_usb_clk);
-		goto egusb;
-	}
+	mxc_ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(mxc_ipg_clk))
+		return PTR_ERR(mxc_ipg_clk);
 
-	if (!cpu_is_mx51()) {
-		freq = clk_get_rate(mxc_usb_clk);
-		if (pdata->phy_mode != FSL_USB2_PHY_ULPI &&
-		    (freq < 59999000 || freq > 60001000)) {
-			dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq);
-			ret = -EINVAL;
-			goto eclkrate;
-		}
+	/* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */
+	freq = clk_get_rate(mxc_usb_clk);
+	if (pdata->phy_mode != FSL_USB2_PHY_ULPI &&
+	    (freq < 59999000 || freq > 60001000)) {
+		dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq);
+		return -EINVAL;
 	}
 
-	ret = clk_enable(mxc_usb_clk);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "clk_enable(\"usb_clk\") failed\n");
-		goto eenusb;
-	}
+	clk_prepare_enable(mxc_ahb_clk);
+	clk_prepare_enable(mxc_per_clk);
+	clk_prepare_enable(mxc_ipg_clk);
 
 	return 0;
-
-eenusb:
-eclkrate:
-	clk_put(mxc_usb_clk);
-	mxc_usb_clk = NULL;
-egusb:
-	if (!cpu_is_mx35())
-		clk_disable(mxc_ahb_clk);
-eenahb:
-	if (!cpu_is_mx35())
-		clk_put(mxc_ahb_clk);
-	return ret;
 }
 
 void fsl_udc_clk_finalize(struct platform_device *pdev)
@@ -112,12 +89,7 @@ void fsl_udc_clk_finalize(struct platform_device *pdev)
 
 void fsl_udc_clk_release(void)
 {
-	if (mxc_usb_clk) {
-		clk_disable(mxc_usb_clk);
-		clk_put(mxc_usb_clk);
-	}
-	if (!cpu_is_mx35()) {
-		clk_disable(mxc_ahb_clk);
-		clk_put(mxc_ahb_clk);
-	}
+	clk_disable_unprepare(mxc_ahb_clk);
+	clk_disable_unprepare(mxc_ipg_clk);
+	clk_disable_unprepare(mxc_per_clk);
 }
-- 
1.7.9.5

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

* [PATCH 39/40] USB ehci i.MX: Fix clock handling
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (37 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 38/40] USB gadget i.MX: fix clock handling Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  2012-04-10 13:45 ` [PATCH 40/40] ARM i.MX: Remove now unused struct clk argument from mxc_timer_init Sascha Hauer
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

The usbotg core generally has three different clocks:

ipg: Bus register accesses
ahb: DMA clock
per: Clock for generating the 60MHz for the phy

The old i.MX clock support messed this up completely, there
were different clocks for different SoCs, but there meaning
varied from SoC to SoC. This patch cleans up the breakage
introduced by the generic clock support. While at it, also
use the managed version of clk_get to make the error path
easier.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/host/ehci-mxc.c |   52 ++++++++++++++++++++++---------------------
 1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index ae16c34..a2fb7c5 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -32,7 +32,10 @@
 #define ULPI_VIEWPORT_OFFSET	0x170
 
 struct ehci_mxc_priv {
-	struct clk *usbclk, *ahbclk, *phy1clk;
+	struct clk *clk_ipg;
+	struct clk *clk_ahb;
+	struct clk *clk_per;
+	struct clk *phy1clk;
 	struct usb_hcd *hcd;
 };
 
@@ -166,22 +169,28 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
 	}
 
 	/* enable clocks */
-	priv->usbclk = clk_get(dev, "usb");
-	if (IS_ERR(priv->usbclk)) {
-		ret = PTR_ERR(priv->usbclk);
+	priv->clk_ipg = devm_clk_get(dev, "ipg");
+	if (IS_ERR(priv->clk_ipg)) {
+		ret = PTR_ERR(priv->clk_ipg);
 		goto err_clk;
 	}
-	clk_prepare_enable(priv->usbclk);
 
-	if (!cpu_is_mx35() && !cpu_is_mx25()) {
-		priv->ahbclk = clk_get(dev, "usb_ahb");
-		if (IS_ERR(priv->ahbclk)) {
-			ret = PTR_ERR(priv->ahbclk);
-			goto err_clk_ahb;
-		}
-		clk_prepare_enable(priv->ahbclk);
+	priv->clk_ahb = devm_clk_get(dev, "ahb");
+	if (IS_ERR(priv->clk_ahb)) {
+		ret = PTR_ERR(priv->clk_ahb);
+		goto err_clk;
+	}
+
+	priv->clk_per = devm_clk_get(dev, "per");
+	if (IS_ERR(priv->clk_per)) {
+		ret = PTR_ERR(priv->clk_per);
+		goto err_clk;
 	}
 
+	clk_prepare_enable(priv->clk_per);
+	clk_prepare_enable(priv->clk_ahb);
+	clk_prepare_enable(priv->clk_ipg);
+
 	/* "dr" device has its own clock on i.MX51 */
 	if (cpu_is_mx51() && (pdev->id == 0)) {
 		priv->phy1clk = clk_get(dev, "usb_phy1");
@@ -270,13 +279,9 @@ err_init:
 		clk_put(priv->phy1clk);
 	}
 err_clk_phy:
-	if (priv->ahbclk) {
-		clk_disable_unprepare(priv->ahbclk);
-		clk_put(priv->ahbclk);
-	}
-err_clk_ahb:
-	clk_disable_unprepare(priv->usbclk);
-	clk_put(priv->usbclk);
+	clk_disable_unprepare(priv->clk_ahb);
+	clk_disable_unprepare(priv->clk_ipg);
+	clk_disable_unprepare(priv->clk_per);
 err_clk:
 	iounmap(hcd->regs);
 err_ioremap:
@@ -307,12 +312,9 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
 	usb_put_hcd(hcd);
 	platform_set_drvdata(pdev, NULL);
 
-	clk_disable_unprepare(priv->usbclk);
-	clk_put(priv->usbclk);
-	if (priv->ahbclk) {
-		clk_disable_unprepare(priv->ahbclk);
-		clk_put(priv->ahbclk);
-	}
+	clk_disable_unprepare(priv->clk_ahb);
+	clk_disable_unprepare(priv->clk_ipg);
+	clk_disable_unprepare(priv->clk_per);
 	if (priv->phy1clk) {
 		clk_disable_unprepare(priv->phy1clk);
 		clk_put(priv->phy1clk);
-- 
1.7.9.5

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

* [PATCH 40/40] ARM i.MX: Remove now unused struct clk argument from mxc_timer_init
  2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
                   ` (38 preceding siblings ...)
  2012-04-10 13:45 ` [PATCH 39/40] USB ehci i.MX: Fix " Sascha Hauer
@ 2012-04-10 13:45 ` Sascha Hauer
  39 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/clk-imx1.c            |    3 +--
 arch/arm/mach-imx/clk-imx21.c           |    4 ++--
 arch/arm/mach-imx/clk-imx25.c           |    2 +-
 arch/arm/mach-imx/clk-imx27.c           |    3 +--
 arch/arm/mach-imx/clk-imx31.c           |    3 +--
 arch/arm/mach-imx/clk-imx35.c           |    3 +--
 arch/arm/mach-imx/clk-imx51-imx53.c     |    6 ++----
 arch/arm/mach-imx/clk-imx6q.c           |    2 +-
 arch/arm/plat-mxc/include/mach/common.h |    2 +-
 arch/arm/plat-mxc/time.c                |    4 ++--
 10 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c
index 60f1801..9d58776 100644
--- a/arch/arm/mach-imx/clk-imx1.c
+++ b/arch/arm/mach-imx/clk-imx1.c
@@ -102,8 +102,7 @@ int __init mx1_clocks_init(unsigned long fref)
 
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
-	mxc_timer_init(NULL, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
-			MX1_TIM1_INT);
+	mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c
index c4779a0..e4a0ede 100644
--- a/arch/arm/mach-imx/clk-imx21.c
+++ b/arch/arm/mach-imx/clk-imx21.c
@@ -167,7 +167,7 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href)
 
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
-	mxc_timer_init(NULL, MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
-			MX21_INT_GPT1);
+	mxc_timer_init(MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), MX21_INT_GPT1);
+
 	return 0;
 }
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
index 717b8a0..9cde523 100644
--- a/arch/arm/mach-imx/clk-imx25.c
+++ b/arch/arm/mach-imx/clk-imx25.c
@@ -227,6 +227,6 @@ int __init mx25_clocks_init(void)
 
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
-	mxc_timer_init(NULL, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+	mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
 	return 0;
 }
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
index 3a1e965..d81c3c6 100644
--- a/arch/arm/mach-imx/clk-imx27.c
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -246,8 +246,7 @@ int __init mx27_clocks_init(unsigned long fref)
 
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
-	mxc_timer_init(NULL, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
-			MX27_INT_GPT1);
+	mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1);
 
 	clk_prepare_enable(emi_ahb);
 
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c
index de3addb..b57a460 100644
--- a/arch/arm/mach-imx/clk-imx31.c
+++ b/arch/arm/mach-imx/clk-imx31.c
@@ -161,8 +161,7 @@ int __init mx31_clocks_init(unsigned long fref)
 	mx31_revision();
 	clk_disable_unprepare(iim);
 
-	mxc_timer_init(NULL, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR),
-			MX31_INT_GPT);
+	mxc_timer_init(MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), MX31_INT_GPT);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
index 7d26ae8..a77502a 100644
--- a/arch/arm/mach-imx/clk-imx35.c
+++ b/arch/arm/mach-imx/clk-imx35.c
@@ -251,8 +251,7 @@ int __init mx35_clocks_init()
 	epit_timer_init(&epit1_clk,
 			MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
 #else
-	mxc_timer_init(NULL, MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR),
-			MX35_INT_GPT);
+	mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
 #endif
 
 	return 0;
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index 5b5d7a0..4d8229e 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -309,8 +309,7 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
 	clk_set_rate(esdhc_b_podf, 166250000);
 
 	/* System timer */
-	mxc_timer_init(NULL, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
-		MX51_INT_GPT);
+	mxc_timer_init(MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), MX51_INT_GPT);
 
 	clk_prepare_enable(iim);
 	imx_print_silicon_rev("i.MX51", mx51_revision());
@@ -363,8 +362,7 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
 	clk_set_rate(esdhc_b_podf, 200000000);
 
 	/* System timer */
-	mxc_timer_init(NULL, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
-		MX53_INT_GPT);
+	mxc_timer_init(MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), MX53_INT_GPT);
 
 	clk_prepare_enable(iim);
 	imx_print_silicon_rev("i.MX53", mx53_revision());
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index f379fa6..cd48fa5 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -401,7 +401,7 @@ int __init mx6q_clocks_init(void)
 	base = of_iomap(np, 0);
 	WARN_ON(!base);
 	irq = irq_of_parse_and_map(np, 0);
-	mxc_timer_init(NULL, base, irq);
+	mxc_timer_init(base, irq);
 
 	return 0;
 }
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 0319c4a..5cae195 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -54,7 +54,7 @@ extern void imx50_soc_init(void);
 extern void imx51_soc_init(void);
 extern void imx53_soc_init(void);
 extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
-extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
+extern void mxc_timer_init(void __iomem *, int);
 extern int mx1_clocks_init(unsigned long fref);
 extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
 extern int mx25_clocks_init(void);
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 99f958c..f32a249 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -280,10 +280,10 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
 	return 0;
 }
 
-void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
+void __init mxc_timer_init(void __iomem *base, int irq)
 {
 	uint32_t tctl_val;
-	struct clk *timer_ipg_clk;
+	struct clk *timer_ipg_clk, *timer_clk;
 
 	if (!timer_clk) {
 		timer_clk = clk_get_sys("imx-gpt.0", "per");
-- 
1.7.9.5

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-10 13:45 ` [PATCH 01/40] clkdev: add clkname to struct clk_lookup Sascha Hauer
@ 2012-04-10 14:30   ` Russell King - ARM Linux
  2012-04-10 16:11     ` Sascha Hauer
  0 siblings, 1 reply; 101+ messages in thread
From: Russell King - ARM Linux @ 2012-04-10 14:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 10, 2012 at 03:45:14PM +0200, Sascha Hauer wrote:
> With the generic clock framework we do not necessarily have
> a pointer to the struct clk we want to register a lookup
> for, so add a const char *clkname field to struct clk_lookup
> so that a lookup can be registered with a clock name.

All this silly names all over the place is getting to be utterly
rediculous. Why do we need to name clocks and look them up by name
when we have a perfectly good way (clkdev) to do this already?  Yes,
it takes a struct clk pointer but that's exactly because that's what
it has to return.

Why do we want to have another idiotic string to look up a clock which
is named using an idiotic scheme to find out its pointer to only then
register that with clkdev?

I think this clk stuff has gone totally insane wrt names recently.

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-10 14:30   ` Russell King - ARM Linux
@ 2012-04-10 16:11     ` Sascha Hauer
  2012-04-11  1:11       ` Richard Zhao
  0 siblings, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-10 16:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 10, 2012 at 03:30:55PM +0100, Russell King - ARM Linux wrote:
> On Tue, Apr 10, 2012 at 03:45:14PM +0200, Sascha Hauer wrote:
> > With the generic clock framework we do not necessarily have
> > a pointer to the struct clk we want to register a lookup
> > for, so add a const char *clkname field to struct clk_lookup
> > so that a lookup can be registered with a clock name.
> 
> All this silly names all over the place is getting to be utterly
> rediculous. Why do we need to name clocks and look them up by name
> when we have a perfectly good way (clkdev) to do this already?  Yes,
> it takes a struct clk pointer but that's exactly because that's what
> it has to return.
> 
> Why do we want to have another idiotic string to look up a clock which
> is named using an idiotic scheme to find out its pointer to only then
> register that with clkdev?
> 
> I think this clk stuff has gone totally insane wrt names recently.

clk names and clk lookups are two different things. The former is a
unique identifier for a clock whereas the latter associates a clock
to a device. Multiple lookups can point to the same clock, so they can't
be used to identify a particular clock. I know I'm not telling anything
new to you here, so I think your question goes down to why we need a
unique identifier string for clocks.

For me the big advantage for clocks having unique names is that I do not
have to have a struct clk * to pass the (possible) parents of a clock to
the clock framework during registration. Also it makes us independent of
the registration order of the clock tree (no need to register the
parents before the children). The debugfs representation of the clock
tree also makes use of the names.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH 25/40] ARM: imx: add common clock support for clk busy
  2012-04-10 13:45 ` [PATCH 25/40] ARM: imx: add common clock support for clk busy Sascha Hauer
@ 2012-04-10 18:59   ` Stephen Boyd
  2012-04-11  6:53     ` Sascha Hauer
  2012-04-12  1:50   ` Richard Zhao
  2012-04-13  2:09   ` [PATCH] ARM: imx: remove clk_hw from clk_busy Shawn Guo
  2 siblings, 1 reply; 101+ messages in thread
From: Stephen Boyd @ 2012-04-10 18:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/10/12 06:45, Sascha Hauer wrote:
> +static int clk_busy_wait(void __iomem *reg, u8 shift)
> +{
> +	unsigned long timeout = jiffies + msecs_to_jiffies(10);
> +
> +	while (readl_relaxed(reg) & (1 << shift))
> +		if (time_after(jiffies, timeout))
> +			return -ETIMEDOUT;
> +
> +	return 0;
> +}

MSM also has a bit to poll to see if a clock is enabled or not, similar
to this rate switch complete bit. Would it make sense to have another
few clock ops like wait_for_enable(), wait_for_rate(),
wait_for_disable()? Then you should be able to copy the basic divider
ops and assign the wait ops and avoid the wrappers.

Also, why are these drivers in arch/arm? Shouldn't we be putting all
clock drivers into drivers/clk/ now?

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

* [PATCH 27/40] ARM i.MX25: implement clocks using common clock framework
  2012-04-10 13:45 ` [PATCH 27/40] ARM i.MX25: implement clocks using common clock framework Sascha Hauer
@ 2012-04-10 20:10   ` Roberto Nibali
  2012-04-10 20:45     ` Fabio Estevam
  0 siblings, 1 reply; 101+ messages in thread
From: Roberto Nibali @ 2012-04-10 20:10 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

Just a small comment below:

> +static struct clk_lookup lookups[] = {
> + ? ? ? /* i.mx25 has the i.mx21 type uart */
> + ? ? ? clkdev("imx21-uart.0", "ipg", "uart1_ipg")
> + ? ? ? clkdev("imx21-uart.0", "per", "uart_ipg_per")
> + ? ? ? clkdev("imx21-uart.1", "ipg", "uart2_ipg")
> + ? ? ? clkdev("imx21-uart.1", "per", "uart_ipg_per")
> + ? ? ? clkdev("imx21-uart.2", "ipg", "uart3_ipg")
> + ? ? ? clkdev("imx21-uart.2", "per", "uart_ipg_per")
> + ? ? ? clkdev("imx21-uart.3", "ipg", "uart4_ipg")
> + ? ? ? clkdev("imx21-uart.3", "per", "uart_ipg_per")
> + ? ? ? clkdev("imx21-uart.4", "ipg", "uart5_ipg")
> + ? ? ? clkdev("imx21-uart.4", "per", "uart_ipg_per")
> + ? ? ? clkdev("imx-gpt.0", "ipg", "ipg")
> + ? ? ? clkdev("imx-gpt.0", "per", "gpt_ipg_per")
> + ? ? ? clkdev("mxc-ehci.0", "ipg", "ipg")
> + ? ? ? clkdev("mxc-ehci.0", "ahb", "usbotg_ahb")
> + ? ? ? clkdev("mxc-ehci.0", "per", "usbdiv")
> + ? ? ? clkdev("mxc-ehci.1", "ipg", "ipg")
> + ? ? ? clkdev("mxc-ehci.1", "ahb", "usbotg_ahb")
> + ? ? ? clkdev("mxc-ehci.1", "per", "usbdiv")
> + ? ? ? clkdev("mxc-ehci.2", "ipg", "ipg")
> + ? ? ? clkdev("mxc-ehci.2", "ahb", "usbotg_ahb")
> + ? ? ? clkdev("mxc-ehci.2", "per", "usbdiv")
> + ? ? ? clkdev("fsl-usb2-udc", "ipg", "ipg")
> + ? ? ? clkdev("fsl-usb2-udc", "ahb", "usbotg_ahb")
> + ? ? ? clkdev("fsl-usb2-udc", "per", "usbdiv")
> + ? ? ? clkdev("mxc_nand.0", NULL, "nfc_ipg_per")
> + ? ? ? /* i.mx25 has the i.mx35 type cspi */
> + ? ? ? clkdev("imx35-cspi.0", NULL, "cspi1_ipg")
> + ? ? ? clkdev("imx35-cspi.1", NULL, "cspi2_ipg")
> + ? ? ? clkdev("imx35-cspi.2", NULL, "cspi3_ipg")
> + ? ? ? clkdev("mxc_pwm.0", "ipg", "pwm1_ipg")
> + ? ? ? clkdev("mxc_pwm.0", "per", "per10")
> + ? ? ? clkdev("mxc_pwm.1", "ipg", "pwm1_ipg")
> + ? ? ? clkdev("mxc_pwm.1", "per", "per10")
> + ? ? ? clkdev("mxc_pwm.2", "ipg", "pwm1_ipg")
> + ? ? ? clkdev("mxc_pwm.2", "per", "per10")
> + ? ? ? clkdev("mxc_pwm.3", "ipg", "pwm1_ipg")
> + ? ? ? clkdev("mxc_pwm.3", "per", "per10")
> + ? ? ? clkdev("imx-keypad", NULL, "kpp_ipg")
> + ? ? ? clkdev("mx25-adc", NULL, "tsc_ipg")

Wouldn't it be better to adjust this to mx25-adc.0, since it already
has a user: the new i.MX25 ADC TS driver by your colleague Juergen
Beiser, no?

> + ? ? ? clkdev("imx-i2c.0", NULL, "i2c_ipg_per")
> + ? ? ? clkdev("imx-i2c.1", NULL, "i2c_ipg_per")
> + ? ? ? clkdev("imx-i2c.2", NULL, "i2c_ipg_per")
> + ? ? ? clkdev("imx25-fec.0", "ipg", "fec_ipg")
> + ? ? ? clkdev("imx25-fec.0", "ahb", "fec_ahb")
> + ? ? ? clkdev("imxdi_rtc.0", NULL, "dryice_ipg")
> + ? ? ? clkdev("imx-fb.0", "per", "lcdc_ipg_per")
> + ? ? ? clkdev("imx-fb.0", "ipg", "lcdc_ipg")
> + ? ? ? clkdev("imx-fb.0", "ahb", "lcdc_ahb")
> + ? ? ? clkdev("imx2-wdt.0", NULL, "wdt_ipg")
> + ? ? ? clkdev("imx-ssi.0", "per", "ssi1_ipg_per")
> + ? ? ? clkdev("imx-ssi.0", "ipg", "ssi1_ipg")
> + ? ? ? clkdev("imx-ssi.1", "per", "ssi2_ipg_per")
> + ? ? ? clkdev("imx-ssi.1", "ipg", "ssi2_ipg")
> + ? ? ? clkdev("sdhci-esdhc-imx25.0", "per", "esdhc1_ipg_per")
> + ? ? ? clkdev("sdhci-esdhc-imx25.0", "ipg", "esdhc1_ipg")
> + ? ? ? clkdev("sdhci-esdhc-imx25.0", "ahb", "esdhc1_ahb")
> + ? ? ? clkdev("sdhci-esdhc-imx25.1", "per", "esdhc2_ipg_per")
> + ? ? ? clkdev("sdhci-esdhc-imx25.1", "ipg", "esdhc2_ipg")
> + ? ? ? clkdev("sdhci-esdhc-imx25.1", "ahb", "esdhc2_ahb")
> + ? ? ? clkdev("mx2-camera.0", "per", "csi_ipg_per")
> + ? ? ? clkdev("mx2-camera.0", "ipg", "csi_ipg")
> + ? ? ? clkdev("mx2-camera.0", "ahb", "csi_ahb")
> + ? ? ? clkdev(NULL, "audmux", "dummy")
> + ? ? ? clkdev("flexcan.0", NULL, "can1_ipg")
> + ? ? ? clkdev("flexcan.1", NULL, "can2_ipg")
> + ? ? ? /* i.mx25 has the i.mx35 type sdma */
> + ? ? ? clkdev("imx35-sdma", "ipg", "sdma_ipg")
> + ? ? ? clkdev("imx35-sdma", "ahb", "sdma_ahb")
> + ? ? ? clkdev(NULL, "iim", "iim_ipg")
> +};

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

* [PATCH 27/40] ARM i.MX25: implement clocks using common clock framework
  2012-04-10 20:10   ` Roberto Nibali
@ 2012-04-10 20:45     ` Fabio Estevam
  2012-04-11  7:01       ` Roberto Nibali
  0 siblings, 1 reply; 101+ messages in thread
From: Fabio Estevam @ 2012-04-10 20:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 10, 2012 at 5:10 PM, Roberto Nibali <rnibali@gmail.com> wrote:

> Wouldn't it be better to adjust this to mx25-adc.0, since it already
> has a user: the new i.MX25 ADC TS driver by your colleague Juergen
> Beiser, no?

Is this mx25 adc driver available somewhere?

Thanks,

Fabio Estevam

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-10 16:11     ` Sascha Hauer
@ 2012-04-11  1:11       ` Richard Zhao
  2012-04-11  8:24         ` Mark Brown
  0 siblings, 1 reply; 101+ messages in thread
From: Richard Zhao @ 2012-04-11  1:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 10, 2012 at 06:11:42PM +0200, Sascha Hauer wrote:
> On Tue, Apr 10, 2012 at 03:30:55PM +0100, Russell King - ARM Linux wrote:
> > On Tue, Apr 10, 2012 at 03:45:14PM +0200, Sascha Hauer wrote:
> > > With the generic clock framework we do not necessarily have
> > > a pointer to the struct clk we want to register a lookup
> > > for, so add a const char *clkname field to struct clk_lookup
> > > so that a lookup can be registered with a clock name.
> > 
> > All this silly names all over the place is getting to be utterly
> > rediculous. Why do we need to name clocks and look them up by name
> > when we have a perfectly good way (clkdev) to do this already?  Yes,
> > it takes a struct clk pointer but that's exactly because that's what
> > it has to return.
> > 
> > Why do we want to have another idiotic string to look up a clock which
> > is named using an idiotic scheme to find out its pointer to only then
> > register that with clkdev?
> > 
> > I think this clk stuff has gone totally insane wrt names recently.
> 
> clk names and clk lookups are two different things. The former is a
> unique identifier for a clock whereas the latter associates a clock
> to a device. Multiple lookups can point to the same clock, so they can't
> be used to identify a particular clock. I know I'm not telling anything
> new to you here, so I think your question goes down to why we need a
> unique identifier string for clocks.
> 
> For me the big advantage for clocks having unique names is that I do not
> have to have a struct clk * to pass the (possible) parents of a clock to
> the clock framework during registration. Also it makes us independent of
> the registration order of the clock tree (no need to register the
> parents before the children). The debugfs representation of the clock
> tree also makes use of the names.
I don't like string loopup either. And after DT binding, we can use
phandler to refer clk.

BRs
Richard

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

* [PATCH 25/40] ARM: imx: add common clock support for clk busy
  2012-04-10 18:59   ` Stephen Boyd
@ 2012-04-11  6:53     ` Sascha Hauer
  2012-04-11 22:21       ` Stephen Boyd
  0 siblings, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-11  6:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 10, 2012 at 11:59:13AM -0700, Stephen Boyd wrote:
> On 04/10/12 06:45, Sascha Hauer wrote:
> > +static int clk_busy_wait(void __iomem *reg, u8 shift)
> > +{
> > +	unsigned long timeout = jiffies + msecs_to_jiffies(10);
> > +
> > +	while (readl_relaxed(reg) & (1 << shift))
> > +		if (time_after(jiffies, timeout))
> > +			return -ETIMEDOUT;
> > +
> > +	return 0;
> > +}
> 
> MSM also has a bit to poll to see if a clock is enabled or not, similar
> to this rate switch complete bit. Would it make sense to have another
> few clock ops like wait_for_enable(), wait_for_rate(),
> wait_for_disable()? Then you should be able to copy the basic divider
> ops and assign the wait ops and avoid the wrappers.

I think this won't work. What arguments would your wait_for_* functions
take?

> 
> Also, why are these drivers in arch/arm? Shouldn't we be putting all
> clock drivers into drivers/clk/ now?

The last time this topic came up this was not entirely clear. Personally
I do not have a preference.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH 27/40] ARM i.MX25: implement clocks using common clock framework
  2012-04-10 20:45     ` Fabio Estevam
@ 2012-04-11  7:01       ` Roberto Nibali
  0 siblings, 0 replies; 101+ messages in thread
From: Roberto Nibali @ 2012-04-11  7:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Tue, Apr 10, 2012 at 22:45, Fabio Estevam <festevam@gmail.com> wrote:
> On Tue, Apr 10, 2012 at 5:10 PM, Roberto Nibali <rnibali@gmail.com> wrote:
>
>> Wouldn't it be better to adjust this to mx25-adc.0, since it already
>> has a user: the new i.MX25 ADC TS driver by your colleague Juergen
>> Beiser, no?
>
> Is this mx25 adc driver available somewhere?

Yes, but I couldn't find it anymore in the archives. You have to ask
Juergen Beisert directly. I could make a diff of my current git tree
with regard to the changes, however I have modified some bits an
pieces of his original work.

I could have sworn that he posted his driver framework somewhere ...

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  1:11       ` Richard Zhao
@ 2012-04-11  8:24         ` Mark Brown
  2012-04-11  8:45           ` Richard Zhao
  0 siblings, 1 reply; 101+ messages in thread
From: Mark Brown @ 2012-04-11  8:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 09:11:50AM +0800, Richard Zhao wrote:

> I don't like string loopup either. And after DT binding, we can use
> phandler to refer clk.

No, this is only useful on platforms that use DT.  This is a generic
Linux API so it needs to support architectures and platforms that don't
use DT as it's vanishingly unlikely that DT will ever be adopted by all
platforms.

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  8:24         ` Mark Brown
@ 2012-04-11  8:45           ` Richard Zhao
  2012-04-11  9:15             ` Mark Brown
  2012-04-11  9:20             ` Russell King - ARM Linux
  0 siblings, 2 replies; 101+ messages in thread
From: Richard Zhao @ 2012-04-11  8:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 09:24:02AM +0100, Mark Brown wrote:
> On Wed, Apr 11, 2012 at 09:11:50AM +0800, Richard Zhao wrote:
> 
> > I don't like string loopup either. And after DT binding, we can use
> > phandler to refer clk.
> 
> No, this is only useful on platforms that use DT.  This is a generic
> Linux API so it needs to support architectures and platforms that don't
> use DT as it's vanishingly unlikely that DT will ever be adopted by all
> platforms.
My point is using string lookup as less as possible. When one register
a clk, one already got the struct clk* pointer and could use it in
struct lookup.

I'm worried about the performance as I saw string lookup is used more
and more often. In fast boot case, for example, even 5ms is important.

Thanks
Richard

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  8:45           ` Richard Zhao
@ 2012-04-11  9:15             ` Mark Brown
  2012-04-11  9:21               ` Russell King - ARM Linux
  2012-04-11  9:20             ` Russell King - ARM Linux
  1 sibling, 1 reply; 101+ messages in thread
From: Mark Brown @ 2012-04-11  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 04:45:29PM +0800, Richard Zhao wrote:
> On Wed, Apr 11, 2012 at 09:24:02AM +0100, Mark Brown wrote:

> > No, this is only useful on platforms that use DT.  This is a generic
> > Linux API so it needs to support architectures and platforms that don't
> > use DT as it's vanishingly unlikely that DT will ever be adopted by all
> > platforms.

> My point is using string lookup as less as possible. When one register

That's not really relevant to what I'm saying here - I'm not commenting
on your goal, I'm commenting on the solution.  Obviously we want to be
able to use things with DT but if we rely on it then we still need to
solve the same problem for non-DT platforms.

> a clk, one already got the struct clk* pointer and could use it in
> struct lookup.

How will you handle cases where one clock supplies another?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120411/3a29c1c3/attachment.sig>

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  8:45           ` Richard Zhao
  2012-04-11  9:15             ` Mark Brown
@ 2012-04-11  9:20             ` Russell King - ARM Linux
  2012-04-11  9:42               ` Sascha Hauer
  2012-04-24  2:17               ` Richard Zhao
  1 sibling, 2 replies; 101+ messages in thread
From: Russell King - ARM Linux @ 2012-04-11  9:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 04:45:29PM +0800, Richard Zhao wrote:
> On Wed, Apr 11, 2012 at 09:24:02AM +0100, Mark Brown wrote:
> > On Wed, Apr 11, 2012 at 09:11:50AM +0800, Richard Zhao wrote:
> > 
> > > I don't like string loopup either. And after DT binding, we can use
> > > phandler to refer clk.
> > 
> > No, this is only useful on platforms that use DT.  This is a generic
> > Linux API so it needs to support architectures and platforms that don't
> > use DT as it's vanishingly unlikely that DT will ever be adopted by all
> > platforms.
> My point is using string lookup as less as possible. When one register
> a clk, one already got the struct clk* pointer and could use it in
> struct lookup.
> 
> I'm worried about the performance as I saw string lookup is used more
> and more often. In fast boot case, for example, even 5ms is important.

Yes, and you're not the only one who has that concern.  What this patch
does is turn a pair of string compares through a table into that plus
another set of string compares across all struct clk, which will make
the lookup yet more expensive.

I see no reason why you'd register the cl_lookup structures before you
know about which clks actually exist - and if they already exist, then
you can already find the struct clk pointer and use that to register
the proper return value for clk_get() via the clkdev APIs.

As I've said in the past, naming individual clock structures is the
stupidest thing that anyone ever did and causes nothing but problems.
We've seen that in the drivers with the abuse of clk_get(NULL, name)
where people wanted to pass the name in via platform data.  We're
starting to see the same thing here as well, except the problem people
will see will be boot performance instead caused by multiple levels of
string compares.

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  9:15             ` Mark Brown
@ 2012-04-11  9:21               ` Russell King - ARM Linux
  2012-04-11  9:32                 ` Mark Brown
  0 siblings, 1 reply; 101+ messages in thread
From: Russell King - ARM Linux @ 2012-04-11  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 10:15:49AM +0100, Mark Brown wrote:
> On Wed, Apr 11, 2012 at 04:45:29PM +0800, Richard Zhao wrote:
> > a clk, one already got the struct clk* pointer and could use it in
> > struct lookup.
> 
> How will you handle cases where one clock supplies another?

What has that got to do with clkdev (which is the topic in this thread)?

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  9:21               ` Russell King - ARM Linux
@ 2012-04-11  9:32                 ` Mark Brown
  2012-04-11  9:41                   ` Russell King - ARM Linux
  0 siblings, 1 reply; 101+ messages in thread
From: Mark Brown @ 2012-04-11  9:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 10:21:47AM +0100, Russell King - ARM Linux wrote:
> On Wed, Apr 11, 2012 at 10:15:49AM +0100, Mark Brown wrote:
> > On Wed, Apr 11, 2012 at 04:45:29PM +0800, Richard Zhao wrote:
> > > a clk, one already got the struct clk* pointer and could use it in
> > > struct lookup.

> > How will you handle cases where one clock supplies another?

> What has that got to do with clkdev (which is the topic in this thread)?

I'm expecting (well, hoping) that at some point we'll want to connect
clock trees between devices and it seems likely that clkdev will be
pressed into service for that since it's how we're binding clocks at the
minute.  It may be that we come up with some other scheme for making
those connections but as we appear to be defining a new scheme for
binding clocks together anyway it seems sensible that we should at least
be considering that case.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120411/bf7b8f1a/attachment-0001.sig>

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  9:32                 ` Mark Brown
@ 2012-04-11  9:41                   ` Russell King - ARM Linux
  2012-04-11 10:31                     ` Mark Brown
  0 siblings, 1 reply; 101+ messages in thread
From: Russell King - ARM Linux @ 2012-04-11  9:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 10:32:54AM +0100, Mark Brown wrote:
> On Wed, Apr 11, 2012 at 10:21:47AM +0100, Russell King - ARM Linux wrote:
> > On Wed, Apr 11, 2012 at 10:15:49AM +0100, Mark Brown wrote:
> > > On Wed, Apr 11, 2012 at 04:45:29PM +0800, Richard Zhao wrote:
> > > > a clk, one already got the struct clk* pointer and could use it in
> > > > struct lookup.
> 
> > > How will you handle cases where one clock supplies another?
> 
> > What has that got to do with clkdev (which is the topic in this thread)?
> 
> I'm expecting (well, hoping) that at some point we'll want to connect
> clock trees between devices and it seems likely that clkdev will be
> pressed into service for that since it's how we're binding clocks at the
> minute.  It may be that we come up with some other scheme for making
> those connections but as we appear to be defining a new scheme for
> binding clocks together anyway it seems sensible that we should at least
> be considering that case.

clkdev is just a mechanism to obtain a struct clk for a particular input
on a particular device.  Nothing more, nothing less.  So how does this
detail about how the struct clk ultimate gets used concern clkdev?

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  9:20             ` Russell King - ARM Linux
@ 2012-04-11  9:42               ` Sascha Hauer
  2012-04-11  9:47                 ` Russell King - ARM Linux
  2012-04-24  2:17               ` Richard Zhao
  1 sibling, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-11  9:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 10:20:34AM +0100, Russell King - ARM Linux wrote:
> On Wed, Apr 11, 2012 at 04:45:29PM +0800, Richard Zhao wrote:
> > On Wed, Apr 11, 2012 at 09:24:02AM +0100, Mark Brown wrote:
> > > On Wed, Apr 11, 2012 at 09:11:50AM +0800, Richard Zhao wrote:
> > > 
> > > > I don't like string loopup either. And after DT binding, we can use
> > > > phandler to refer clk.
> > > 
> > > No, this is only useful on platforms that use DT.  This is a generic
> > > Linux API so it needs to support architectures and platforms that don't
> > > use DT as it's vanishingly unlikely that DT will ever be adopted by all
> > > platforms.
> > My point is using string lookup as less as possible. When one register
> > a clk, one already got the struct clk* pointer and could use it in
> > struct lookup.
> > 
> > I'm worried about the performance as I saw string lookup is used more
> > and more often. In fast boot case, for example, even 5ms is important.
> 
> Yes, and you're not the only one who has that concern.  What this patch
> does is turn a pair of string compares through a table into that plus
> another set of string compares across all struct clk, which will make
> the lookup yet more expensive.
> 
> I see no reason why you'd register the cl_lookup structures before you
> know about which clks actually exist - and if they already exist, then
> you can already find the struct clk pointer and use that to register
> the proper return value for clk_get() via the clkdev APIs.

Indeed I have struct clk pointers, so I can instead use a to-be-written
combination of clkdev_alloc/clkdev_add. Would that be ok?

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  9:42               ` Sascha Hauer
@ 2012-04-11  9:47                 ` Russell King - ARM Linux
  2012-04-13  3:33                   ` Viresh Kumar
  0 siblings, 1 reply; 101+ messages in thread
From: Russell King - ARM Linux @ 2012-04-11  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 11:42:31AM +0200, Sascha Hauer wrote:
> On Wed, Apr 11, 2012 at 10:20:34AM +0100, Russell King - ARM Linux wrote:
> > Yes, and you're not the only one who has that concern.  What this patch
> > does is turn a pair of string compares through a table into that plus
> > another set of string compares across all struct clk, which will make
> > the lookup yet more expensive.
> > 
> > I see no reason why you'd register the cl_lookup structures before you
> > know about which clks actually exist - and if they already exist, then
> > you can already find the struct clk pointer and use that to register
> > the proper return value for clk_get() via the clkdev APIs.
> 
> Indeed I have struct clk pointers, so I can instead use a to-be-written
> combination of clkdev_alloc/clkdev_add. Would that be ok?

As we already have clkdev_alloc and clkdev_add, then I don't see that as
a problem - except we may have to change __clkdev_alloc() so that it can
be used before kmalloc() is up and running.

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  9:41                   ` Russell King - ARM Linux
@ 2012-04-11 10:31                     ` Mark Brown
  2012-04-11 11:43                       ` Russell King - ARM Linux
  0 siblings, 1 reply; 101+ messages in thread
From: Mark Brown @ 2012-04-11 10:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 10:41:36AM +0100, Russell King - ARM Linux wrote:

> clkdev is just a mechanism to obtain a struct clk for a particular input
> on a particular device.  Nothing more, nothing less.  So how does this
> detail about how the struct clk ultimate gets used concern clkdev?

It shouldn't.  

The main point I'm trying to make is that if we're adding an alternative
mechanism to the direct pointers for specifying the bindings to clkdev
(which is broadly the point of the original patch, AFAICT based on a
desire to split the mapping out from the definitions) then having it rely
on device tree in the first instance means we'll just need to solve the
same problem again for non-DT systems.  Richard was saying that the
problem Sascha was trying to solve is irrelevant because we can rely on
device tree but device tree is not widely available enough for that.

The bit about clock to clock mappings was mostly an aside since it seems
like it's roughly the same as what Sascha was trying to do and if we're
going to add something new it'd be better if it handled that case also;
that said re-reading Richard's message I'm not sure if this is actually
a suggestion of a new mechanism.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120411/eb2f1efe/attachment.sig>

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11 10:31                     ` Mark Brown
@ 2012-04-11 11:43                       ` Russell King - ARM Linux
  2012-04-12 16:33                         ` Mark Brown
  0 siblings, 1 reply; 101+ messages in thread
From: Russell King - ARM Linux @ 2012-04-11 11:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 11:31:07AM +0100, Mark Brown wrote:
> On Wed, Apr 11, 2012 at 10:41:36AM +0100, Russell King - ARM Linux wrote:
> > clkdev is just a mechanism to obtain a struct clk for a particular input
> > on a particular device.  Nothing more, nothing less.  So how does this
> > detail about how the struct clk ultimate gets used concern clkdev?
> 
> It shouldn't.  
> 
> The main point I'm trying to make is that if we're adding an alternative
> mechanism to the direct pointers for specifying the bindings to clkdev
> (which is broadly the point of the original patch, AFAICT based on a
> desire to split the mapping out from the definitions) then having it rely
> on device tree in the first instance means we'll just need to solve the
> same problem again for non-DT systems.  Richard was saying that the
> problem Sascha was trying to solve is irrelevant because we can rely on
> device tree but device tree is not widely available enough for that.

Err what?  Look, it's very very simple.

clkdev is all about translating a device + connection ID to a struct clk
pointer.  That's all, nothing more, nothing less.

What I see going on is that people want to translate a device + connection
ID to some other name, and use this other name to look up a struct clk.
Utterly idiotic and pointless.  Whether it be OF or not OF.

It's a crazy absurd idea.  At some point, you have to do some kind of
lookup and return a struct clk.  Why the hell have this insane double
mapping?

Look, solving the DT problem with clkdev is really simple.  You have the
DT node for the struct device, so you can look up DT properties associated
with that device.  Properties have a name, and you can use the connection
ID to translate into a DT property name to be looked up - eg, clk_%s.
This can return a phandle or whatever else which could then be translated
into a struct clk if you're representing each clk as a node in DT.

Nice and simple, no need for any additional crappy translation what so
ever - and, oh my god, it reduces the amount of list based searching
required to do the translation.

And it also allows non-DT to work just fine provided you register your
clk lookups _after_ you know the struct clk pointers which is exactly what
happens today.

Now, if getting the struct clk pointers is insanely difficult because of
the design of the common clk stuff, then that's where the problem lies,
and that problem needs to be fixed, and clkdev does not need to be bodged
around to fix a problem which is not relevant to it.

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

* [PATCH 25/40] ARM: imx: add common clock support for clk busy
  2012-04-11  6:53     ` Sascha Hauer
@ 2012-04-11 22:21       ` Stephen Boyd
  2012-04-12  3:30         ` Shawn Guo
  0 siblings, 1 reply; 101+ messages in thread
From: Stephen Boyd @ 2012-04-11 22:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/10/12 23:53, Sascha Hauer wrote:
> On Tue, Apr 10, 2012 at 11:59:13AM -0700, Stephen Boyd wrote:
>> On 04/10/12 06:45, Sascha Hauer wrote:
>>> +static int clk_busy_wait(void __iomem *reg, u8 shift)
>>> +{
>>> +	unsigned long timeout = jiffies + msecs_to_jiffies(10);
>>> +
>>> +	while (readl_relaxed(reg) & (1 << shift))
>>> +		if (time_after(jiffies, timeout))
>>> +			return -ETIMEDOUT;
>>> +
>>> +	return 0;
>>> +}
>> MSM also has a bit to poll to see if a clock is enabled or not, similar
>> to this rate switch complete bit. Would it make sense to have another
>> few clock ops like wait_for_enable(), wait_for_rate(),
>> wait_for_disable()? Then you should be able to copy the basic divider
>> ops and assign the wait ops and avoid the wrappers.
> I think this won't work. What arguments would your wait_for_* functions
> take?

I assume the same as what all the other ops take.

wait_for_disable(struct clk_hw *hw)
wait_for_enable(struct clk_hw *hw)
wait_for_rate(struct clk_hw *hw)

Do you see the need for anything else?

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

* [PATCH 25/40] ARM: imx: add common clock support for clk busy
  2012-04-10 13:45 ` [PATCH 25/40] ARM: imx: add common clock support for clk busy Sascha Hauer
  2012-04-10 18:59   ` Stephen Boyd
@ 2012-04-12  1:50   ` Richard Zhao
  2012-04-12  2:44     ` Shawn Guo
  2012-04-13  2:09   ` [PATCH] ARM: imx: remove clk_hw from clk_busy Shawn Guo
  2 siblings, 1 reply; 101+ messages in thread
From: Richard Zhao @ 2012-04-12  1:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 10, 2012 at 03:45:38PM +0200, Sascha Hauer wrote:
> From: Shawn Guo <shawn.guo@linaro.org>
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ---
>  arch/arm/mach-imx/Makefile   |    2 +-
>  arch/arm/mach-imx/clk-busy.c |  167 ++++++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-imx/clk.h      |    8 ++
>  3 files changed, 176 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/mach-imx/clk-busy.c
> 
> diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> index 4d6be8d..ae0a779 100644
> --- a/arch/arm/mach-imx/Makefile
> +++ b/arch/arm/mach-imx/Makefile
> @@ -12,7 +12,7 @@ obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-i
>  obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
>  
>  obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
> -			    clk-pfd.o
> +			    clk-pfd.o clk-busy.o
>  
>  # Support for CMOS sensor interface
>  obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
> diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c
> new file mode 100644
> index 0000000..9450f0b
> --- /dev/null
> +++ b/arch/arm/mach-imx/clk-busy.c
> @@ -0,0 +1,167 @@
> +/*
> + * Copyright 2012 Freescale Semiconductor, Inc.
> + * Copyright 2012 Linaro Ltd.
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +#include <linux/jiffies.h>
> +#include "clk.h"
> +
> +static int clk_busy_wait(void __iomem *reg, u8 shift)
> +{
> +	unsigned long timeout = jiffies + msecs_to_jiffies(10);
> +
> +	while (readl_relaxed(reg) & (1 << shift))
> +		if (time_after(jiffies, timeout))
> +			return -ETIMEDOUT;
> +
> +	return 0;
> +}
> +
> +struct clk_busy_divider {
> +	struct clk_hw hw;
> +	void __iomem *reg;
> +	u8 shift;
> +	struct clk_divider div;
> +	const struct clk_ops *div_ops;
> +};
It's not like a good way to inherit from struct clk_divider. Since we
already have struct clk_hw in struct clk_divider, why do you still 
duplicate hw here?
 
BRs
Richard

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

* [PATCH 25/40] ARM: imx: add common clock support for clk busy
  2012-04-12  1:50   ` Richard Zhao
@ 2012-04-12  2:44     ` Shawn Guo
  0 siblings, 0 replies; 101+ messages in thread
From: Shawn Guo @ 2012-04-12  2:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 12, 2012 at 09:50:14AM +0800, Richard Zhao wrote:
...
> > +struct clk_busy_divider {
> > +	struct clk_hw hw;
> > +	void __iomem *reg;
> > +	u8 shift;
> > +	struct clk_divider div;
> > +	const struct clk_ops *div_ops;
> > +};
> It's not like a good way to inherit from struct clk_divider.

Any good way to suggest?

> Since we
> already have struct clk_hw in struct clk_divider, why do you still 
> duplicate hw here?
>  
I can use the clk_hw in clk_divider, but it will make the translation
from clk_hw to clk_busy_divider a bit more complicated.  And in any
case, clk_busy_divider is a particular type of clk, so it should not
be surprising to have a its own clk_hw like any other clks.

-- 
Regards,
Shawn

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

* [PATCH 25/40] ARM: imx: add common clock support for clk busy
  2012-04-11 22:21       ` Stephen Boyd
@ 2012-04-12  3:30         ` Shawn Guo
  0 siblings, 0 replies; 101+ messages in thread
From: Shawn Guo @ 2012-04-12  3:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:21:29PM -0700, Stephen Boyd wrote:
> On 04/10/12 23:53, Sascha Hauer wrote:
> > On Tue, Apr 10, 2012 at 11:59:13AM -0700, Stephen Boyd wrote:
> >> On 04/10/12 06:45, Sascha Hauer wrote:
> >>> +static int clk_busy_wait(void __iomem *reg, u8 shift)
> >>> +{
> >>> +	unsigned long timeout = jiffies + msecs_to_jiffies(10);
> >>> +
> >>> +	while (readl_relaxed(reg) & (1 << shift))
> >>> +		if (time_after(jiffies, timeout))
> >>> +			return -ETIMEDOUT;
> >>> +
> >>> +	return 0;
> >>> +}
> >> MSM also has a bit to poll to see if a clock is enabled or not, similar
> >> to this rate switch complete bit. Would it make sense to have another
> >> few clock ops like wait_for_enable(), wait_for_rate(),
> >> wait_for_disable()? Then you should be able to copy the basic divider
> >> ops and assign the wait ops and avoid the wrappers.
> > I think this won't work. What arguments would your wait_for_* functions
> > take?
> 
> I assume the same as what all the other ops take.
> 
> wait_for_disable(struct clk_hw *hw)
> wait_for_enable(struct clk_hw *hw)
> wait_for_rate(struct clk_hw *hw)
> 
> Do you see the need for anything else?
> 
I guess Sascha is asking what arguments the particular clk registration
function need to take for implementing those wait_for_* ops.

For clk_gate example, besides the existing parameters that
clk_register_gate already takes, it needs to take more, probably
reg_busy, bit_busy, timeout at least.  And we need the same for
clk_divider and clk_mux.  (Yes, I have clks that need to wait for
busy when changing divider and parent.)

Having basic clks support that will definitely reduce the clock driver
code, but it will make the long parameter list of basic clks even
longer.  I do not know which way we should go.

-- 
Regards,
Shawn

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11 11:43                       ` Russell King - ARM Linux
@ 2012-04-12 16:33                         ` Mark Brown
  0 siblings, 0 replies; 101+ messages in thread
From: Mark Brown @ 2012-04-12 16:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 12:43:11PM +0100, Russell King - ARM Linux wrote:

> What I see going on is that people want to translate a device + connection
> ID to some other name, and use this other name to look up a struct clk.
> Utterly idiotic and pointless.  Whether it be OF or not OF.

> It's a crazy absurd idea.  At some point, you have to do some kind of
> lookup and return a struct clk.  Why the hell have this insane double
> mapping?

I agree, that is silly.  I had understood from Sascha's comments that
the use case was building up the SoC clock tree with some indirect
references.  I can understand someone wanting to do that for a use case
like grafting chunks of tree built up of static data together, it might
be a bit more nicely data driven.

> Look, solving the DT problem with clkdev is really simple.  You have the
> DT node for the struct device, so you can look up DT properties associated

Yes, DT is completely straightforward here.

> And it also allows non-DT to work just fine provided you register your
> clk lookups _after_ you know the struct clk pointers which is exactly what
> happens today.

> Now, if getting the struct clk pointers is insanely difficult because of
> the design of the common clk stuff, then that's where the problem lies,
> and that problem needs to be fixed, and clkdev does not need to be bodged
> around to fix a problem which is not relevant to it.

I don't think it's anything particularly to do with the common clk stuff
really (at least I share your opinion that it shouldn't be) but it does
seem like it might be a real pain once we start deploying clock trees
that go off SoC.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120412/6f2bafb0/attachment.sig>

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

* [PATCH] ARM: imx: remove clk_hw from clk_busy
  2012-04-10 13:45 ` [PATCH 25/40] ARM: imx: add common clock support for clk busy Sascha Hauer
  2012-04-10 18:59   ` Stephen Boyd
  2012-04-12  1:50   ` Richard Zhao
@ 2012-04-13  2:09   ` Shawn Guo
  2012-04-13 14:34     ` Sascha Hauer
  2 siblings, 1 reply; 101+ messages in thread
From: Shawn Guo @ 2012-04-13  2:09 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
Hi Sascha,

I'm convinced by Richard that we do not need a clk_hw duplication
in clk_busy for a better OOP view.  So please consider to squash
the patch to "ARM: imx: add common clock support for clk busy".

Thanks,
Shawn

 arch/arm/mach-imx/clk-busy.c |   32 ++++++++++++++++++--------------
 1 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c
index 9450f0b..977d50a 100644
--- a/arch/arm/mach-imx/clk-busy.c
+++ b/arch/arm/mach-imx/clk-busy.c
@@ -29,14 +29,18 @@ static int clk_busy_wait(void __iomem *reg, u8 shift)
 }
 
 struct clk_busy_divider {
-	struct clk_hw hw;
-	void __iomem *reg;
-	u8 shift;
 	struct clk_divider div;
 	const struct clk_ops *div_ops;
+	void __iomem *reg;
+	u8 shift;
 };
 
-#define to_clk_busy_divider(_hw) container_of(_hw, struct clk_busy_divider, hw)
+static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw)
+{
+	struct clk_divider *div = container_of(hw, struct clk_divider, hw);
+
+	return container_of(div, struct clk_busy_divider, div);
+}
 
 static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw,
 						  unsigned long parent_rate)
@@ -92,25 +96,27 @@ struct clk *imx_clk_busy_divider(const char *name, char *parent_name,
 	busy->div.lock = &imx_ccm_lock;
 	busy->div_ops = &clk_divider_ops;
 
-	clk = clk_register(NULL, name, &clk_busy_divider_ops, &busy->hw,
+	clk = clk_register(NULL, name, &clk_busy_divider_ops, &busy->div.hw,
 			   &parent_name, 1, CLK_SET_RATE_PARENT);
 	if (!clk)
 		kfree(busy);
 
-	busy->div.hw.clk = clk;
-
 	return clk;
 }
 
 struct clk_busy_mux {
-	struct clk_hw hw;
-	void __iomem *reg;
-	u8 shift;
 	struct clk_mux mux;
 	const struct clk_ops *mux_ops;
+	void __iomem *reg;
+	u8 shift;
 };
 
-#define to_clk_busy_mux(_hw) container_of(_hw, struct clk_busy_mux, hw)
+static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw)
+{
+	struct clk_mux *mux = container_of(hw, struct clk_mux, hw);
+
+	return container_of(mux, struct clk_busy_mux, mux);
+}
 
 static u8 clk_busy_mux_get_parent(struct clk_hw *hw)
 {
@@ -156,12 +162,10 @@ struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
 	busy->mux.lock = &imx_ccm_lock;
 	busy->mux_ops = &clk_mux_ops;
 
-	clk = clk_register(NULL, name, &clk_busy_mux_ops, &busy->hw,
+	clk = clk_register(NULL, name, &clk_busy_mux_ops, &busy->mux.hw,
 			   parent_names, num_parents, 0);
 	if (!clk)
 		kfree(busy);
 
-	busy->mux.hw.clk = clk;
-
 	return clk;
 }
-- 
1.7.5.4

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  9:47                 ` Russell King - ARM Linux
@ 2012-04-13  3:33                   ` Viresh Kumar
  2012-04-13  4:17                     ` Shawn Guo
  0 siblings, 1 reply; 101+ messages in thread
From: Viresh Kumar @ 2012-04-13  3:33 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/11/2012 3:17 PM, Russell King - ARM Linux wrote:
>> > Indeed I have struct clk pointers, so I can instead use a to-be-written
>> > combination of clkdev_alloc/clkdev_add. Would that be ok?
> As we already have clkdev_alloc and clkdev_add, then I don't see that as
> a problem - except we may have to change __clkdev_alloc() so that it can
> be used before kmalloc() is up and running.

Instead of platforms calling these routines, can we have these calls from
clk_register_*() routines directly? So, for every clock registered with
common clk framework this gets done automatically. We just need to pass
dev & con id strings to these routines.

-- 
viresh

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13  3:33                   ` Viresh Kumar
@ 2012-04-13  4:17                     ` Shawn Guo
  2012-04-13  5:06                       ` Viresh Kumar
  0 siblings, 1 reply; 101+ messages in thread
From: Shawn Guo @ 2012-04-13  4:17 UTC (permalink / raw)
  To: linux-arm-kernel

On 13 April 2012 11:33, Viresh Kumar <viresh.kumar@st.com> wrote:
> On 4/11/2012 3:17 PM, Russell King - ARM Linux wrote:
>>> > Indeed I have struct clk pointers, so I can instead use a to-be-written
>>> > combination of clkdev_alloc/clkdev_add. Would that be ok?
>> As we already have clkdev_alloc and clkdev_add, then I don't see that as
>> a problem - except we may have to change __clkdev_alloc() so that it can
>> be used before kmalloc() is up and running.
>
> Instead of platforms calling these routines, can we have these calls from
> clk_register_*() routines directly? So, for every clock registered with
> common clk framework this gets done automatically. We just need to pass
> dev & con id strings to these routines.
>
No.

Only small portion of the entire clock tree need to be in the lookup,
usually the leaf clocks that device drivers need to access/manage.

Regards,
Shawn

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13  4:17                     ` Shawn Guo
@ 2012-04-13  5:06                       ` Viresh Kumar
  2012-04-13  5:22                         ` Shawn Guo
  0 siblings, 1 reply; 101+ messages in thread
From: Viresh Kumar @ 2012-04-13  5:06 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/13/2012 9:47 AM, Shawn Guo wrote:
>> >
>> > Instead of platforms calling these routines, can we have these calls from
>> > clk_register_*() routines directly? So, for every clock registered with
>> > common clk framework this gets done automatically. We just need to pass
>> > dev & con id strings to these routines.
>> >
> No.
> 
> Only small portion of the entire clock tree need to be in the lookup,
> usually the leaf clocks that device drivers need to access/manage.

I am not asking to enforce this for all clocks and create too many clk lookups.
But do it for all clk_register() calls, that have valid dev_id or con_id.

Apart from device clocks, there are other clocks, parent selection, etc
that need it, so that we can do clk_get_sys().

-- 
viresh

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13  5:06                       ` Viresh Kumar
@ 2012-04-13  5:22                         ` Shawn Guo
  2012-04-13  8:59                           ` Mark Brown
  0 siblings, 1 reply; 101+ messages in thread
From: Shawn Guo @ 2012-04-13  5:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 13 April 2012 13:06, Viresh Kumar <viresh.kumar@st.com> wrote:
> On 4/13/2012 9:47 AM, Shawn Guo wrote:
>>> >
>>> > Instead of platforms calling these routines, can we have these calls from
>>> > clk_register_*() routines directly? So, for every clock registered with
>>> > common clk framework this gets done automatically. We just need to pass
>>> > dev & con id strings to these routines.
>>> >
>> No.
>>
>> Only small portion of the entire clock tree need to be in the lookup,
>> usually the leaf clocks that device drivers need to access/manage.
>
> I am not asking to enforce this for all clocks and create too many clk lookups.
> But do it for all clk_register() calls, that have valid dev_id or con_id.
>
It makes sense then.  Only concern I have is the long argument list of
clk_register() becomes even longer.

Regards,
Shawn

> Apart from device clocks, there are other clocks, parent selection, etc
> that need it, so that we can do clk_get_sys().

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13  5:22                         ` Shawn Guo
@ 2012-04-13  8:59                           ` Mark Brown
  2012-04-13  9:10                             ` Viresh Kumar
  0 siblings, 1 reply; 101+ messages in thread
From: Mark Brown @ 2012-04-13  8:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 13, 2012 at 01:22:24PM +0800, Shawn Guo wrote:

> It makes sense then.  Only concern I have is the long argument list of
> clk_register() becomes even longer.

Or we need to dump the arguments into a struct.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120413/f83715ee/attachment.sig>

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13  8:59                           ` Mark Brown
@ 2012-04-13  9:10                             ` Viresh Kumar
  2012-04-13  9:17                               ` Richard Zhao
  0 siblings, 1 reply; 101+ messages in thread
From: Viresh Kumar @ 2012-04-13  9:10 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/13/2012 2:29 PM, Mark Brown wrote:
> Or we need to dump the arguments into a struct.

Then we would end up creating too many structures in our mach/clock.c
files. That will look bad. May perform better. :)

-- 
viresh

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13  9:10                             ` Viresh Kumar
@ 2012-04-13  9:17                               ` Richard Zhao
  2012-04-13  9:26                                 ` Russell King - ARM Linux
  0 siblings, 1 reply; 101+ messages in thread
From: Richard Zhao @ 2012-04-13  9:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 13, 2012 at 02:40:12PM +0530, Viresh Kumar wrote:
> On 4/13/2012 2:29 PM, Mark Brown wrote:
> > Or we need to dump the arguments into a struct.
> 
> Then we would end up creating too many structures in our mach/clock.c
> files. That will look bad. May perform better. :)
or pass struct clk_lookup* ? For non-leaf clks, it's NULL.

> 
> -- 
> viresh
> 

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13  9:17                               ` Richard Zhao
@ 2012-04-13  9:26                                 ` Russell King - ARM Linux
  2012-04-13  9:27                                   ` Viresh Kumar
  0 siblings, 1 reply; 101+ messages in thread
From: Russell King - ARM Linux @ 2012-04-13  9:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 13, 2012 at 05:17:13PM +0800, Richard Zhao wrote:
> On Fri, Apr 13, 2012 at 02:40:12PM +0530, Viresh Kumar wrote:
> > On 4/13/2012 2:29 PM, Mark Brown wrote:
> > > Or we need to dump the arguments into a struct.
> > 
> > Then we would end up creating too many structures in our mach/clock.c
> > files. That will look bad. May perform better. :)
> or pass struct clk_lookup* ? For non-leaf clks, it's NULL.

What's wrong with the struct clk returned from clk_register() - why
not do this as a two-step process?  Especially as you may want to
associate a single clock with more than one clk_lookup.

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13  9:26                                 ` Russell King - ARM Linux
@ 2012-04-13  9:27                                   ` Viresh Kumar
  2012-04-13  9:36                                     ` Russell King - ARM Linux
  0 siblings, 1 reply; 101+ messages in thread
From: Viresh Kumar @ 2012-04-13  9:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/13/2012 2:56 PM, Russell King - ARM Linux wrote:
> What's wrong with the struct clk returned from clk_register() - why
> not do this as a two-step process?

Code duplication on all platforms for creating these lookups.

> Especially as you may want to
> associate a single clock with more than one clk_lookup.

Can still be done, as we are still getting clk pointer back.

-- 
viresh

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13  9:27                                   ` Viresh Kumar
@ 2012-04-13  9:36                                     ` Russell King - ARM Linux
  2012-04-13 10:02                                       ` Viresh Kumar
  0 siblings, 1 reply; 101+ messages in thread
From: Russell King - ARM Linux @ 2012-04-13  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 13, 2012 at 02:57:36PM +0530, Viresh Kumar wrote:
> On 4/13/2012 2:56 PM, Russell King - ARM Linux wrote:
> > What's wrong with the struct clk returned from clk_register() - why
> > not do this as a two-step process?
> 
> Code duplication on all platforms for creating these lookups.
> 
> > Especially as you may want to
> > associate a single clock with more than one clk_lookup.
> 
> Can still be done, as we are still getting clk pointer back.

You're not convincing me that you're approach here is correct, and
I really doubt that this will have any effect at saving lines of code -
your argument list is soo long that you'll have to wrap it onto several
lines.

So I don't buy the 'code duplication' argument here - I think that's a
red herring, and I think you're better off making interfaces which are
simpler to use.

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13  9:36                                     ` Russell King - ARM Linux
@ 2012-04-13 10:02                                       ` Viresh Kumar
  2012-04-13 10:08                                         ` Mark Brown
  2012-04-13 10:20                                         ` Russell King - ARM Linux
  0 siblings, 2 replies; 101+ messages in thread
From: Viresh Kumar @ 2012-04-13 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/13/2012 3:06 PM, Russell King - ARM Linux wrote:
> You're not convincing me that you're approach here is correct, and

:(

> I really doubt that this will have any effect at saving lines of code -
> your argument list is soo long that you'll have to wrap it onto several
> lines.

There are two ways here:
1. Leave clk_register() untouched and create lookups in machine code.
2. change clk_register():
	A. pass all arguments as i mentioned in my patch
	B. pass structure instead of all so many args.

Option 2 will have much lesser code than option 1, with both option A & B.
In option 2.A.: we can create separate registration routines to save extra
arguments passed, like:

 struct clk *clk_register_gate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 bit_idx,
		u8 clk_gate_flags, spinlock_t *lock, struct clk_lookup **cl,
		const char *dev_id, const char *con_id);

static inline struct clk *clk_register_gate_nolookup(struct device *dev,
		const char *name, const char *parent_name, unsigned long flags,
		void __iomem *reg, u8 bit_idx, u8 clk_gate_flags,
		spinlock_t *lock);

Nodes, that don't need lookup stuff, can go ahead as earlier, just need
to add _nolookup in existing routine name.

-- 
viresh

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13 10:02                                       ` Viresh Kumar
@ 2012-04-13 10:08                                         ` Mark Brown
  2012-04-13 10:20                                         ` Russell King - ARM Linux
  1 sibling, 0 replies; 101+ messages in thread
From: Mark Brown @ 2012-04-13 10:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 13, 2012 at 03:32:43PM +0530, Viresh Kumar wrote:

> Nodes, that don't need lookup stuff, can go ahead as earlier, just need
> to add _nolookup in existing routine name.

Or just have the core function handle NULL as a lookup array gracefully.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120413/24bcc1a6/attachment.sig>

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13 10:02                                       ` Viresh Kumar
  2012-04-13 10:08                                         ` Mark Brown
@ 2012-04-13 10:20                                         ` Russell King - ARM Linux
  2012-04-13 10:43                                           ` Viresh Kumar
  2012-04-13 23:19                                           ` Turquette, Mike
  1 sibling, 2 replies; 101+ messages in thread
From: Russell King - ARM Linux @ 2012-04-13 10:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 13, 2012 at 03:32:43PM +0530, Viresh Kumar wrote:
> On 4/13/2012 3:06 PM, Russell King - ARM Linux wrote:
> > You're not convincing me that you're approach here is correct, and
> 
> :(
> 
> > I really doubt that this will have any effect at saving lines of code -
> > your argument list is soo long that you'll have to wrap it onto several
> > lines.
> 
> There are two ways here:
> 1. Leave clk_register() untouched and create lookups in machine code.
> 2. change clk_register():
> 	A. pass all arguments as i mentioned in my patch
> 	B. pass structure instead of all so many args.
> 
> Option 2 will have much lesser code than option 1, with both option A & B.
> In option 2.A.: we can create separate registration routines to save extra
> arguments passed, like:
> 
>  struct clk *clk_register_gate(struct device *dev, const char *name,
>  		const char *parent_name, unsigned long flags,
>  		void __iomem *reg, u8 bit_idx,
> 		u8 clk_gate_flags, spinlock_t *lock, struct clk_lookup **cl,
> 		const char *dev_id, const char *con_id);

So you're going to have something around 4-5 lines of arguments per
function call to use this function.  That's not elegant, that's not
easy to use, that's not nice.  And I doubt that it really solves any
code space concern because the compiler will have to store pointers
and values somewhere, and shuffle those into registers and onto the
stack for every function call using additional code to do that.

I really don't get why you think this is an improvement.

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13 10:20                                         ` Russell King - ARM Linux
@ 2012-04-13 10:43                                           ` Viresh Kumar
  2012-04-13 23:19                                           ` Turquette, Mike
  1 sibling, 0 replies; 101+ messages in thread
From: Viresh Kumar @ 2012-04-13 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/13/2012 3:50 PM, Russell King - ARM Linux wrote:
> So you're going to have something around 4-5 lines of arguments per
> function call to use this function.  That's not elegant, that's not
> easy to use, that's not nice.  And I doubt that it really solves any
> code space concern because the compiler will have to store pointers
> and values somewhere, and shuffle those into registers and onto the
> stack for every function call using additional code to do that.

But it is still the same with the current implementation. Right now
also we have too many arguments. Even if we do clkdev_alloc() in
platform files.

> I really don't get why you think this is an improvement.

Only improvement is simplicity at the end of machine clock.c files, that
don't need to do clkdev_alloc() for every clock they clk_lookups.

I didn't liked this long of argument list, but couldn't think of
something better, that makes machine clock code easy. :(

-- 
viresh

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

* [PATCH] ARM: imx: remove clk_hw from clk_busy
  2012-04-13  2:09   ` [PATCH] ARM: imx: remove clk_hw from clk_busy Shawn Guo
@ 2012-04-13 14:34     ` Sascha Hauer
  0 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-13 14:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 13, 2012 at 10:09:57AM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ---
> Hi Sascha,
> 
> I'm convinced by Richard that we do not need a clk_hw duplication
> in clk_busy for a better OOP view.  So please consider to squash
> the patch to "ARM: imx: add common clock support for clk busy".

Ok, will do.

Thanks
 Sascha

> 
> Thanks,
> Shawn
> 
>  arch/arm/mach-imx/clk-busy.c |   32 ++++++++++++++++++--------------
>  1 files changed, 18 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c
> index 9450f0b..977d50a 100644
> --- a/arch/arm/mach-imx/clk-busy.c
> +++ b/arch/arm/mach-imx/clk-busy.c
> @@ -29,14 +29,18 @@ static int clk_busy_wait(void __iomem *reg, u8 shift)
>  }
>  
>  struct clk_busy_divider {
> -	struct clk_hw hw;
> -	void __iomem *reg;
> -	u8 shift;
>  	struct clk_divider div;
>  	const struct clk_ops *div_ops;
> +	void __iomem *reg;
> +	u8 shift;
>  };
>  
> -#define to_clk_busy_divider(_hw) container_of(_hw, struct clk_busy_divider, hw)
> +static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw)
> +{
> +	struct clk_divider *div = container_of(hw, struct clk_divider, hw);
> +
> +	return container_of(div, struct clk_busy_divider, div);
> +}
>  
>  static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw,
>  						  unsigned long parent_rate)
> @@ -92,25 +96,27 @@ struct clk *imx_clk_busy_divider(const char *name, char *parent_name,
>  	busy->div.lock = &imx_ccm_lock;
>  	busy->div_ops = &clk_divider_ops;
>  
> -	clk = clk_register(NULL, name, &clk_busy_divider_ops, &busy->hw,
> +	clk = clk_register(NULL, name, &clk_busy_divider_ops, &busy->div.hw,
>  			   &parent_name, 1, CLK_SET_RATE_PARENT);
>  	if (!clk)
>  		kfree(busy);
>  
> -	busy->div.hw.clk = clk;
> -
>  	return clk;
>  }
>  
>  struct clk_busy_mux {
> -	struct clk_hw hw;
> -	void __iomem *reg;
> -	u8 shift;
>  	struct clk_mux mux;
>  	const struct clk_ops *mux_ops;
> +	void __iomem *reg;
> +	u8 shift;
>  };
>  
> -#define to_clk_busy_mux(_hw) container_of(_hw, struct clk_busy_mux, hw)
> +static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw)
> +{
> +	struct clk_mux *mux = container_of(hw, struct clk_mux, hw);
> +
> +	return container_of(mux, struct clk_busy_mux, mux);
> +}
>  
>  static u8 clk_busy_mux_get_parent(struct clk_hw *hw)
>  {
> @@ -156,12 +162,10 @@ struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
>  	busy->mux.lock = &imx_ccm_lock;
>  	busy->mux_ops = &clk_mux_ops;
>  
> -	clk = clk_register(NULL, name, &clk_busy_mux_ops, &busy->hw,
> +	clk = clk_register(NULL, name, &clk_busy_mux_ops, &busy->mux.hw,
>  			   parent_names, num_parents, 0);
>  	if (!clk)
>  		kfree(busy);
>  
> -	busy->mux.hw.clk = clk;
> -
>  	return clk;
>  }
> -- 
> 1.7.5.4
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-13 10:20                                         ` Russell King - ARM Linux
  2012-04-13 10:43                                           ` Viresh Kumar
@ 2012-04-13 23:19                                           ` Turquette, Mike
  1 sibling, 0 replies; 101+ messages in thread
From: Turquette, Mike @ 2012-04-13 23:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 13, 2012 at 3:20 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Fri, Apr 13, 2012 at 03:32:43PM +0530, Viresh Kumar wrote:
>> On 4/13/2012 3:06 PM, Russell King - ARM Linux wrote:
>> > You're not convincing me that you're approach here is correct, and
>>
>> :(
>>
>> > I really doubt that this will have any effect at saving lines of code -
>> > your argument list is soo long that you'll have to wrap it onto several
>> > lines.
>>
>> There are two ways here:
>> 1. Leave clk_register() untouched and create lookups in machine code.
>> 2. change clk_register():
>> ? ? ? A. pass all arguments as i mentioned in my patch
>> ? ? ? B. pass structure instead of all so many args.
>>
>> Option 2 will have much lesser code than option 1, with both option A & B.
>> In option 2.A.: we can create separate registration routines to save extra
>> arguments passed, like:
>>
>> ?struct clk *clk_register_gate(struct device *dev, const char *name,
>> ? ? ? ? ? ? ? const char *parent_name, unsigned long flags,
>> ? ? ? ? ? ? ? void __iomem *reg, u8 bit_idx,
>> ? ? ? ? ? ? ? u8 clk_gate_flags, spinlock_t *lock, struct clk_lookup **cl,
>> ? ? ? ? ? ? ? const char *dev_id, const char *con_id);
>
> So you're going to have something around 4-5 lines of arguments per
> function call to use this function. ?That's not elegant, that's not
> easy to use, that's not nice. ?And I doubt that it really solves any
> code space concern because the compiler will have to store pointers
> and values somewhere, and shuffle those into registers and onto the
> stack for every function call using additional code to do that.
>
> I really don't get why you think this is an improvement.

My hope is that forthcoming struct clk_hw/static initializer patch
will reduce the number of arguments to clk_register considerably.
These interfaces are not frozen and everyone concerned with using the
common framework is still figuring out exactly how this stuff should
look.

http://article.gmane.org/gmane.linux.ports.arm.msm/2587

Regards,
Mike

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

* [PATCH 28/40] ARM i.MX1: implement clocks using common clock framework
  2012-04-10 13:45 ` [PATCH 28/40] ARM i.MX1: " Sascha Hauer
@ 2012-04-16 21:07   ` Sascha Hauer
  0 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-16 21:07 UTC (permalink / raw)
  To: linux-arm-kernel

Here is a new version of the i.MX1 support which does not register the
clk lookups based on string names for the clks.

Before converting the rest I'd like to know whether everyones happy
with this.

Comments?

Thanks
 Sascha

8<---------------------------------------------------

[PATCH] ARM i.MX1: implement clocks using common clock framework

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/Kconfig    |    1 +
 arch/arm/mach-imx/Makefile   |    2 +-
 arch/arm/mach-imx/clk-imx1.c |  115 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-imx/clk-imx1.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 0b832b1..c03920a 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -34,6 +34,7 @@ config ARCH_MX53
 config SOC_IMX1
 	bool
 	select ARCH_MX1
+	select COMMON_CLK
 	select CPU_ARM920T
 	select IMX_HAVE_IOMUX_V1
 	select MXC_AVIC
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 173e869..52b3af4 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_SOC_IMX1) += clock-imx1.o mm-imx1.o
+obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o
 obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o
 
 obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c
new file mode 100644
index 0000000..3b3df4d
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx1.c
@@ -0,0 +1,115 @@
+/*
+ *  Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include "clk.h"
+
+/* CCM register addresses */
+#define IO_ADDR_CCM(off)	(MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
+
+#define CCM_CSCR	IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0	IO_ADDR_CCM(0x4)
+#define CCM_SPCTL0	IO_ADDR_CCM(0xc)
+#define CCM_PCDR	IO_ADDR_CCM(0x20)
+
+/* SCM register addresses */
+#define IO_ADDR_SCM(off)	(MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
+
+#define SCM_GCCR	IO_ADDR_SCM(0xc)
+
+static char *prem_sel_clks[] = { "clk32_premult", "clk16m", };
+static char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m", "prem",
+				"fclk", };
+enum imx1_clks {
+	dummy, clk32, clk16m_ext, clk16m, clk32_premult, prem, mpll, spll, mcu,
+	fclk, hclk, clk48m, per1, per2, per3, clko, dma_gate, csi_gate,
+	mma_gate, usbd_gate, clk_max
+};
+
+static struct clk *clk[clk_max];
+
+int __init mx1_clocks_init(unsigned long fref)
+{
+	int i;
+
+	clk[dummy] = imx_clk_fixed("dummy", 0);
+	clk[clk32] = imx_clk_fixed("clk32", fref);
+	clk[clk16m_ext] = imx_clk_fixed("clk16m_ext", 16000000);
+	clk[clk16m] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17);
+	clk[clk32_premult] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
+	clk[prem] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks,
+			ARRAY_SIZE(prem_sel_clks));
+	clk[mpll] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0);
+	clk[spll] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0);
+	clk[mcu] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1);
+	clk[fclk] = imx_clk_divider("fclk", "mpll", CCM_CSCR, 15, 1);
+	clk[hclk] = imx_clk_divider("hclk", "spll", CCM_CSCR, 10, 4);
+	clk[clk48m] = imx_clk_divider("clk48m", "spll", CCM_CSCR, 26, 3);
+	clk[per1] = imx_clk_divider("per1", "spll", CCM_PCDR, 0, 4);
+	clk[per2] = imx_clk_divider("per2", "spll", CCM_PCDR, 4, 4);
+	clk[per3] = imx_clk_divider("per3", "spll", CCM_PCDR, 16, 7);
+	clk[clko] = imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks,
+			ARRAY_SIZE(clko_sel_clks));
+	clk[dma_gate] = imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 4);
+	clk[csi_gate] = imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2);
+	clk[mma_gate] = imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1);
+	clk[usbd_gate] = imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0);
+
+	for (i = 0; i < ARRAY_SIZE(clk); i++)
+		if (IS_ERR(clk[i]))
+			pr_err("imx1 clk %d: register failed with %ld\n",
+				i, PTR_ERR(clk[i]));
+
+	clk_register_single_clkdev(clk[dma_gate], "dma", NULL);
+	clk_register_single_clkdev(clk[csi_gate], NULL, "mx1-camera.0");
+	clk_register_single_clkdev(clk[mma_gate], "mma", NULL);
+	clk_register_single_clkdev(clk[usbd_gate], NULL, "imx_udc.0");
+	clk_register_single_clkdev(clk[per1], "per", "imx-gpt.0");
+	clk_register_single_clkdev(clk[hclk], "ipg", "imx-gpt.0");
+	clk_register_single_clkdev(clk[per1], "per", "imx1-uart.0");
+	clk_register_single_clkdev(clk[hclk], "ipg", "imx1-uart.0");
+	clk_register_single_clkdev(clk[per1], "per", "imx1-uart.1");
+	clk_register_single_clkdev(clk[hclk], "ipg", "imx1-uart.1");
+	clk_register_single_clkdev(clk[per1], "per", "imx1-uart.2");
+	clk_register_single_clkdev(clk[hclk], "ipg", "imx1-uart.2");
+	clk_register_single_clkdev(clk[hclk], NULL, "imx-i2c.0");
+	clk_register_single_clkdev(clk[per2], "per", "imx1-cspi.0");
+	clk_register_single_clkdev(clk[dummy], "ipg", "imx1-cspi.0");
+	clk_register_single_clkdev(clk[per2], "per", "imx1-cspi.1");
+	clk_register_single_clkdev(clk[dummy], "ipg", "imx1-cspi.1");
+	clk_register_single_clkdev(clk[per2], NULL, "imx-mmc.0");
+	clk_register_single_clkdev(clk[per2], "per", "imx-fb.0");
+	clk_register_single_clkdev(clk[dummy], "ipg", "imx-fb.0");
+	clk_register_single_clkdev(clk[dummy], "ahb", "imx-fb.0");
+	clk_register_single_clkdev(clk[hclk], "mshc", NULL);
+	clk_register_single_clkdev(clk[per3], "ssi", NULL);
+	clk_register_single_clkdev(clk[clk32], NULL, "mxc_rtc.0");
+	clk_register_single_clkdev(clk[clko], "clko", NULL);
+
+	mxc_timer_init(NULL, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
+			MX1_TIM1_INT);
+
+	return 0;
+}
-- 
1.7.10


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH 02/40] clk: add a fixed factor clock
  2012-04-10 13:45 ` [PATCH 02/40] clk: add a fixed factor clock Sascha Hauer
@ 2012-04-17 10:15   ` Viresh Kumar
  2012-04-19  3:48   ` Viresh Kumar
  1 sibling, 0 replies; 101+ messages in thread
From: Viresh Kumar @ 2012-04-17 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/10/2012 7:15 PM, Sascha Hauer wrote:
> Having fixed factors/dividers in hardware is a common pattern, so
> add a basic clock type doing this. It basically describes a fixed
> factor clock using a nominator and a denominator.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/clk/Makefile           |    2 +-
>  drivers/clk/clk-fixed-factor.c |   97 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/clk-provider.h   |    4 ++
>  3 files changed, 102 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/clk-fixed-factor.c

Please see if below changes look fine to you. They would be required once
you rebase over latest patches floated by Mike:

---
 drivers/clk/clk-fixed-factor.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 7c5e1fc..45a4823 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -16,7 +16,7 @@ struct clk_fixed_factor {
        struct clk_hw   hw;
        unsigned int    mult;
        unsigned int    div;
-       char            *parent[1];
+       const char      *parent[1];
 };
 
 #define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
@@ -86,11 +86,13 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
                        fix->parent,
                        (parent_name ? 1 : 0),
                        flags);
+
+       if (parent_name)
+               kfree(fix->parent[0]);
+
        if (clk)
                return clk;
-
 out:
-       kfree(fix->parent[0]);
        kfree(fix);
 
        return NULL;


-- 
viresh

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

* [PATCH 34/40] ARM: imx6: implement clocks using common clock framework
  2012-04-10 13:45 ` [PATCH 34/40] ARM: imx6: " Sascha Hauer
@ 2012-04-18 11:33   ` Sascha Hauer
  2012-04-19 13:56     ` Shawn Guo
  0 siblings, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-18 11:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Shawn,

> +
> +static const char * const clks_init_on[] __initconst = {
> +	"mmdc_ch0_axi", "mmdc_ch1_axi", "uart_ipg", "uart_serial",
> +};

I assume uart_ipg and uart_serial is here for the earlyprintk case. This
is not needed anymore. earlyprintk depends on an enabled uart anyway, so
we can safely assume that the clock is turned on when Linux starts. The
clock framework will disable the clock in a late initcall, long after
the real driver has taken over and enabled the clock.

I'll fix that on my side.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH 02/40] clk: add a fixed factor clock
  2012-04-10 13:45 ` [PATCH 02/40] clk: add a fixed factor clock Sascha Hauer
  2012-04-17 10:15   ` Viresh Kumar
@ 2012-04-19  3:48   ` Viresh Kumar
  2012-04-19  6:16     ` Domenico Andreoli
  2012-04-19  6:45     ` Sascha Hauer
  1 sibling, 2 replies; 101+ messages in thread
From: Viresh Kumar @ 2012-04-19  3:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/10/2012 7:15 PM, Sascha Hauer wrote:
> Having fixed factors/dividers in hardware is a common pattern, so
> add a basic clock type doing this. It basically describes a fixed
> factor clock using a nominator and a denominator.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/clk/Makefile           |    2 +-
>  drivers/clk/clk-fixed-factor.c |   97 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/clk-provider.h   |    4 ++
>  3 files changed, 102 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/clk-fixed-factor.c

@Mike: It would be better if you can take this patch atleast ASAP in your next,
so that Arnd can pull in SPEAr clk patches.

Hi Sascha/Mike,

Please see if following can be squashed with this patch. This clock is
used for SPEAr too :)

---
 drivers/clk/clk-fixed-factor.c |   12 ++----------
 1 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 7c5e1fc..aaf5a88 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -16,7 +16,6 @@ struct clk_fixed_factor {
 	struct clk_hw	hw;
 	unsigned int	mult;
 	unsigned int	div;
-	char		*parent[1];
 };
 
 #define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
@@ -75,22 +74,15 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
 	fix->mult = mult;
 	fix->div = div;
 
-	if (parent_name) {
-		fix->parent[0] = kstrdup(parent_name, GFP_KERNEL);
-		if (!fix->parent[0])
-			goto out;
-	}
-
 	clk = clk_register(dev, name,
 			&clk_fixed_factor_ops, &fix->hw,
-			fix->parent,
+			&parent_name,
 			(parent_name ? 1 : 0),
 			flags);
+
 	if (clk)
 		return clk;
 
-out:
-	kfree(fix->parent[0]);
 	kfree(fix);
 
 	return NULL;
-- 
1.7.9

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

* [PATCH 02/40] clk: add a fixed factor clock
  2012-04-19  3:48   ` Viresh Kumar
@ 2012-04-19  6:16     ` Domenico Andreoli
  2012-04-19  6:19       ` Viresh Kumar
  2012-04-19  6:45     ` Sascha Hauer
  1 sibling, 1 reply; 101+ messages in thread
From: Domenico Andreoli @ 2012-04-19  6:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 19, 2012 at 09:18:01AM +0530, Viresh Kumar wrote:
> On 4/10/2012 7:15 PM, Sascha Hauer wrote:
> > Having fixed factors/dividers in hardware is a common pattern, so
> > add a basic clock type doing this. It basically describes a fixed
> > factor clock using a nominator and a denominator.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> >  drivers/clk/Makefile           |    2 +-
> >  drivers/clk/clk-fixed-factor.c |   97 ++++++++++++++++++++++++++++++++++++++++
> >  include/linux/clk-provider.h   |    4 ++
> >  3 files changed, 102 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/clk/clk-fixed-factor.c
> 
> @Mike: It would be better if you can take this patch atleast ASAP in your next,
> so that Arnd can pull in SPEAr clk patches.
> 
> Hi Sascha/Mike,
> 
> Please see if following can be squashed with this patch. This clock is
> used for SPEAr too :)
> 
> ---
>  drivers/clk/clk-fixed-factor.c |   12 ++----------
>  1 files changed, 2 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
> index 7c5e1fc..aaf5a88 100644
> --- a/drivers/clk/clk-fixed-factor.c
> +++ b/drivers/clk/clk-fixed-factor.c
> @@ -16,7 +16,6 @@ struct clk_fixed_factor {
>  	struct clk_hw	hw;
>  	unsigned int	mult;
>  	unsigned int	div;
> -	char		*parent[1];

add const here

>  };
>  
>  #define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
> @@ -75,22 +74,15 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
>  	fix->mult = mult;
>  	fix->div = div;
>  
> -	if (parent_name) {

		char *tmp = kstrdup(parent_name, GFP_KERNEL);
		if (!tmp)
			goto out;
		fix->parent[0] = tmp;
	
> -	}
> -
>  	clk = clk_register(dev, name,
>  			&clk_fixed_factor_ops, &fix->hw,
> -			fix->parent,
> +			&parent_name,

&parent_name is a pointer to a stack variable, right? clk_register
saves it in the clk struct for later use, when the stack is already gone.

>  			(parent_name ? 1 : 0),
>  			flags);
> +
>  	if (clk)
>  		return clk;
>  
> -out:
> -	kfree(fix->parent[0]);
>  	kfree(fix);
>  
>  	return NULL;

BRs,
Domenico

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

* [PATCH 02/40] clk: add a fixed factor clock
  2012-04-19  6:16     ` Domenico Andreoli
@ 2012-04-19  6:19       ` Viresh Kumar
  0 siblings, 0 replies; 101+ messages in thread
From: Viresh Kumar @ 2012-04-19  6:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/19/2012 11:46 AM, Domenico Andreoli wrote:
> On Thu, Apr 19, 2012 at 09:18:01AM +0530, Viresh Kumar wrote:
>> On 4/10/2012 7:15 PM, Sascha Hauer wrote:
>> diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
>> @@ -16,7 +16,6 @@ struct clk_fixed_factor {
>>  	struct clk_hw	hw;
>>  	unsigned int	mult;
>>  	unsigned int	div;
>> -	char		*parent[1];
> 
> add const here
> 

I removed it. :)

>>  	clk = clk_register(dev, name,
>>  			&clk_fixed_factor_ops, &fix->hw,
>> -			fix->parent,
>> +			&parent_name,
> 
> &parent_name is a pointer to a stack variable, right? clk_register
> saves it in the clk struct for later use, when the stack is already gone.

Yes. It is on stack, but clk_register doesn't save it any more. Following is
part of clk_register that saves

	/* copy each string name in case parent_names is __initdata */
	for (i = 0; i < num_parents; i++) {
		clk->parent_names[i] = kstrdup(parent_names[i], GFP_KERNEL);
		if (!clk->parent_names[i]) {
			pr_err("%s: could not copy parent_names\n", __func__);
			goto fail_parent_names_copy;
		}
	}

This happened with following patch sent by Mike. This isn't pushed till now.

Author: Mike Turquette <mturquette@linaro.org>
Date:   Thu Apr 12 09:02:50 2012 +0800

    clk: core: copy parent_names & return error codes
    
    This patch cleans up clk_register and solves a few bugs by teaching
    clk_register and __clk_init to return error codes (instead of just NULL)
    to better align with the existing clk.h api.
    
    Along with that change this patch also introduces a new behavior whereby
    clk_register copies the parent_names array, thus allowing platforms to
    declare their parent_names arrays as __initdata.

--
Viresh

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

* [PATCH 02/40] clk: add a fixed factor clock
  2012-04-19  3:48   ` Viresh Kumar
  2012-04-19  6:16     ` Domenico Andreoli
@ 2012-04-19  6:45     ` Sascha Hauer
  1 sibling, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-19  6:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 19, 2012 at 09:18:01AM +0530, Viresh Kumar wrote:
> On 4/10/2012 7:15 PM, Sascha Hauer wrote:
> > Having fixed factors/dividers in hardware is a common pattern, so
> > add a basic clock type doing this. It basically describes a fixed
> > factor clock using a nominator and a denominator.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> >  drivers/clk/Makefile           |    2 +-
> >  drivers/clk/clk-fixed-factor.c |   97 ++++++++++++++++++++++++++++++++++++++++
> >  include/linux/clk-provider.h   |    4 ++
> >  3 files changed, 102 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/clk/clk-fixed-factor.c
> 
> @Mike: It would be better if you can take this patch atleast ASAP in your next,
> so that Arnd can pull in SPEAr clk patches.
> 
> Hi Sascha/Mike,
> 
> Please see if following can be squashed with this patch. This clock is
> used for SPEAr too :)

Generally yes, but I want to delay this until we have an official branch
for clk-common-next (In which probably clk_register copies the parent
names)

Sascha

> 
> ---
>  drivers/clk/clk-fixed-factor.c |   12 ++----------
>  1 files changed, 2 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
> index 7c5e1fc..aaf5a88 100644
> --- a/drivers/clk/clk-fixed-factor.c
> +++ b/drivers/clk/clk-fixed-factor.c
> @@ -16,7 +16,6 @@ struct clk_fixed_factor {
>  	struct clk_hw	hw;
>  	unsigned int	mult;
>  	unsigned int	div;
> -	char		*parent[1];
>  };
>  
>  #define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
> @@ -75,22 +74,15 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
>  	fix->mult = mult;
>  	fix->div = div;
>  
> -	if (parent_name) {
> -		fix->parent[0] = kstrdup(parent_name, GFP_KERNEL);
> -		if (!fix->parent[0])
> -			goto out;
> -	}
> -
>  	clk = clk_register(dev, name,
>  			&clk_fixed_factor_ops, &fix->hw,
> -			fix->parent,
> +			&parent_name,
>  			(parent_name ? 1 : 0),
>  			flags);
> +
>  	if (clk)
>  		return clk;
>  
> -out:
> -	kfree(fix->parent[0]);
>  	kfree(fix);
>  
>  	return NULL;
> -- 
> 1.7.9
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH 23/40] ARM i.MX: Add common clock support for 2bit gate
  2012-04-10 13:45 ` [PATCH 23/40] ARM i.MX: Add common clock support for 2bit gate Sascha Hauer
@ 2012-04-19  7:00   ` Shawn Guo
  2012-04-19  7:15     ` Richard Zhao
  2012-04-19  7:26     ` Lei Wen
  0 siblings, 2 replies; 101+ messages in thread
From: Shawn Guo @ 2012-04-19  7:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 10, 2012 at 03:45:36PM +0200, Sascha Hauer wrote:
[snip]
> +struct clk *clk_register_gate2(struct device *dev, const char *name,
> +		const char *parent_name, unsigned long flags,
> +		void __iomem *reg, u8 bit_idx,
> +		u8 clk_gate2_flags, spinlock_t *lock)
> +{
> +	struct clk_gate *gate;
> +	struct clk *clk;
> +
> +	gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
> +
> +	if (!gate) {
> +		pr_err("%s: could not allocate gated clk\n", __func__);
> +		return NULL;
> +	}
> +
> +	/* struct clk_gate assignments */
> +	gate->reg = reg;
> +	gate->bit_idx = bit_idx;
> +	gate->flags = clk_gate2_flags;
> +	gate->lock = lock;
> +
> +	if (parent_name) {
> +		gate->parent[0] = kstrdup(parent_name, GFP_KERNEL);
> +		if (!gate->parent[0])
> +			goto out;
> +	}
> +
> +	clk = clk_register(dev, name,
> +			&clk_gate2_ops, &gate->hw,
> +			gate->parent,
> +			(parent_name ? 1 : 0),
> +			flags);
Why do you re-use struct clk_gate while you don't use clk_gate_ops?
It doesn't follow object oriented thought. struct clk_gate may change
according to clk_gate_ops changes.

Thanks
Richard
 

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

* [PATCH 23/40] ARM i.MX: Add common clock support for 2bit gate
  2012-04-19  7:00   ` Shawn Guo
@ 2012-04-19  7:15     ` Richard Zhao
  2012-04-19  7:26     ` Lei Wen
  1 sibling, 0 replies; 101+ messages in thread
From: Richard Zhao @ 2012-04-19  7:15 UTC (permalink / raw)
  To: linux-arm-kernel

Sorry Shawn, I steal your name :) . Last mail is from me.

Richard

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

* [PATCH 23/40] ARM i.MX: Add common clock support for 2bit gate
  2012-04-19  7:00   ` Shawn Guo
  2012-04-19  7:15     ` Richard Zhao
@ 2012-04-19  7:26     ` Lei Wen
  2012-04-19  7:52       ` Domenico Andreoli
  1 sibling, 1 reply; 101+ messages in thread
From: Lei Wen @ 2012-04-19  7:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 19, 2012 at 3:00 PM, Shawn Guo <shawn.guo@freescale.com> wrote:
> On Tue, Apr 10, 2012 at 03:45:36PM +0200, Sascha Hauer wrote:
> [snip]
>> +struct clk *clk_register_gate2(struct device *dev, const char *name,
>> + ? ? ? ? ? ? const char *parent_name, unsigned long flags,
>> + ? ? ? ? ? ? void __iomem *reg, u8 bit_idx,
>> + ? ? ? ? ? ? u8 clk_gate2_flags, spinlock_t *lock)
>> +{
>> + ? ? struct clk_gate *gate;
>> + ? ? struct clk *clk;
>> +
>> + ? ? gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
>> +
>> + ? ? if (!gate) {
>> + ? ? ? ? ? ? pr_err("%s: could not allocate gated clk\n", __func__);
>> + ? ? ? ? ? ? return NULL;
>> + ? ? }
>> +
>> + ? ? /* struct clk_gate assignments */
>> + ? ? gate->reg = reg;
>> + ? ? gate->bit_idx = bit_idx;
>> + ? ? gate->flags = clk_gate2_flags;
>> + ? ? gate->lock = lock;
>> +
>> + ? ? if (parent_name) {
>> + ? ? ? ? ? ? gate->parent[0] = kstrdup(parent_name, GFP_KERNEL);
>> + ? ? ? ? ? ? if (!gate->parent[0])
>> + ? ? ? ? ? ? ? ? ? ? goto out;
>> + ? ? }
>> +
>> + ? ? clk = clk_register(dev, name,
>> + ? ? ? ? ? ? ? ? ? ? &clk_gate2_ops, &gate->hw,
>> + ? ? ? ? ? ? ? ? ? ? gate->parent,
>> + ? ? ? ? ? ? ? ? ? ? (parent_name ? 1 : 0),
>> + ? ? ? ? ? ? ? ? ? ? flags);
> Why do you re-use struct clk_gate while you don't use clk_gate_ops?
> It doesn't follow object oriented thought. struct clk_gate may change
> according to clk_gate_ops changes.
>
> Thanks
> Richard
>
>
>

Why not expend original clk-gate.c to allow set more than one bit a
time to gate that clock?
At least in my platform, some clock need 12bit to get its gate mode,
which means that module
has more than one clock concurrently up to work, and only a part of
that group work cannot lead
to a correct working mode. This also means those bits need to turn
on/off at the same time.

Thanks,
Lei

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

* [PATCH 23/40] ARM i.MX: Add common clock support for 2bit gate
  2012-04-19  7:26     ` Lei Wen
@ 2012-04-19  7:52       ` Domenico Andreoli
  0 siblings, 0 replies; 101+ messages in thread
From: Domenico Andreoli @ 2012-04-19  7:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 19, 2012 at 03:26:53PM +0800, Lei Wen wrote:
> On Thu, Apr 19, 2012 at 3:00 PM, Shawn Guo <shawn.guo@freescale.com> wrote:
> > On Tue, Apr 10, 2012 at 03:45:36PM +0200, Sascha Hauer wrote:
> > [snip]
> >> +struct clk *clk_register_gate2(struct device *dev, const char *name,
> >> + ? ? ? ? ? ? const char *parent_name, unsigned long flags,
> >> + ? ? ? ? ? ? void __iomem *reg, u8 bit_idx,
> >> + ? ? ? ? ? ? u8 clk_gate2_flags, spinlock_t *lock)
> >> +{
> >> + ? ? struct clk_gate *gate;
> >> + ? ? struct clk *clk;
> >> +
> >> + ? ? gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
> >> +
> >> + ? ? if (!gate) {
> >> + ? ? ? ? ? ? pr_err("%s: could not allocate gated clk\n", __func__);
> >> + ? ? ? ? ? ? return NULL;
> >> + ? ? }
> >> +
> >> + ? ? /* struct clk_gate assignments */
> >> + ? ? gate->reg = reg;
> >> + ? ? gate->bit_idx = bit_idx;
> >> + ? ? gate->flags = clk_gate2_flags;
> >> + ? ? gate->lock = lock;
> >> +
> >> + ? ? if (parent_name) {
> >> + ? ? ? ? ? ? gate->parent[0] = kstrdup(parent_name, GFP_KERNEL);
> >> + ? ? ? ? ? ? if (!gate->parent[0])
> >> + ? ? ? ? ? ? ? ? ? ? goto out;
> >> + ? ? }
> >> +
> >> + ? ? clk = clk_register(dev, name,
> >> + ? ? ? ? ? ? ? ? ? ? &clk_gate2_ops, &gate->hw,
> >> + ? ? ? ? ? ? ? ? ? ? gate->parent,
> >> + ? ? ? ? ? ? ? ? ? ? (parent_name ? 1 : 0),
> >> + ? ? ? ? ? ? ? ? ? ? flags);
> > Why do you re-use struct clk_gate while you don't use clk_gate_ops?
> > It doesn't follow object oriented thought. struct clk_gate may change
> > according to clk_gate_ops changes.
> >
> > Thanks
> > Richard
> >
> >
> >
> 
> Why not expend original clk-gate.c to allow set more than one bit a
> time to gate that clock?
> At least in my platform, some clock need 12bit to get its gate mode,
> which means that module
> has more than one clock concurrently up to work, and only a part of
> that group work cannot lead
> to a correct working mode. This also means those bits need to turn
> on/off at the same time.

I would also need a double gate, one reg to enable and one to disable,
both or-ing the same bitmask. I think this can be addressed in the
flags but what about a union to store the different regs, widths, shifts?

thanks,
Domenico

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

* [PATCH 34/40] ARM: imx6: implement clocks using common clock framework
  2012-04-18 11:33   ` Sascha Hauer
@ 2012-04-19 13:56     ` Shawn Guo
  2012-04-19 14:06       ` Sascha Hauer
  0 siblings, 1 reply; 101+ messages in thread
From: Shawn Guo @ 2012-04-19 13:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 18, 2012 at 01:33:55PM +0200, Sascha Hauer wrote:
> Hi Shawn,
> 
> > +
> > +static const char * const clks_init_on[] __initconst = {
> > +	"mmdc_ch0_axi", "mmdc_ch1_axi", "uart_ipg", "uart_serial",
> > +};
> 
> I assume uart_ipg and uart_serial is here for the earlyprintk case. This
> is not needed anymore. earlyprintk depends on an enabled uart anyway, so
> we can safely assume that the clock is turned on when Linux starts. The
> clock framework will disable the clock in a late initcall, long after
> the real driver has taken over and enabled the clock.
> 
Yes, that's the case for the last 2 clocks, but the first 2 clocks are
for memory and need to be kept there.  Also, currently I do not have
uart_ipg in the clkdev for uart driver to look up, so if we remove it
from clks_init_on, we need to add it into clkdev.

-- 
Regards,
Shawn

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

* [PATCH 34/40] ARM: imx6: implement clocks using common clock framework
  2012-04-19 13:56     ` Shawn Guo
@ 2012-04-19 14:06       ` Sascha Hauer
  0 siblings, 0 replies; 101+ messages in thread
From: Sascha Hauer @ 2012-04-19 14:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 19, 2012 at 09:56:32PM +0800, Shawn Guo wrote:
> On Wed, Apr 18, 2012 at 01:33:55PM +0200, Sascha Hauer wrote:
> > Hi Shawn,
> > 
> > > +
> > > +static const char * const clks_init_on[] __initconst = {
> > > +	"mmdc_ch0_axi", "mmdc_ch1_axi", "uart_ipg", "uart_serial",
> > > +};
> > 
> > I assume uart_ipg and uart_serial is here for the earlyprintk case. This
> > is not needed anymore. earlyprintk depends on an enabled uart anyway, so
> > we can safely assume that the clock is turned on when Linux starts. The
> > clock framework will disable the clock in a late initcall, long after
> > the real driver has taken over and enabled the clock.
> > 
> Yes, that's the case for the last 2 clocks, but the first 2 clocks are
> for memory and need to be kept there.  Also, currently I do not have
> uart_ipg in the clkdev for uart driver to look up, so if we remove it
> from clks_init_on, we need to add it into clkdev.

Yes, I already fixed up the uart clocks.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH 09/40] mmc sdhc i.MX: do not depend on grouped clocks
  2012-04-10 13:45 ` [PATCH 09/40] mmc sdhc i.MX: " Sascha Hauer
@ 2012-04-20  2:06   ` Richard Zhao
  2012-04-20  2:42     ` Richard Zhao
  0 siblings, 1 reply; 101+ messages in thread
From: Richard Zhao @ 2012-04-20  2:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 10, 2012 at 03:45:22PM +0200, Sascha Hauer wrote:
> the current i.MX clock support groups together unrelated clocks
> to a single clock which is then used by the driver. This can't
> be accomplished with the generic clock framework so we instead
> request the individual clocks in the driver. For i.MX there are
> generally three different clocks:
> 
> ipg: bus clock (needed to access registers)
> ahb: dma relevant clock, sometimes referred to as hclk in the datasheet
> per: bit clock, pixel clock
> 
> This patch changes the driver to request the individual clocks.
> Currently all clk_get will get the same clock until the SoCs
> are converted to the generic clock framework
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c |   42 ++++++++++++++++++++++++++----------
>  1 file changed, 31 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 6193a0d..938095a 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -69,6 +69,9 @@ struct pltfm_imx_data {
>  	u32 scratchpad;
>  	enum imx_esdhc_type devtype;
>  	struct esdhc_platform_data boarddata;
> +	struct clk *clk_ipg;
> +	struct clk *clk_ahb;
> +	struct clk *clk_per;
>  };
>  
>  static struct platform_device_id imx_esdhc_devtype[] = {
> @@ -437,7 +440,6 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
>  	struct sdhci_pltfm_host *pltfm_host;
>  	struct sdhci_host *host;
>  	struct esdhc_platform_data *boarddata;
> -	struct clk *clk;
>  	int err;
>  	struct pltfm_imx_data *imx_data;
>  
> @@ -458,14 +460,29 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
>  	imx_data->devtype = pdev->id_entry->driver_data;
>  	pltfm_host->priv = imx_data;
>  
> -	clk = clk_get(mmc_dev(host->mmc), NULL);
> -	if (IS_ERR(clk)) {
> -		dev_err(mmc_dev(host->mmc), "clk err\n");
> -		err = PTR_ERR(clk);
> +	imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
> +	if (IS_ERR(imx_data->clk_ipg)) {
> +		err = PTR_ERR(imx_data->clk_ipg);
>  		goto err_clk_get;
>  	}
> -	clk_prepare_enable(clk);
> -	pltfm_host->clk = clk;
> +
> +	imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
> +	if (IS_ERR(imx_data->clk_ahb)) {
> +		err = PTR_ERR(imx_data->clk_ahb);
> +		goto err_clk_get;
> +	}
> +
> +	imx_data->clk_per = devm_clk_get(&pdev->dev, "per");
> +	if (IS_ERR(imx_data->clk_per)) {
> +		err = PTR_ERR(imx_data->clk_per);
> +		goto err_clk_get;
> +	}
> +
> +	pltfm_host->clk = imx_data->clk_per;
> +
> +	clk_prepare_enable(imx_data->clk_per);
> +	clk_prepare_enable(imx_data->clk_ipg);
> +	clk_prepare_enable(imx_data->clk_ahb);
>  
>  	if (!is_imx25_esdhc(imx_data))
>  		host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
> @@ -559,8 +576,9 @@ no_card_detect_irq:
>  		gpio_free(boarddata->wp_gpio);
>  no_card_detect_pin:
>  no_board_data:
> -	clk_disable_unprepare(pltfm_host->clk);
> -	clk_put(pltfm_host->clk);
> +	clk_disable_unprepare(imx_data->clk_per);
> +	clk_disable_unprepare(imx_data->clk_ipg);
> +	clk_disable_unprepare(imx_data->clk_ahb);
You forgot to clk_put them.
>  err_clk_get:
>  	kfree(imx_data);
>  err_imx_data:
> @@ -586,8 +604,10 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
>  		gpio_free(boarddata->cd_gpio);
>  	}
>  
> -	clk_disable_unprepare(pltfm_host->clk);
> -	clk_put(pltfm_host->clk);
> +	clk_disable_unprepare(imx_data->clk_per);
> +	clk_disable_unprepare(imx_data->clk_ipg);
> +	clk_disable_unprepare(imx_data->clk_ahb);
ditto

Thanks
Richard
> +
>  	kfree(imx_data);
>  
>  	sdhci_pltfm_free(pdev);
> -- 
> 1.7.9.5
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

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

* [PATCH 09/40] mmc sdhc i.MX: do not depend on grouped clocks
  2012-04-20  2:06   ` Richard Zhao
@ 2012-04-20  2:42     ` Richard Zhao
  0 siblings, 0 replies; 101+ messages in thread
From: Richard Zhao @ 2012-04-20  2:42 UTC (permalink / raw)
  To: linux-arm-kernel

> > -	clk_disable_unprepare(pltfm_host->clk);
> > -	clk_put(pltfm_host->clk);
> > +	clk_disable_unprepare(imx_data->clk_per);
> > +	clk_disable_unprepare(imx_data->clk_ipg);
> > +	clk_disable_unprepare(imx_data->clk_ahb);
> You forgot to clk_put them.
Sorry, I just realized you're using the new devm_clk_get.

Richard

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

* [PATCH 32/40] ARM i.MX5: implement clocks using common clock framework
  2012-04-10 13:45 ` [PATCH 32/40] ARM i.MX5: " Sascha Hauer
@ 2012-04-23  6:39   ` Richard Zhao
  2012-04-23  6:54     ` Sascha Hauer
  0 siblings, 1 reply; 101+ messages in thread
From: Richard Zhao @ 2012-04-23  6:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Sascha,

I saw some code removed from clk init code. For example:
mx51_clocks_init:
clk_enable(&cpu_clk);
clk_enable(&main_bus_clk);
/* move usb_phy_clk to 24MHz */
clk_set_parent(&usb_phy1_clk, &osc_clk);
/* set the usboh3_clk parent to pll2_sw_clk */
clk_set_parent(&usboh3_clk, &pll2_sw_clk);

mx53_clocks_init:
clk_set_parent(&uart_root_clk, &pll3_sw_clk);

Could you explain why you remove them?
If it has reasonable purpose, do you think it's better to put
them in a seperate patch? It makes everyone clear what it changed.
 
Thanks
Richard
 

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

* [PATCH 32/40] ARM i.MX5: implement clocks using common clock framework
  2012-04-23  6:39   ` Richard Zhao
@ 2012-04-23  6:54     ` Sascha Hauer
  2012-04-23  7:28       ` Richard Zhao
  0 siblings, 1 reply; 101+ messages in thread
From: Sascha Hauer @ 2012-04-23  6:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 23, 2012 at 02:39:50PM +0800, Richard Zhao wrote:
> Hello Sascha,
> 
> I saw some code removed from clk init code. For example:
> mx51_clocks_init:
> clk_enable(&cpu_clk);
> clk_enable(&main_bus_clk);
> /* move usb_phy_clk to 24MHz */
> clk_set_parent(&usb_phy1_clk, &osc_clk);
> /* set the usboh3_clk parent to pll2_sw_clk */
> clk_set_parent(&usboh3_clk, &pll2_sw_clk);
> 
> mx53_clocks_init:
> clk_set_parent(&uart_root_clk, &pll3_sw_clk);
> 
> Could you explain why you remove them?
> If it has reasonable purpose, do you think it's better to put
> them in a seperate patch? It makes everyone clear what it changed.

I can readd most of them, the setup simply got lost. BTW what is the
reason for reparenting the uart clock in the i.MX53 setup? This will
break early console support if the bootloader didn't setup the uart
clock in the same way already.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH 32/40] ARM i.MX5: implement clocks using common clock framework
  2012-04-23  6:54     ` Sascha Hauer
@ 2012-04-23  7:28       ` Richard Zhao
  0 siblings, 0 replies; 101+ messages in thread
From: Richard Zhao @ 2012-04-23  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 23, 2012 at 08:54:19AM +0200, Sascha Hauer wrote:
> On Mon, Apr 23, 2012 at 02:39:50PM +0800, Richard Zhao wrote:
> > Hello Sascha,
> > 
> > I saw some code removed from clk init code. For example:
> > mx51_clocks_init:
> > clk_enable(&cpu_clk);
> > clk_enable(&main_bus_clk);
> > /* move usb_phy_clk to 24MHz */
> > clk_set_parent(&usb_phy1_clk, &osc_clk);
> > /* set the usboh3_clk parent to pll2_sw_clk */
> > clk_set_parent(&usboh3_clk, &pll2_sw_clk);
> > 
> > mx53_clocks_init:
> > clk_set_parent(&uart_root_clk, &pll3_sw_clk);
> > 
> > Could you explain why you remove them?
> > If it has reasonable purpose, do you think it's better to put
> > them in a seperate patch? It makes everyone clear what it changed.
> 
> I can readd most of them, the setup simply got lost. BTW what is the
> reason for reparenting the uart clock in the i.MX53 setup? This will
> break early console support if the bootloader didn't setup the uart
> clock in the same way already.
I think you can remove the uart reparent. The original aim is to avoid
use the same pll as display/ipu. Dispaly requires precise clk which sometimes
change pll rate.

You might need also check other platforms wheter they lost setup code.

Thanks
Richard
> 
> Sascha
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

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

* [PATCH 01/40] clkdev: add clkname to struct clk_lookup
  2012-04-11  9:20             ` Russell King - ARM Linux
  2012-04-11  9:42               ` Sascha Hauer
@ 2012-04-24  2:17               ` Richard Zhao
  1 sibling, 0 replies; 101+ messages in thread
From: Richard Zhao @ 2012-04-24  2:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 10:20:34AM +0100, Russell King - ARM Linux wrote:
> On Wed, Apr 11, 2012 at 04:45:29PM +0800, Richard Zhao wrote:
> > On Wed, Apr 11, 2012 at 09:24:02AM +0100, Mark Brown wrote:
> > > On Wed, Apr 11, 2012 at 09:11:50AM +0800, Richard Zhao wrote:
> > > 
> > > > I don't like string loopup either. And after DT binding, we can use
> > > > phandler to refer clk.
> > > 
> > > No, this is only useful on platforms that use DT.  This is a generic
> > > Linux API so it needs to support architectures and platforms that don't
> > > use DT as it's vanishingly unlikely that DT will ever be adopted by all
> > > platforms.
> > My point is using string lookup as less as possible. When one register
> > a clk, one already got the struct clk* pointer and could use it in
> > struct lookup.
> > 
> > I'm worried about the performance as I saw string lookup is used more
> > and more often. In fast boot case, for example, even 5ms is important.
> 
> Yes, and you're not the only one who has that concern.  What this patch
> does is turn a pair of string compares through a table into that plus
> another set of string compares across all struct clk, which will make
> the lookup yet more expensive.
> 
> I see no reason why you'd register the cl_lookup structures before you
> know about which clks actually exist - and if they already exist, then
> you can already find the struct clk pointer and use that to register
> the proper return value for clk_get() via the clkdev APIs.
> 
> As I've said in the past, naming individual clock structures is the
> stupidest thing that anyone ever did and causes nothing but problems.
> We've seen that in the drivers with the abuse of clk_get(NULL, name)
> where people wanted to pass the name in via platform data.  We're
> starting to see the same thing here as well, except the problem people
> will see will be boot performance instead caused by multiple levels of
> string compares.
I just realized an important benefit of string lookup is we can define
machine specific lookups at its machine file.
Without it, we have to expose machine specific clk twice. For example,
cko1 is SoC internal clock name and is connected to sgtl5000 audio codec.
{"sgtl5000-dev-name", "function name"} lookup is board specific, and
{NULL, "cko1"} is SoC specific. We have to expose both of them.

Thanks
Richard
> 

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

end of thread, other threads:[~2012-04-24  2:17 UTC | newest]

Thread overview: 101+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-10 13:45 Convert i.MX architecture to generic clock framework Sascha Hauer
2012-04-10 13:45 ` [PATCH 01/40] clkdev: add clkname to struct clk_lookup Sascha Hauer
2012-04-10 14:30   ` Russell King - ARM Linux
2012-04-10 16:11     ` Sascha Hauer
2012-04-11  1:11       ` Richard Zhao
2012-04-11  8:24         ` Mark Brown
2012-04-11  8:45           ` Richard Zhao
2012-04-11  9:15             ` Mark Brown
2012-04-11  9:21               ` Russell King - ARM Linux
2012-04-11  9:32                 ` Mark Brown
2012-04-11  9:41                   ` Russell King - ARM Linux
2012-04-11 10:31                     ` Mark Brown
2012-04-11 11:43                       ` Russell King - ARM Linux
2012-04-12 16:33                         ` Mark Brown
2012-04-11  9:20             ` Russell King - ARM Linux
2012-04-11  9:42               ` Sascha Hauer
2012-04-11  9:47                 ` Russell King - ARM Linux
2012-04-13  3:33                   ` Viresh Kumar
2012-04-13  4:17                     ` Shawn Guo
2012-04-13  5:06                       ` Viresh Kumar
2012-04-13  5:22                         ` Shawn Guo
2012-04-13  8:59                           ` Mark Brown
2012-04-13  9:10                             ` Viresh Kumar
2012-04-13  9:17                               ` Richard Zhao
2012-04-13  9:26                                 ` Russell King - ARM Linux
2012-04-13  9:27                                   ` Viresh Kumar
2012-04-13  9:36                                     ` Russell King - ARM Linux
2012-04-13 10:02                                       ` Viresh Kumar
2012-04-13 10:08                                         ` Mark Brown
2012-04-13 10:20                                         ` Russell King - ARM Linux
2012-04-13 10:43                                           ` Viresh Kumar
2012-04-13 23:19                                           ` Turquette, Mike
2012-04-24  2:17               ` Richard Zhao
2012-04-10 13:45 ` [PATCH 02/40] clk: add a fixed factor clock Sascha Hauer
2012-04-17 10:15   ` Viresh Kumar
2012-04-19  3:48   ` Viresh Kumar
2012-04-19  6:16     ` Domenico Andreoli
2012-04-19  6:19       ` Viresh Kumar
2012-04-19  6:45     ` Sascha Hauer
2012-04-10 13:45 ` [PATCH 03/40] clk: declare clk_ops of basic clks in clk-provider.h Sascha Hauer
2012-04-10 13:45 ` [PATCH 04/40] dmaengine i.MX SDMA: do not depend on grouped clocks Sascha Hauer
2012-04-10 13:45 ` [PATCH 05/40] spi i.MX: " Sascha Hauer
2012-04-10 13:45 ` [PATCH 06/40] video imxfb: " Sascha Hauer
2012-04-10 13:45 ` [PATCH 07/40] net fec: " Sascha Hauer
2012-04-10 13:45 ` [PATCH 08/40] mmc mxcmmc: " Sascha Hauer
2012-04-10 13:45 ` [PATCH 09/40] mmc sdhc i.MX: " Sascha Hauer
2012-04-20  2:06   ` Richard Zhao
2012-04-20  2:42     ` Richard Zhao
2012-04-10 13:45 ` [PATCH 10/40] serial " Sascha Hauer
2012-04-10 13:45 ` [PATCH 11/40] mtd mxc_nand: prepare/unprepare clock Sascha Hauer
2012-04-10 13:45 ` [PATCH 12/40] USB ehci mxc: " Sascha Hauer
2012-04-10 13:45 ` [PATCH 13/40] w1 i.MX: " Sascha Hauer
2012-04-10 13:45 ` [PATCH 14/40] watchdog imx2: prepare clk before enabling it Sascha Hauer
2012-04-10 13:45 ` [PATCH 15/40] media mx3 camera: " Sascha Hauer
2012-04-10 13:45 ` [PATCH 16/40] dmaengine i.MX ipu: clk_prepare/unprepare clock Sascha Hauer
2012-04-10 13:45 ` [PATCH 17/40] ARM i.MX5: prepare gpc_dvfs_clk Sascha Hauer
2012-04-10 13:45 ` [PATCH 18/40] ARM i.MX: prepare for common clock framework Sascha Hauer
2012-04-10 13:45 ` [PATCH 19/40] ARM i.MX timer: request correct clock Sascha Hauer
2012-04-10 13:45 ` [PATCH 20/40] ARM i.MX: Add common clock support for pllv1 Sascha Hauer
2012-04-10 13:45 ` [PATCH 21/40] ARM i.MX: Add common clock support for pllv2 Sascha Hauer
2012-04-10 13:45 ` [PATCH 22/40] ARM: imx: add common clock support for pllv3 Sascha Hauer
2012-04-10 13:45 ` [PATCH 23/40] ARM i.MX: Add common clock support for 2bit gate Sascha Hauer
2012-04-19  7:00   ` Shawn Guo
2012-04-19  7:15     ` Richard Zhao
2012-04-19  7:26     ` Lei Wen
2012-04-19  7:52       ` Domenico Andreoli
2012-04-10 13:45 ` [PATCH 24/40] ARM: imx: add common clock support for pfd Sascha Hauer
2012-04-10 13:45 ` [PATCH 25/40] ARM: imx: add common clock support for clk busy Sascha Hauer
2012-04-10 18:59   ` Stephen Boyd
2012-04-11  6:53     ` Sascha Hauer
2012-04-11 22:21       ` Stephen Boyd
2012-04-12  3:30         ` Shawn Guo
2012-04-12  1:50   ` Richard Zhao
2012-04-12  2:44     ` Shawn Guo
2012-04-13  2:09   ` [PATCH] ARM: imx: remove clk_hw from clk_busy Shawn Guo
2012-04-13 14:34     ` Sascha Hauer
2012-04-10 13:45 ` [PATCH 26/40] ARM i.MX3: Make ccm base address a variable Sascha Hauer
2012-04-10 13:45 ` [PATCH 27/40] ARM i.MX25: implement clocks using common clock framework Sascha Hauer
2012-04-10 20:10   ` Roberto Nibali
2012-04-10 20:45     ` Fabio Estevam
2012-04-11  7:01       ` Roberto Nibali
2012-04-10 13:45 ` [PATCH 28/40] ARM i.MX1: " Sascha Hauer
2012-04-16 21:07   ` Sascha Hauer
2012-04-10 13:45 ` [PATCH 29/40] ARM i.MX21: " Sascha Hauer
2012-04-10 13:45 ` [PATCH 30/40] ARM i.MX27: " Sascha Hauer
2012-04-10 13:45 ` [PATCH 31/40] ARM i.MX31: " Sascha Hauer
2012-04-10 13:45 ` [PATCH 32/40] ARM i.MX5: " Sascha Hauer
2012-04-23  6:39   ` Richard Zhao
2012-04-23  6:54     ` Sascha Hauer
2012-04-23  7:28       ` Richard Zhao
2012-04-10 13:45 ` [PATCH 33/40] ARM i.MX35: " Sascha Hauer
2012-04-10 13:45 ` [PATCH 34/40] ARM: imx6: " Sascha Hauer
2012-04-18 11:33   ` Sascha Hauer
2012-04-19 13:56     ` Shawn Guo
2012-04-19 14:06       ` Sascha Hauer
2012-04-10 13:45 ` [PATCH 35/40] ARM i.MX: remove now unused old clock support Sascha Hauer
2012-04-10 13:45 ` [PATCH 36/40] ARM i.MX pllv1: move mxc_decode_pll to its only user Sascha Hauer
2012-04-10 13:45 ` [PATCH 37/40] ARM i.MX: remove unused legacy clock support Sascha Hauer
2012-04-10 13:45 ` [PATCH 38/40] USB gadget i.MX: fix clock handling Sascha Hauer
2012-04-10 13:45 ` [PATCH 39/40] USB ehci i.MX: Fix " Sascha Hauer
2012-04-10 13:45 ` [PATCH 40/40] ARM i.MX: Remove now unused struct clk argument from mxc_timer_init Sascha Hauer

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.