linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/16] tz1090: add clock components
@ 2014-12-01 23:19 James Hogan
  2014-12-01 23:19 ` [PATCH v2 01/16] clk: tz1090: add clock provider common code James Hogan
                   ` (16 more replies)
  0 siblings, 17 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:19 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan, Ian Campbell, Kumar Gala,
	Mark Rutland, Pawel Moll, Rob Herring

This patchset adds common clock framework support for the TZ1090 SoC.

Patch 1 adds common code to simplify TZ1090 clock providers.

Patches 2 to 6 add TZ1090 clock types, specifically:
* Gate banks (a register containing clock gate bits)
* Mux banks (a register containing clock mux bits)
* Clock deleters (delete up to 1023 out of every 1024 clocks)
* PLLs (True Circuits, but TZ1090 specific register interface)
* Divider clock (pretty basic divider, but specific to TZ1090)

Patches 7 to 14 add clock providers and DT bindings:
* Top level register  (TOP) clocks
* High end peripheral (HEP) clocks
* Peripheral (PERIP) clocks
* PowerDown Controller (PDC) clocks

Finally patch 15 defines most of the TZ1090 clocks in DT using these
clock providers, with a few placeholders for less interesting clocks
from more complex components, and patch 16 hooks up the Meta core clock
so that the precise frequency of the Meta clock source can be
determined. These are mostly for reference to give an idea how the clock
components are intended to be used, and I'll take this one through the
metag tree when the drivers/clk/ stuff is accepted.

Changes since v1:

Rework (the main change):
- Convert explicit DT representation of clock infrastructure using
  generic bindings for individual components to several TZ1090 specific
  bindings representing groups of TZ1090 clocks (thanks Heiko). This
  results in more lines of code overall, but it is nicer and more
  maintainable.
- Add common code for allocating and registering TZ1090 specific clock
  providers. Various tz1090_clk_register_*() helper functions are
  provided to conveniently register various low level TZ1090 clocks in a
  clock provider from static initialisation data, which can be
  initialised statically using provided macros.
- Drop DT bindings for TZ1090 gate banks, mux banks, deleters, dividers
  and PLLs as they will be instantiated directly from a larger clock
  provider rather than individually from DT.
- Switch back to using clk_divider::width rather than clk_divider::mask.
  Mask was only added to make it easier to be exposed in a DT binding,
  which is no longer required.
- Add DT bindings and clock providers for TZ1090 top level register
  clocks (TOP), high end peripheral clocks (HEP), peripheral (PERIP)
  clocks, and powerdown controller clocks (PDC).
- Add headers in <dt-bindings/clock/> to enumerate provided clocks.
- Move divider specific flags (policy) to clock providers as dividers
  will be instantiated by a provider rather than directly from DT.

Functional changes and corrections:
- Tweak various clock names. A couple were wrong, some had the slightly
  redundant text "clk" in them, and others were output clocks so were
  better named without the "_en" which the output of clock gates tend to
  be called.
- Add TOP_CLKEN register to top clocks, which gates system clock to PDC.
- Combine unrepresented AFE block clocks into single fixed-clock
  placeholder.

Other cleanups and refactorings:
- Split out wrapped (meta exclusive locked) divider driver from PDC
  clock driver to clk-tz1090-divider.c.
- Change the PDC clocks DT bindings and driver to conceptually represent
  all clocks provided by the PDC in TZ1090 rather than the same generic
  arrangement of clocks as the PDC in TZ1090, since the driver will use
  the common TZ1090 specific clock provider helpers to provide specific
  clocks.
- Change PDC clocks compatible string from "img,tz1090-pdc-clock" to
  "img,tz1090-pdc-clocks" to match the intended purpose.
- Add clock-names as required property to PDC clocks DT binding as used
  by common TZ1090 clock provider code.
- Mention standard clock-indices and clock-output-names in PDC clocks DT
  binding as optional properties for when the clocks may be used by
  other clock providers and should match the names used in the driver.
- Split out use of Meta core clock into separate patch 16.
- Renamed function prefixes from clk_tz1090_ to tz1090_clk_ for
  consistency with the rest.
- Tweak ascii art clock diagrams a little.

Cc: Mike Turquette <mturquette@linaro.org>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Heiko Stuebner <heiko@sntech.de>
Cc: linux-metag@vger.kernel.org
Cc: devicetree@vger.kernel.org

James Hogan (16):
  clk: tz1090: add clock provider common code
  clk: tz1090: add gate bank clock driver
  clk: tz1090: add mux bank clock driver
  clk: tz1090: add deleter clock driver
  clk: tz1090: add divider clock driver
  clk: tz1090: add PLL clock driver
  dt: binding: add binding for TZ1090 PDC clocks
  clk: tz1090: add PDC clock provider driver
  dt: binding: add binding for TZ1090 TOP clocks
  clk: tz1090: add TOP clock provider driver
  dt: binding: add binding for TZ1090 HEP clocks
  clk: tz1090: add HEP clock provider driver
  dt: binding: add binding for TZ1090 PERIP clocks
  clk: tz1090: add PERIP clock provider driver
  metag: tz1090: add TZ1090 clocks to device tree
  metag: tz1090: connect Meta core clock

 .../bindings/clock/img,tz1090-hep-cru.txt          |  53 +++
 .../bindings/clock/img,tz1090-pdc-clocks.txt       |  59 ++++
 .../bindings/clock/img,tz1090-perip-cru.txt        |  49 +++
 .../bindings/clock/img,tz1090-top-clocks.txt       |  68 ++++
 arch/metag/Kconfig.soc                             |   1 +
 arch/metag/boot/dts/tz1090.dtsi                    |   4 +
 arch/metag/boot/dts/tz1090_clk.dtsi                | 143 ++++++++
 drivers/clk/Makefile                               |   1 +
 drivers/clk/tz1090/Makefile                        |  13 +
 drivers/clk/tz1090/clk-tz1090-deleter.c            | 132 ++++++++
 drivers/clk/tz1090/clk-tz1090-divider.c            | 151 +++++++++
 drivers/clk/tz1090/clk-tz1090-gate-bank.c          | 149 +++++++++
 drivers/clk/tz1090/clk-tz1090-hep.c                |  46 +++
 drivers/clk/tz1090/clk-tz1090-mux-bank.c           | 139 ++++++++
 drivers/clk/tz1090/clk-tz1090-pdc.c                |  52 +++
 drivers/clk/tz1090/clk-tz1090-perip.c              |  57 ++++
 drivers/clk/tz1090/clk-tz1090-pll.c                | 276 ++++++++++++++++
 drivers/clk/tz1090/clk-tz1090-top.c                | 364 +++++++++++++++++++++
 drivers/clk/tz1090/clk.c                           |  89 +++++
 drivers/clk/tz1090/clk.h                           | 254 ++++++++++++++
 include/dt-bindings/clock/tz1090-hep.h             |  19 ++
 include/dt-bindings/clock/tz1090-pdc.h             |  18 +
 include/dt-bindings/clock/tz1090-perip.h           |  30 ++
 include/dt-bindings/clock/tz1090-top.h             | 118 +++++++
 24 files changed, 2285 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-hep-cru.txt
 create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-pdc-clocks.txt
 create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-perip-cru.txt
 create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-top-clocks.txt
 create mode 100644 arch/metag/boot/dts/tz1090_clk.dtsi
 create mode 100644 drivers/clk/tz1090/Makefile
 create mode 100644 drivers/clk/tz1090/clk-tz1090-deleter.c
 create mode 100644 drivers/clk/tz1090/clk-tz1090-divider.c
 create mode 100644 drivers/clk/tz1090/clk-tz1090-gate-bank.c
 create mode 100644 drivers/clk/tz1090/clk-tz1090-hep.c
 create mode 100644 drivers/clk/tz1090/clk-tz1090-mux-bank.c
 create mode 100644 drivers/clk/tz1090/clk-tz1090-pdc.c
 create mode 100644 drivers/clk/tz1090/clk-tz1090-perip.c
 create mode 100644 drivers/clk/tz1090/clk-tz1090-pll.c
 create mode 100644 drivers/clk/tz1090/clk-tz1090-top.c
 create mode 100644 drivers/clk/tz1090/clk.c
 create mode 100644 drivers/clk/tz1090/clk.h
 create mode 100644 include/dt-bindings/clock/tz1090-hep.h
 create mode 100644 include/dt-bindings/clock/tz1090-pdc.h
 create mode 100644 include/dt-bindings/clock/tz1090-perip.h
 create mode 100644 include/dt-bindings/clock/tz1090-top.h

-- 
2.0.4


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

* [PATCH v2 01/16] clk: tz1090: add clock provider common code
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
@ 2014-12-01 23:19 ` James Hogan
  2014-12-01 23:19 ` [PATCH v2 02/16] clk: tz1090: add gate bank clock driver James Hogan
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:19 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan

Add some common code for the TZ1090 SoC to allocate and register onecell
based clock providers. These have some memory mapped registers and are
instantiated from DT.

Also provided is a tz1090_clk_xlate() function to help handle external
clocks from other clock providers by processing the internal clock
names.

Parent clocks from other providers can be specified as "@label" where
label is the name of an input clock provided by the clock-names DT
property. tz1090_clk_xlate() translates these strings by finding the
actual name of the parent clock. It first uses
of_property_match_string() to find the index of the matching parent
clock, and then of_clk_get_parent_name() to get its name. Since
of_clk_get_parent_name() uses the parent clock node's clock-output-names
property, this should be specified for any complex input clocks which
use this mechanism.

Clock strings which don't start with '@' are used directly as the parent
clock name. This is intended for other clocks within the clock provider.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: linux-metag@vger.kernel.org
---
New patch in v2
---
 drivers/clk/Makefile        |  1 +
 drivers/clk/tz1090/Makefile |  2 +
 drivers/clk/tz1090/clk.c    | 89 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/tz1090/clk.h    | 37 +++++++++++++++++++
 4 files changed, 129 insertions(+)
 create mode 100644 drivers/clk/tz1090/Makefile
 create mode 100644 drivers/clk/tz1090/clk.c
 create mode 100644 drivers/clk/tz1090/clk.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5fba5b..ca486ed 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_PLAT_SPEAR)		+= spear/
 obj-$(CONFIG_ARCH_STI)			+= st/
 obj-$(CONFIG_ARCH_SUNXI)		+= sunxi/
 obj-$(CONFIG_ARCH_TEGRA)		+= tegra/
+obj-$(CONFIG_SOC_TZ1090)		+= tz1090/
 obj-$(CONFIG_ARCH_OMAP2PLUS)		+= ti/
 obj-$(CONFIG_ARCH_U8500)		+= ux500/
 obj-$(CONFIG_COMMON_CLK_VERSATILE)	+= versatile/
diff --git a/drivers/clk/tz1090/Makefile b/drivers/clk/tz1090/Makefile
new file mode 100644
index 0000000..a2ace14
--- /dev/null
+++ b/drivers/clk/tz1090/Makefile
@@ -0,0 +1,2 @@
+# Makefile for TZ1090-specific clocks
+obj-y		+= clk.o
diff --git a/drivers/clk/tz1090/clk.c b/drivers/clk/tz1090/clk.c
new file mode 100644
index 0000000..5f4e8f28
--- /dev/null
+++ b/drivers/clk/tz1090/clk.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ * Copyright (C) 2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ *
+ * TZ1090 Clocks
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+struct tz1090_clk_provider *tz1090_clk_alloc_provider(struct device_node *node,
+						      unsigned int num_clks)
+{
+	struct tz1090_clk_provider *p;
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return p;
+
+	p->clk_data.clks = kcalloc(num_clks, sizeof(struct clk *), GFP_KERNEL);
+	if (!p->clk_data.clks)
+		goto free_provider;
+	p->clk_data.clk_num = num_clks;
+	p->node = node;
+	p->base = of_iomap(node, 0);
+	if (!p->base) {
+		pr_err("%s: Failed to map clock provider registers\n",
+		       node->full_name);
+		goto free_clks;
+	}
+
+	return p;
+
+free_clks:
+	kfree(p->clk_data.clks);
+free_provider:
+	kfree(p);
+	return NULL;
+}
+
+const char *tz1090_clk_xlate(struct tz1090_clk_provider *p,
+			     const char *clk_name)
+{
+	/*
+	 * If clock name begins with @, the rest refers to an external clock.
+	 *
+	 * Look for the index of the parent clock with a matching label in
+	 * clock-names. If found, find the name of the specified parent clock.
+	 *
+	 * If not found, we leave it unchanged. The @ at the beginning should
+	 * ensure it doesn't accidentally match a real clock.
+	 */
+	if (*clk_name == '@') {
+		const char *clk_label = clk_name + 1;
+		int idx = of_property_match_string(p->node, "clock-names",
+						   clk_label);
+		if (idx >= 0) {
+			clk_name = of_clk_get_parent_name(p->node, idx);
+			pr_debug("%s: Parent clock '%s' found as '%s'\n",
+				 p->node->full_name, clk_label, clk_name);
+		} else {
+			pr_err("%s: No parent clock '%s' found\n",
+			       p->node->full_name, clk_label);
+		}
+	}
+
+	return clk_name;
+}
+
+void tz1090_clk_register_provider(struct tz1090_clk_provider *p)
+{
+	unsigned int i;
+
+	for (i = 0; i < p->clk_data.clk_num; i++)
+		if (IS_ERR(p->clk_data.clks[i]))
+			pr_warn("%s: Failed to register clock %d: %ld\n",
+				p->node->full_name, i,
+				PTR_ERR(p->clk_data.clks[i]));
+
+	of_clk_add_provider(p->node, of_clk_src_onecell_get, &p->clk_data);
+}
diff --git a/drivers/clk/tz1090/clk.h b/drivers/clk/tz1090/clk.h
new file mode 100644
index 0000000..c20e7b4
--- /dev/null
+++ b/drivers/clk/tz1090/clk.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ *
+ * TZ1090 Clocks
+ */
+
+#ifndef CLK_TZ1090_CLK_H
+#define CLK_TZ1090_CLK_H
+
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+
+/* Generic TZ1090 clock provider */
+
+/**
+ * struct tz1090_clk_provider - Clock provider data.
+ * @node:	Device tree node for the clock provider.
+ * @base:	IO remapped base address.
+ * @clk_data:	Standard onecell clock data including list of clocks.
+ */
+struct tz1090_clk_provider {
+	struct device_node		*node;
+	void __iomem			*base;
+	struct clk_onecell_data		clk_data;
+};
+
+struct tz1090_clk_provider *tz1090_clk_alloc_provider(struct device_node *node,
+						      unsigned int num_clks);
+const char *tz1090_clk_xlate(struct tz1090_clk_provider *p,
+			     const char *clk_name);
+void tz1090_clk_register_provider(struct tz1090_clk_provider *p);
+
+#endif
-- 
2.0.4


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

* [PATCH v2 02/16] clk: tz1090: add gate bank clock driver
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
  2014-12-01 23:19 ` [PATCH v2 01/16] clk: tz1090: add clock provider common code James Hogan
@ 2014-12-01 23:19 ` James Hogan
  2014-12-01 23:19 ` [PATCH v2 03/16] clk: tz1090: add mux " James Hogan
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:19 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan

Add a clock driver for banks of clock gates in the TZ1090 SoC. A single
32 bit register controls up to 32 separate clock gates. The generic
clock gate clock operations are wrapped in order to acquire and release
the Meta global exclusive lock (__global_lock2) to ensure atomicity with
other non-Linux cores and threads which may need to control some of the
clocks.

The tz1090_clk_register_gate_bank() helper function can be used to
register a gate bank from static initialisation data. Macros are
provided in tz1090/clk.h to aid the creation of this data, for example:

GATE_BANK(tz1090_perip_clken, 0, PERIP_CLKEN,
        /*   bit in      out */
        GATE( 0, "@sys", "sys_scb0")
        GATE( 1, "@sys", "sys_scb1")
        GATE( 2, "@sys", "sys_scb2")
        ...
);
...
clk_register_gate_bank(p, &tz1090_perip_clken);

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: linux-metag@vger.kernel.org
---
Changes since v1 (patch 6):
- Renamed function prefixes from clk_tz1090_ to tz1090_clk_ for
  consistency with the rest.
- Drop DT binding as it will be instantiated directly from a provider.
- Add tz1090_clk_register_gate_bank() to conveniently register a bank of
  gates in a clock provider from static initilisation data.
- Extend tz1090/clk.h interface for easy static initialisation with
  macros.
---
 drivers/clk/tz1090/Makefile               |   2 +
 drivers/clk/tz1090/clk-tz1090-gate-bank.c | 149 ++++++++++++++++++++++++++++++
 drivers/clk/tz1090/clk.h                  |  49 ++++++++++
 3 files changed, 200 insertions(+)
 create mode 100644 drivers/clk/tz1090/clk-tz1090-gate-bank.c

diff --git a/drivers/clk/tz1090/Makefile b/drivers/clk/tz1090/Makefile
index a2ace14..ab88f53 100644
--- a/drivers/clk/tz1090/Makefile
+++ b/drivers/clk/tz1090/Makefile
@@ -1,2 +1,4 @@
 # Makefile for TZ1090-specific clocks
 obj-y		+= clk.o
+
+obj-y		+= clk-tz1090-gate-bank.o
diff --git a/drivers/clk/tz1090/clk-tz1090-gate-bank.c b/drivers/clk/tz1090/clk-tz1090-gate-bank.c
new file mode 100644
index 0000000..5834afd
--- /dev/null
+++ b/drivers/clk/tz1090/clk-tz1090-gate-bank.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ *
+ * TZ1090 Clock gate bank
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <asm/global_lock.h>
+
+#include "clk.h"
+
+/**
+ * struct tz1090_clk_gate_priv - tz1090 gating clock
+ *
+ * @mux:	the parent class
+ * @ops:	pointer to clk_ops of parent class
+ *
+ * Clock which can gate its output. Extends basic mux by using a global
+ * exclusive lock when read-modify-writing the mux field so that multiple
+ * threads/cores can use different fields in the same register.
+ */
+struct tz1090_clk_gate_priv {
+	struct clk_gate		gate;
+	const struct clk_ops	*ops;
+};
+
+static inline struct tz1090_clk_gate_priv *to_tz1090_clk_gate(struct clk_hw *hw)
+{
+	struct clk_gate *gate = container_of(hw, struct clk_gate, hw);
+
+	return container_of(gate, struct tz1090_clk_gate_priv, gate);
+}
+
+/* Acquire exclusive lock since other cores may access the same register */
+static int tz1090_clk_gate_enable(struct clk_hw *hw)
+{
+	struct tz1090_clk_gate_priv *gate = to_tz1090_clk_gate(hw);
+	int ret;
+	unsigned long flags;
+
+	__global_lock2(flags);
+	ret = gate->ops->enable(&gate->gate.hw);
+	__global_unlock2(flags);
+
+	return ret;
+}
+
+/* Acquire exclusive lock since other cores may access the same register */
+static void tz1090_clk_gate_disable(struct clk_hw *hw)
+{
+	struct tz1090_clk_gate_priv *gate = to_tz1090_clk_gate(hw);
+	unsigned long flags;
+
+	__global_lock2(flags);
+	gate->ops->disable(&gate->gate.hw);
+	__global_unlock2(flags);
+}
+
+static int tz1090_clk_gate_is_enabled(struct clk_hw *hw)
+{
+	struct tz1090_clk_gate_priv *gate = to_tz1090_clk_gate(hw);
+
+	return gate->ops->is_enabled(&gate->gate.hw);
+}
+
+static const struct clk_ops tz1090_clk_gate_ops = {
+	.enable = tz1090_clk_gate_enable,
+	.disable = tz1090_clk_gate_disable,
+	.is_enabled = tz1090_clk_gate_is_enabled,
+};
+
+/**
+ * __register_gate() - register a TZ1090 gate clock with clock framework.
+ * @name: name of this clock
+ * @parent_name: name of this clock's parent
+ * @flags: framework-specific flags for this clock
+ * @reg: register address to control gating of this clock
+ * @bit_idx: which bit in the register controls gating of this clock
+ * @clk_gate_flags: gate-specific flags for this clock
+ */
+static struct clk *__init __register_gate(const char *name,
+					  const char *parent_name,
+					  unsigned long flags,
+					  void __iomem *reg,
+					  u8 bit_idx,
+					  u8 clk_gate_flags)
+{
+	struct tz1090_clk_gate_priv *gate;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	/* allocate the gate */
+	gate = kzalloc(sizeof(struct tz1090_clk_gate_priv), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &tz1090_clk_gate_ops;
+	init.flags = flags | CLK_IS_BASIC;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	/* struct clk_gate assignments */
+	gate->gate.reg = reg;
+	gate->gate.bit_idx = bit_idx;
+	gate->gate.flags = clk_gate_flags;
+	gate->gate.hw.init = &init;
+
+	/* struct tz1090_clk_gate_priv assignments */
+	gate->ops = &clk_gate_ops;
+
+	clk = clk_register(NULL, &gate->gate.hw);
+
+	if (IS_ERR(clk))
+		kfree(gate);
+
+	return clk;
+}
+
+/**
+ * tz1090_clk_register_gate_bank() - Register bank of gates with a provider.
+ * @p:		TZ1090 clock provider.
+ * @bank:	Data describing gate bank.
+ */
+void __init tz1090_clk_register_gate_bank(struct tz1090_clk_provider *p,
+					const struct tz1090_clk_gate_bank *bank)
+{
+	const struct tz1090_clk_gate *gate;
+	struct clk *clk;
+	unsigned int id = bank->id_base;
+
+	for (gate = bank->gates; gate->name; ++gate, ++id) {
+		clk = __register_gate(tz1090_clk_xlate(p, gate->name),
+				      tz1090_clk_xlate(p, gate->parent),
+				      CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT,
+				      p->base + bank->reg_base, gate->shift, 0);
+		p->clk_data.clks[id] = clk;
+	}
+}
diff --git a/drivers/clk/tz1090/clk.h b/drivers/clk/tz1090/clk.h
index c20e7b4..06274b7 100644
--- a/drivers/clk/tz1090/clk.h
+++ b/drivers/clk/tz1090/clk.h
@@ -34,4 +34,53 @@ const char *tz1090_clk_xlate(struct tz1090_clk_provider *p,
 			     const char *clk_name);
 void tz1090_clk_register_provider(struct tz1090_clk_provider *p);
 
+
+/* Clock gate banks */
+
+/**
+ * struct tz1090_clk_gate - Describes an individual gate in a bank.
+ * @shift:	Shift of bit controlling gate within the bank control register.
+ * @name:	Name of gated clock to provide.
+ * @parent:	Name of parent/source clock.
+ */
+struct tz1090_clk_gate {
+	unsigned int	shift;
+	const char	*name;
+	const char	*parent;
+};
+
+/**
+ * struct tz1090_clk_gate_bank - Describes a gate bank.
+ * @id_base:	Base id of bank in provider.
+ *		Individual gates get the id id_base + index in gates array.
+ * @reg_base:	Offset of gate bank register in the MMIO region.
+ * @gates:	Pointer to array of gates in the bank, terminated by one with a
+ *		NULL name field.
+ */
+struct tz1090_clk_gate_bank {
+	unsigned int			id_base;
+	unsigned long			reg_base;
+	const struct tz1090_clk_gate	*gates;
+};
+
+#define GATE(_shift, _parent, _name)					\
+	{								\
+		.shift		= (_shift),				\
+		.name		= (_name),				\
+		.parent		= (_parent),				\
+	},
+
+#define GATE_BANK(_name, _id, _reg, _gates)				\
+	static const struct tz1090_clk_gate_bank _name __initconst = {	\
+		.id_base	= (_id),				\
+		.reg_base	= (_reg),				\
+		.gates		= (const struct tz1090_clk_gate[]) {	\
+			_gates						\
+			{ .name	= NULL }				\
+		},							\
+	}
+
+void tz1090_clk_register_gate_bank(struct tz1090_clk_provider *p,
+				   const struct tz1090_clk_gate_bank *bank);
+
 #endif
-- 
2.0.4


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

* [PATCH v2 03/16] clk: tz1090: add mux bank clock driver
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
  2014-12-01 23:19 ` [PATCH v2 01/16] clk: tz1090: add clock provider common code James Hogan
  2014-12-01 23:19 ` [PATCH v2 02/16] clk: tz1090: add gate bank clock driver James Hogan
@ 2014-12-01 23:19 ` James Hogan
  2014-12-01 23:19 ` [PATCH v2 04/16] clk: tz1090: add deleter " James Hogan
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:19 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan

Add a clock driver for banks of clock muxes in the TZ1090 SoC. A single
32 bit register controls up to 32 separate clock muxes. The generic
clock mux clock operations are wrapped in order to acquire and release
the Meta global exclusive lock (__global_lock2) to ensure atomicity with
other non-Linux cores and threads which may need to control some of the
clocks.

The tz1090_clk_register_mux_bank() helper function can be used to
register a mux bank from static initialisation data. Macros are provided
in tz1090/clk.h to aid the creation of this data, for example:

MUX_BANK(tz1090_top_clkswitch, CLK_TOP_CLKSWITCH_BASE, TOP_CLKSWITCH,
	/*  bit in[0]    in[1]            out */
	MUX( 0, "@xtal1" "@xtal2",        "sys_sw")
	MUX( 1, "@xtal1" "sys_div",       "sys_x2_undeleted")
	MUX( 2, "@xtal1" "@afe_progdiv1", "out0_sw0")
	...
);
...
tz1090_clk_register_mux_bank(p, &tz1090_top_clkswitch);

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: linux-metag@vger.kernel.org
---
Changes since v1 (patch 8):
- Renamed function prefixes from clk_tz1090_ to tz1090_clk_ for
  consistency with the rest.
- Drop DT binding as it will be instantiated directly from a provider.
- Add tz1090_clk_register_mux_bank() to conveniently register a bank of
  gates in a clock provider from static initilisation data.
- Extend tz1090/clk.h interface for easy static initialisation with
  macros.
---
 drivers/clk/tz1090/Makefile              |   1 +
 drivers/clk/tz1090/clk-tz1090-mux-bank.c | 139 +++++++++++++++++++++++++++++++
 drivers/clk/tz1090/clk.h                 |  52 ++++++++++++
 3 files changed, 192 insertions(+)
 create mode 100644 drivers/clk/tz1090/clk-tz1090-mux-bank.c

diff --git a/drivers/clk/tz1090/Makefile b/drivers/clk/tz1090/Makefile
index ab88f53..d44acac 100644
--- a/drivers/clk/tz1090/Makefile
+++ b/drivers/clk/tz1090/Makefile
@@ -2,3 +2,4 @@
 obj-y		+= clk.o
 
 obj-y		+= clk-tz1090-gate-bank.o
+obj-y		+= clk-tz1090-mux-bank.o
diff --git a/drivers/clk/tz1090/clk-tz1090-mux-bank.c b/drivers/clk/tz1090/clk-tz1090-mux-bank.c
new file mode 100644
index 0000000..0c7732d
--- /dev/null
+++ b/drivers/clk/tz1090/clk-tz1090-mux-bank.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ *
+ * TZ1090 Clock mux bank
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <asm/global_lock.h>
+
+#include "clk.h"
+
+/**
+ * struct tz1090_clk_mux_priv - tz1090 multiplexer clock
+ *
+ * @mux:	the parent class
+ * @ops:	pointer to clk_ops of parent class
+ *
+ * Clock with multiple selectable parents. Extends basic mux by using a global
+ * exclusive lock when read-modify-writing the mux field so that multiple
+ * threads/cores can use different fields in the same register.
+ */
+struct tz1090_clk_mux_priv {
+	struct clk_mux		mux;
+	const struct clk_ops	*ops;
+};
+
+static inline struct tz1090_clk_mux_priv *to_tz1090_clk_mux(struct clk_hw *hw)
+{
+	struct clk_mux *mux = container_of(hw, struct clk_mux, hw);
+
+	return container_of(mux, struct tz1090_clk_mux_priv, mux);
+}
+
+static u8 tz1090_clk_mux_get_parent(struct clk_hw *hw)
+{
+	struct tz1090_clk_mux_priv *mux = to_tz1090_clk_mux(hw);
+
+	return mux->ops->get_parent(&mux->mux.hw);
+}
+
+/* Acquire exclusive lock since other cores may access the same register */
+static int tz1090_clk_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct tz1090_clk_mux_priv *mux = to_tz1090_clk_mux(hw);
+	int ret;
+	unsigned long flags;
+
+	__global_lock2(flags);
+	ret = mux->ops->set_parent(&mux->mux.hw, index);
+	__global_unlock2(flags);
+
+	return ret;
+}
+
+static long tz1090_clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long *prate,
+				     struct clk **best_parent)
+{
+	struct tz1090_clk_mux_priv *mux = to_tz1090_clk_mux(hw);
+
+	return mux->ops->determine_rate(&mux->mux.hw, rate, prate, best_parent);
+}
+
+static const struct clk_ops tz1090_clk_mux_ops = {
+	.get_parent = tz1090_clk_mux_get_parent,
+	.set_parent = tz1090_clk_mux_set_parent,
+	.determine_rate = tz1090_clk_mux_determine_rate,
+};
+
+static struct clk *__init __register_mux(const char *name,
+					 const char **parent_names,
+					 unsigned long flags, void __iomem *reg,
+					 u8 shift, u8 clk_mux_flags)
+{
+	struct tz1090_clk_mux_priv *mux;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	/* allocate the mux */
+	mux = kzalloc(sizeof(struct tz1090_clk_mux_priv), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &tz1090_clk_mux_ops;
+	init.flags = flags | CLK_IS_BASIC;
+	init.parent_names = parent_names;
+	init.num_parents = 2;
+
+	/* struct clk_mux assignments */
+	mux->mux.reg = reg;
+	mux->mux.shift = shift;
+	mux->mux.mask = 0x1;
+	mux->mux.flags = clk_mux_flags;
+	mux->mux.hw.init = &init;
+
+	/* struct tz1090_clk_mux_priv assignments */
+	mux->ops = &clk_mux_ops;
+
+	clk = clk_register(NULL, &mux->mux.hw);
+
+	if (IS_ERR(clk))
+		kfree(mux);
+
+	return clk;
+}
+
+/**
+ * tz1090_clk_register_mux_bank() - Register bank of muxes with a provider.
+ * @p:		TZ1090 clock provider.
+ * @bank:	Data describing mux bank.
+ */
+void __init tz1090_clk_register_mux_bank(struct tz1090_clk_provider *p,
+					 const struct tz1090_clk_mux_bank *bank)
+{
+	const struct tz1090_clk_mux *mux;
+	struct clk *clk;
+	unsigned int id = bank->id_base;
+	const char *parents[2];
+
+	for (mux = bank->muxes; mux->name; ++mux, ++id) {
+		parents[0] = tz1090_clk_xlate(p, mux->parents[0]);
+		parents[1] = tz1090_clk_xlate(p, mux->parents[1]);
+		clk = __register_mux(tz1090_clk_xlate(p, mux->name), parents,
+				     CLK_SET_RATE_PARENT,
+				     p->base + bank->reg_base, mux->shift, 0);
+		p->clk_data.clks[id] = clk;
+	}
+}
diff --git a/drivers/clk/tz1090/clk.h b/drivers/clk/tz1090/clk.h
index 06274b7..c9fe6ca 100644
--- a/drivers/clk/tz1090/clk.h
+++ b/drivers/clk/tz1090/clk.h
@@ -83,4 +83,56 @@ struct tz1090_clk_gate_bank {
 void tz1090_clk_register_gate_bank(struct tz1090_clk_provider *p,
 				   const struct tz1090_clk_gate_bank *bank);
 
+
+/* Clock mux banks */
+
+/**
+ * struct tz1090_clk_mux - Describes an individual mux in a bank.
+ * @shift:	Shift of bit controlling mux within the bank control register.
+ * @name:	Name of muxed clock to provide.
+ * @parents:	Name of two parent/source clocks for when the bit is 0 and 1.
+ */
+struct tz1090_clk_mux {
+	unsigned int	shift;
+	const char	*name;
+	const char	*parents[2];
+};
+
+/**
+ * struct tz1090_clk_mux_bank - Describes a mux bank.
+ * @id_base:	Base id of bank in provider.
+ *		Individual muxes get the id id_base + index in muxes array.
+ * @reg_base:	Offset of mux bank register in the MMIO region.
+ * @muxes:	Pointer to array of muxes in the bank, terminated by one with a
+ *		NULL name field.
+ */
+struct tz1090_clk_mux_bank {
+	unsigned int			id_base;
+	unsigned long			reg_base;
+	const struct tz1090_clk_mux	*muxes;
+};
+
+#define MUX(_shift, _parent0, _parent1, _name)				\
+	{								\
+		.shift		= (_shift),				\
+		.name		= (_name),				\
+		.parents	= {					\
+			_parent0,					\
+			_parent1					\
+		},							\
+	},
+
+#define MUX_BANK(_name, _id, _reg, _muxes)				\
+	static const struct tz1090_clk_mux_bank _name __initconst = {	\
+		.id_base	= (_id),				\
+		.reg_base	= (_reg),				\
+		.muxes		= (const struct tz1090_clk_mux[]) {	\
+			_muxes						\
+			{ .name	= NULL }				\
+		},							\
+	}
+
+void tz1090_clk_register_mux_bank(struct tz1090_clk_provider *p,
+				  const struct tz1090_clk_mux_bank *bank);
+
 #endif
-- 
2.0.4


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

* [PATCH v2 04/16] clk: tz1090: add deleter clock driver
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (2 preceding siblings ...)
  2014-12-01 23:19 ` [PATCH v2 03/16] clk: tz1090: add mux " James Hogan
@ 2014-12-01 23:19 ` James Hogan
  2014-12-01 23:19 ` [PATCH v2 05/16] clk: tz1090: add divider " James Hogan
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:19 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan

Add a clock driver for clock deleters in the TZ1090 SoC, which delete up
to 1023 out of every 1024 clock pulses. There are 4 of these in TZ1090,
for the system clock, the Meta core clock, and one for each UCC.

The tz1090_clk_register_deleters() helper function can be used to
register a set of deleters from static initialisation data. A DEL()
macro is provided in tz1090/clk.h to aid the creation of this data, for
example:

static const struct tz1090_clk_deleter deleters[] __initconst = {
	DEL(CLK_TOP_SYS, "sys_undeleted", "sys", TOP_CLKDELETE),
	...
};
...
tz1090_clk_register_deleters(p, deleters, ARRAY_SIZE(deleters));

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: linux-metag@vger.kernel.org
---
Changes since v1 (patch 10):
- Renamed function prefixes from clk_tz1090_ to tz1090_clk_ for
  consistency with the rest.
- Drop DT binding as it will be instantiated directly from a provider.
- Add tz1090_clk_register_deleters() to conveniently register a set of
  deleters in a clock provider from static initilisation data.
- Extend tz1090/clk.h interface for easy static initialisation with
  macros.
---
 drivers/clk/tz1090/Makefile             |   1 +
 drivers/clk/tz1090/clk-tz1090-deleter.c | 132 ++++++++++++++++++++++++++++++++
 drivers/clk/tz1090/clk.h                |  31 ++++++++
 3 files changed, 164 insertions(+)
 create mode 100644 drivers/clk/tz1090/clk-tz1090-deleter.c

diff --git a/drivers/clk/tz1090/Makefile b/drivers/clk/tz1090/Makefile
index d44acac..39c29ac 100644
--- a/drivers/clk/tz1090/Makefile
+++ b/drivers/clk/tz1090/Makefile
@@ -1,5 +1,6 @@
 # Makefile for TZ1090-specific clocks
 obj-y		+= clk.o
 
+obj-y		+= clk-tz1090-deleter.o
 obj-y		+= clk-tz1090-gate-bank.o
 obj-y		+= clk-tz1090-mux-bank.o
diff --git a/drivers/clk/tz1090/clk-tz1090-deleter.c b/drivers/clk/tz1090/clk-tz1090-deleter.c
new file mode 100644
index 0000000..9ec604d
--- /dev/null
+++ b/drivers/clk/tz1090/clk-tz1090-deleter.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2012-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ *
+ * Clock deleter in TZ1090
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+/**
+ * struct tz1090_clk_deleter_priv - Clock deleter
+ *
+ * @hw:		handle between common and hardware-specific interfaces
+ * @reg:	delete register
+ * @period:	cycle period
+ * @mask:	bit mask of delete field
+ * @shift:	start bit of delete field
+ *
+ * Deleter in TZ1090, allowing up to period-1 out of each period cycles to be
+ * deleted.
+ */
+struct tz1090_clk_deleter_priv {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	u32		period;
+	u32		mask;
+	u8		shift;
+};
+
+#define to_tz1090_clk_deleter(_hw) \
+	container_of(_hw, struct tz1090_clk_deleter_priv, hw)
+
+static unsigned long tz1090_clk_deleter_recalc_rate(struct clk_hw *hw,
+						    unsigned long parent_rate)
+{
+	struct tz1090_clk_deleter_priv *deleter = to_tz1090_clk_deleter(hw);
+	u32 delete;
+	u64 rate;
+
+	delete = (readl(deleter->reg) & deleter->mask) >> deleter->shift;
+	rate = (u64)parent_rate * (deleter->period - delete);
+	do_div(rate, deleter->period);
+	return rate;
+}
+
+static const struct clk_ops tz1090_clk_deleter_ops = {
+	.recalc_rate = tz1090_clk_deleter_recalc_rate,
+};
+
+/**
+ * __register_deleter() - register a clock deleter
+ * @name:		name of this clock
+ * @parent_name:	name of clock's parent
+ * @flags:		framework-specific flags
+ * @reg:		register address to adjust deleter
+ * @period:		delete cycle period
+ * @mask:		mask of delete field
+ * @shift:		start bit of delete field
+ *
+ * Register a TZ1090 clock deleter with the clock framework.
+ */
+static struct clk *__init __register_deleter(const char *name,
+					     const char *parent_name,
+					     unsigned long flags,
+					     void __iomem *reg,
+					     u32 period,
+					     u32 mask,
+					     u8 shift)
+{
+	struct tz1090_clk_deleter_priv *deleter;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	/* allocate the deleter */
+	deleter = kzalloc(sizeof(struct tz1090_clk_deleter_priv), GFP_KERNEL);
+	if (!deleter)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &tz1090_clk_deleter_ops;
+	init.flags = flags | CLK_IS_BASIC;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	/* struct tz1090_clk_deleter_priv assignments */
+	deleter->reg = reg;
+	deleter->period = period;
+	deleter->mask = mask;
+	deleter->shift = shift;
+	deleter->hw.init = &init;
+
+	/* register the clock */
+	clk = clk_register(NULL, &deleter->hw);
+
+	if (IS_ERR(clk))
+		kfree(deleter);
+
+	return clk;
+}
+
+/**
+ * tz1090_clk_register_deleters() - Register set of deleters with a provider.
+ * @p:		TZ1090 clock provider.
+ * @deleters:	Array of deleter descriptions.
+ * @count	Number of deleters described in the array.
+ */
+void __init tz1090_clk_register_deleters(struct tz1090_clk_provider *p,
+				const struct tz1090_clk_deleter *deleters,
+				unsigned int count)
+{
+	const struct tz1090_clk_deleter *del;
+	struct clk *clk;
+	unsigned int i;
+
+	for (del = deleters, i = 0; i < count; ++del, ++i) {
+		clk = __register_deleter(tz1090_clk_xlate(p, del->name),
+					 tz1090_clk_xlate(p, del->parent), 0,
+					 p->base + del->reg, 1024, 0x3ff, 0);
+		p->clk_data.clks[del->id] = clk;
+	}
+}
diff --git a/drivers/clk/tz1090/clk.h b/drivers/clk/tz1090/clk.h
index c9fe6ca..8f90908 100644
--- a/drivers/clk/tz1090/clk.h
+++ b/drivers/clk/tz1090/clk.h
@@ -135,4 +135,35 @@ struct tz1090_clk_mux_bank {
 void tz1090_clk_register_mux_bank(struct tz1090_clk_provider *p,
 				  const struct tz1090_clk_mux_bank *bank);
 
+
+/* Deleters */
+
+/**
+ * struct tz1090_clk_deleter - Describes a clock deleter.
+ * @id:		Id of output clock in provider.
+ * @reg:	Offset of deleter register in the MMIO region.
+ * @name:	Name of deleted clock to provide.
+ * @parent:	Name of parent/source clocks.
+ *
+ * The deleter is assumed to have a period of 1024.
+ */
+struct tz1090_clk_deleter {
+	unsigned int		id;
+	unsigned long		reg;
+	const char		*name;
+	const char		*parent;
+};
+
+#define DEL(_id, _parent, _name, _reg)		\
+	{					\
+		.id		= (_id),	\
+		.reg		= (_reg),	\
+		.name		= (_name),	\
+		.parent		= (_parent),	\
+	}
+
+void tz1090_clk_register_deleters(struct tz1090_clk_provider *p,
+				  const struct tz1090_clk_deleter *deleters,
+				  unsigned int count);
+
 #endif
-- 
2.0.4


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

* [PATCH v2 05/16] clk: tz1090: add divider clock driver
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (3 preceding siblings ...)
  2014-12-01 23:19 ` [PATCH v2 04/16] clk: tz1090: add deleter " James Hogan
@ 2014-12-01 23:19 ` James Hogan
  2014-12-01 23:19 ` [PATCH v2 06/16] clk: tz1090: add PLL " James Hogan
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:19 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan

Add a clock driver for dividers in the TZ1090 SoC, which divide an input
clock by an integer. The generic divider operations are optionally
wrapped in order to acquire and release the Meta global exclusive lock
(__global_lock2) to ensure atomicity with other non-Linux cores and
threads which may need to use some other fields in the same register.

The tz1090_clk_register_dividers() helper function can be used to
register a set of dividers from static initialisation data. DIV(),
DIV_FLAGS(), and DIV_SHARED() (for globally locked divider) macros are
provided in tz1090/clk.h to aid the creation of this data.  For example:

static const struct tz1090_clk_divider dividers[] __initconst = {
	DIV(CLK_TOP_SYS_DIV, "sys_pll", "sys_div", TOP_SYSCLK_DIV, 8),
	DIV_FLAGS(CLK_TOP_UART, "uart_en", "uart", TOP_UARTCLK_DIV, 8,
		  CLK_SET_RATE_PARENT, 0),
	DIV_SHARED(CLK_PDC_XTAL1_DIV, "@xtal1", "xtal1_div", PDC_SOC0,
		   11, 16),
	...
};
...
tz1090_clk_register_dividers(p, dividers, ARRAY_SIZE(dividers));

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: linux-metag@vger.kernel.org
---
Changes since v1 (patches 14 and 12):
- Drop divider DT binding and divider specific flags (policy) as
  dividers will be instantiated directly from a provider. These were the
  only things in clk-tz1090-divider.c.
- Split out wrapped (meta exclusive locked) divider driver from PDC
  clock driver.
- Renamed function prefixes from clk_tz1090_ to tz1090_clk_ for
  consistency with the rest.
- Switch back to using clk_divider::width rather than clk_divider::mask.
  Mask was only added to make it easier to be exposed in a DT binding,
  which is no longer required.
- Add tz1090_clk_register_dividers() to conveniently register a set of
  dividers in a clock provider from static initilisation data, either
  wrapped or generic dividers.
- Extend tz1090/clk.h interface for easy static initialisation with
  macros.
---
 drivers/clk/tz1090/Makefile             |   1 +
 drivers/clk/tz1090/clk-tz1090-divider.c | 151 ++++++++++++++++++++++++++++++++
 drivers/clk/tz1090/clk.h                |  63 +++++++++++++
 3 files changed, 215 insertions(+)
 create mode 100644 drivers/clk/tz1090/clk-tz1090-divider.c

diff --git a/drivers/clk/tz1090/Makefile b/drivers/clk/tz1090/Makefile
index 39c29ac..a7127d9 100644
--- a/drivers/clk/tz1090/Makefile
+++ b/drivers/clk/tz1090/Makefile
@@ -2,5 +2,6 @@
 obj-y		+= clk.o
 
 obj-y		+= clk-tz1090-deleter.o
+obj-y		+= clk-tz1090-divider.o
 obj-y		+= clk-tz1090-gate-bank.o
 obj-y		+= clk-tz1090-mux-bank.o
diff --git a/drivers/clk/tz1090/clk-tz1090-divider.c b/drivers/clk/tz1090/clk-tz1090-divider.c
new file mode 100644
index 0000000..22db67d
--- /dev/null
+++ b/drivers/clk/tz1090/clk-tz1090-divider.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ *
+ * TZ1090 Divider Clock.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <asm/global_lock.h>
+
+#include "clk.h"
+
+/**
+ * struct tz1090_clk_div_priv - tz1090 divider clock
+ *
+ * @div:	the parent class
+ * @ops:	pointer to clk_ops of parent class
+ *
+ * Divider clock whose field shares a register with other fields which may be
+ * used by multiple threads/cores and other drivers.
+ */
+struct tz1090_clk_div_priv {
+	struct clk_divider	div;
+	const struct clk_ops	*ops;
+};
+
+static inline struct tz1090_clk_div_priv *to_tz1090_clk_div(struct clk_hw *hw)
+{
+	struct clk_divider *div = container_of(hw, struct clk_divider, hw);
+
+	return container_of(div, struct tz1090_clk_div_priv, div);
+}
+
+static unsigned long tz1090_clk_divider_recalc_rate(struct clk_hw *hw,
+						    unsigned long parent_rate)
+{
+	struct tz1090_clk_div_priv *div = to_tz1090_clk_div(hw);
+
+	return div->ops->recalc_rate(&div->div.hw, parent_rate);
+}
+
+static long tz1090_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+					  unsigned long *prate)
+{
+	struct tz1090_clk_div_priv *div = to_tz1090_clk_div(hw);
+
+	return div->ops->round_rate(&div->div.hw, rate, prate);
+}
+
+/* Acquire exclusive lock since other cores may access the same register */
+static int tz1090_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+				       unsigned long parent_rate)
+{
+	struct tz1090_clk_div_priv *div = to_tz1090_clk_div(hw);
+	int ret;
+	unsigned long flags;
+
+	__global_lock2(flags);
+	ret = div->ops->set_rate(&div->div.hw, rate, parent_rate);
+	__global_unlock2(flags);
+
+	return ret;
+}
+
+static const struct clk_ops tz1090_clk_div_ops = {
+	.recalc_rate	= tz1090_clk_divider_recalc_rate,
+	.round_rate	= tz1090_clk_divider_round_rate,
+	.set_rate	= tz1090_clk_divider_set_rate,
+};
+
+static struct clk *__init __register_divider(const char *name,
+					     const char *parent_name,
+					     unsigned long flags,
+					     void __iomem *reg, u8 shift,
+					     u8 width, u8 clk_divider_flags)
+{
+	struct tz1090_clk_div_priv *div;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	/* allocate the divider */
+	div = kzalloc(sizeof(struct tz1090_clk_div_priv), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &tz1090_clk_div_ops;
+	init.flags = flags | CLK_IS_BASIC;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	/* struct clk_divider assignments */
+	div->div.reg = reg;
+	div->div.shift = shift;
+	div->div.width = width;
+	div->div.flags = clk_divider_flags;
+	div->div.hw.init = &init;
+
+	/* struct tz1090_clk_div_priv assignments */
+	div->ops = &clk_divider_ops;
+
+	/* register the clock */
+	clk = clk_register(NULL, &div->div.hw);
+
+	if (IS_ERR(clk))
+		kfree(div);
+
+	return clk;
+}
+
+/**
+ * tz1090_clk_register_dividers() - Register set of dividers with a provider.
+ * @p:		TZ1090 clock provider.
+ * @dividers:	Array of divider descriptions.
+ * @count	Number of dividers described in the array.
+ */
+void __init tz1090_clk_register_dividers(struct tz1090_clk_provider *p,
+				const struct tz1090_clk_divider *dividers,
+				unsigned int count)
+{
+	const struct tz1090_clk_divider *div;
+	struct clk *clk;
+	unsigned int i;
+
+	for (div = dividers, i = 0; i < count; ++div, ++i) {
+		/*
+		 * Dividers in registers shared between OSes must protect the
+		 * register with a global lock. Others with dedicated registers
+		 * can just use a normal divider.
+		 */
+		if (div->shared)
+			clk = __register_divider(tz1090_clk_xlate(p, div->name),
+					tz1090_clk_xlate(p, div->parent),
+					div->flags, p->base + div->reg,
+					div->shift, div->width, div->div_flags);
+		else
+			clk = clk_register_divider(NULL,
+					tz1090_clk_xlate(p, div->name),
+					tz1090_clk_xlate(p, div->parent),
+					div->flags, p->base + div->reg,
+					div->shift, div->width, div->div_flags,
+					NULL);
+		p->clk_data.clks[div->id] = clk;
+	}
+}
diff --git a/drivers/clk/tz1090/clk.h b/drivers/clk/tz1090/clk.h
index 8f90908..ca51f87 100644
--- a/drivers/clk/tz1090/clk.h
+++ b/drivers/clk/tz1090/clk.h
@@ -166,4 +166,67 @@ void tz1090_clk_register_deleters(struct tz1090_clk_provider *p,
 				  const struct tz1090_clk_deleter *deleters,
 				  unsigned int count);
 
+
+/* Dividers */
+
+/**
+ * struct tz1090_clk_divider - Describes a clock divider.
+ * @id:		Id of output clock in provider.
+ * @reg:	Offset of divider register in the MMIO region.
+ * @flags:	Clock flags.
+ * @div_flags:	Divider flags.
+ * @shift:	Shift of field controlling divider.
+ * @width:	Width of field controlling divider.
+ * @shared:	1 if register is shared with other important fields and requires
+ *		global locking.
+ * @name:	Name of divided clock to provide.
+ * @parent:	Name of parent/source clocks.
+ */
+struct tz1090_clk_divider {
+	unsigned int		id;
+	unsigned long		reg;
+	unsigned long		flags;
+	u8			div_flags;
+	u8			shift;
+	u8			width;
+	u8			shared;
+	const char		*name;
+	const char		*parent;
+};
+
+#define DIV(_id, _parent, _name, _reg, _width)	\
+	{								\
+		.id		= (_id),				\
+		.reg		= (_reg),				\
+		.width		= (_width),				\
+		.name		= (_name),				\
+		.parent		= (_parent),				\
+	}
+
+#define DIV_FLAGS(_id, _parent, _name, _reg, _width, _flags, _divflags)	\
+	{								\
+		.id		= (_id),				\
+		.reg		= (_reg),				\
+		.flags		= (_flags),				\
+		.div_flags	= (_divflags),				\
+		.width		= (_width),				\
+		.name		= (_name),				\
+		.parent		= (_parent),				\
+	}
+
+#define DIV_SHARED(_id, _parent, _name, _reg, _width, _shift)		\
+	{								\
+		.id		= (_id),				\
+		.reg		= (_reg),				\
+		.shift		= (_shift),				\
+		.width		= (_width),				\
+		.shared		= 1,					\
+		.name		= (_name),				\
+		.parent		= (_parent),				\
+	}
+
+void tz1090_clk_register_dividers(struct tz1090_clk_provider *p,
+				  const struct tz1090_clk_divider *dividers,
+				  unsigned int count);
+
 #endif
-- 
2.0.4


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

* [PATCH v2 06/16] clk: tz1090: add PLL clock driver
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (4 preceding siblings ...)
  2014-12-01 23:19 ` [PATCH v2 05/16] clk: tz1090: add divider " James Hogan
@ 2014-12-01 23:19 ` James Hogan
  2014-12-01 23:19 ` [PATCH v2 07/16] dt: binding: add binding for TZ1090 PDC clocks James Hogan
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:19 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan

Add a clock driver for the main PLLs in the TZ1090 SoC, the system PLL
and the ADC PLL. The system PLL is used to derive the core Meta clock,
the DDR clock, and the system clock. The ADC PLL can be used for various
purposes, but is usually used for the pixel clock.

The PLL is a True Circuits PLL, but the arrangement of the fields in the
registers is specific to the TZ1090 SoC.

The driver supports recalc_rate, round_rate, and set_rate operations.

The tz1090_clk_register_plls() helper function can be used to register a
set of PLLs from static initialisation data. A PLL() macro is provided
in tz1090/clk.h to aid the creation of this data. For example:

static const struct tz1090_clk_pll plls[] __initconst = {
	PLL(CLK_TOP_SYSPLL, "sys_sw", "sys_pll", TOP_SYSPLL_CTL0),
	...
};
...
tz1090_clk_register_plls(p, plls, ARRAY_SIZE(plls));

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: linux-metag@vger.kernel.org
---
Changes since v1 (patch 4):
- Renamed function prefixes from clk_tz1090_ to tz1090_clk_ for
  consistency with the rest.
- Drop DT binding as it will be instantiated directly from a provider.
- Add tz1090_clk_register_plls() to conveniently register a set of PLLs
  in a clock provider from static initilisation data.
- Extend tz1090/clk.h interface for easy static initialisation with
  macros.
---
 drivers/clk/tz1090/Makefile         |   1 +
 drivers/clk/tz1090/clk-tz1090-pll.c | 276 ++++++++++++++++++++++++++++++++++++
 drivers/clk/tz1090/clk.h            |  22 +++
 3 files changed, 299 insertions(+)
 create mode 100644 drivers/clk/tz1090/clk-tz1090-pll.c

diff --git a/drivers/clk/tz1090/Makefile b/drivers/clk/tz1090/Makefile
index a7127d9..a28a5bb 100644
--- a/drivers/clk/tz1090/Makefile
+++ b/drivers/clk/tz1090/Makefile
@@ -5,3 +5,4 @@ obj-y		+= clk-tz1090-deleter.o
 obj-y		+= clk-tz1090-divider.o
 obj-y		+= clk-tz1090-gate-bank.o
 obj-y		+= clk-tz1090-mux-bank.o
+obj-y		+= clk-tz1090-pll.o
diff --git a/drivers/clk/tz1090/clk-tz1090-pll.c b/drivers/clk/tz1090/clk-tz1090-pll.c
new file mode 100644
index 0000000..ca8260b
--- /dev/null
+++ b/drivers/clk/tz1090/clk-tz1090-pll.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ *
+ * True Circuits PLL in TZ1090 SoC.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+/* Register definitions */
+
+#define PLL_CTL0		0
+#define  PLL_CTL0_BWADJ_M		0xfff
+#define  PLL_CTL0_BWADJ_S		20
+#define  PLL_CTL0_CLKF_M		0x1fff
+#define  PLL_CTL0_CLKF_S		4
+#define  PLL_CTL0_CLKOD_M		0x7
+#define  PLL_CTL0_CLKOD_S		0
+#define PLL_CTL1		4
+#define  PLL_CTL1_RESET_B		BIT(28)
+#define  PLL_CTL1_FASTEN_B		BIT(27)
+#define  PLL_CTL1_ENSAT_B		BIT(26)
+#define  PLL_CTL1_BYPASS_B		BIT(25)
+#define  PLL_CTL1_PWRDN_B		BIT(24)
+#define  PLL_CTL1_CLKR_M		0x3f
+#define  PLL_CTL1_CLKR_S		0
+
+/**
+ * struct tz1090_clk_pll_priv - PLL in TZ1090
+ *
+ * @hw:		handle between common and hardware-specific interfaces
+ * @reg:	first of two registers
+ *
+ * PLL in TZ1090.
+ */
+struct tz1090_clk_pll_priv {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+};
+
+#define to_tz1090_clk_pll(_hw) container_of(_hw, struct tz1090_clk_pll_priv, hw)
+
+static unsigned long tz1090_clk_pll_recalc_rate(struct clk_hw *hw,
+						unsigned long f_in)
+{
+	struct tz1090_clk_pll_priv *pll = to_tz1090_clk_pll(hw);
+	u32 ctl0, ctl1;
+	unsigned int clk_f;	/* feedback divide */
+	unsigned int clk_od;	/* output divide */
+	unsigned int clk_r;	/* reference divide */
+	unsigned long f_out;
+
+	ctl0 = readl(pll->reg + PLL_CTL0);
+	ctl1 = readl(pll->reg + PLL_CTL1);
+
+	/* Bypass? */
+	if (ctl1 & PLL_CTL1_BYPASS_B)
+		return f_in;
+
+	/* Get divider values */
+	clk_f  = 1 + ((ctl0 >> PLL_CTL0_CLKF_S)  & PLL_CTL0_CLKF_M);
+	clk_od = 1 + ((ctl0 >> PLL_CTL0_CLKOD_S) & PLL_CTL0_CLKOD_M);
+	clk_r  = 1 + ((ctl1 >> PLL_CTL1_CLKR_S)  & PLL_CTL1_CLKR_M);
+
+	/*
+	 * formula:
+	 * f_out = (f_in / clk_r) * (clk_f / 2) / clk_od
+	 *       = (f_in * clk_f) / (2 * clk_r * clk_od)
+	 */
+	f_out = div_u64((u64)f_in * clk_f,
+			2 * clk_r * clk_od);
+	return f_out;
+}
+
+/* finds best pll parameters and returns rate on success (or 0) */
+static int tz1090_clk_pll_bestvals(struct clk_hw *hw, unsigned long parent_rate,
+				   unsigned long rate, unsigned long *clkf,
+				   unsigned long *clkr, unsigned long *clkod)
+{
+	unsigned long odmin, odmax;
+	unsigned long bestf = 1, bestr = 1, bestod = 1;
+	unsigned long rod2, cur, best = 0;
+	unsigned long f, r, od;
+
+	/* 120MHz/freq < od < 600MHz/freq */
+	odmin = 120000000/rate + 1;
+	odmax = 600000000/rate;
+
+	if (odmin < 1)
+		odmin = 1;
+	if (odmax > PLL_CTL0_CLKOD_M + 1)
+		odmax = PLL_CTL0_CLKOD_M + 1;
+
+	/*
+	 * Search through valid combinations of od and r, starting with lower
+	 * output divider values to get a lower intermediate frequency.
+	 */
+	for (od = odmin; od <= odmax; ++od) {
+		for (r = 1; r <= PLL_CTL1_CLKR_M + 1; ++r) {
+			/*
+			 * Calculate best f for given r and od, rounding down
+			 * So for f, freq <= rate
+			 * And for f+1, freq > rate
+			 * We have to do rate+1 because rate may have itself
+			 * been rounded down.
+			 */
+			rod2 = 2 * r * od;
+			f = div_u64((u64)(rate + 1) * rod2, parent_rate);
+			if (f < 1)
+				continue;
+			if (f > PLL_CTL0_CLKF_M + 1)
+				f = PLL_CTL0_CLKF_M + 1;
+
+			/* Calculate final rate and see if it's the best */
+			cur = div_u64((u64)parent_rate * f, rod2);
+			if (cur > best) {
+				bestf = f;
+				bestr = r;
+				bestod = od;
+				best = cur;
+				/* Can't improve on a perfect match */
+				if (cur == rate)
+					goto done;
+			}
+		}
+	}
+	if (!best)
+		return 0;
+done:
+	pr_debug("tz1090_clk_pll: final %lu/%lu * %lu/2/%lu=%lu (req=%lu, err=%ld)\n",
+		 parent_rate, bestr, bestf, bestod, best, rate, best - rate);
+
+	*clkf = bestf;
+	*clkr = bestr;
+	*clkod = bestod;
+	return best;
+}
+
+static long tz1090_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *prate)
+{
+	unsigned long clkf, clkr, clkod;
+	unsigned long parent_rate = *prate;
+
+	return tz1090_clk_pll_bestvals(hw, parent_rate, rate, &clkf, &clkr,
+				       &clkod);
+}
+
+static int tz1090_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long parent_rate)
+{
+	struct tz1090_clk_pll_priv *pll = to_tz1090_clk_pll(hw);
+	unsigned long clkf, clkr, clkod, bwadj;
+	u32 ctl0, ctl1;
+
+	if (!tz1090_clk_pll_bestvals(hw, parent_rate, rate,
+				     &clkf, &clkr, &clkod))
+		return -EINVAL;
+
+	/* offset the values ready to go in the PLL registers */
+	--clkr;
+	--clkf;
+	--clkod;
+	bwadj = clkf / 2;
+
+	/* bypass, reset and configure PLL */
+	ctl0 =	(bwadj << PLL_CTL0_BWADJ_S) |
+		(clkf  << PLL_CTL0_CLKF_S)  |
+		(clkod << PLL_CTL0_CLKOD_S);
+	ctl1 =	PLL_CTL1_RESET_B  |
+		PLL_CTL1_ENSAT_B  |
+		PLL_CTL1_BYPASS_B |
+		(clkr  << PLL_CTL1_CLKR_S);
+	writel(ctl1, pll->reg + PLL_CTL1);
+	writel(ctl0, pll->reg + PLL_CTL0);
+
+	/* allow 5us after clkf before deasserting reset */
+	udelay(5);
+
+	/* take PLL out of reset and enable fasten */
+	ctl1 &= ~PLL_CTL1_RESET_B;
+	ctl1 |= PLL_CTL1_FASTEN_B;
+	writel(ctl1, pll->reg + PLL_CTL1);
+
+	/* count at least 500 divided ref clks to allow time to lock */
+	msleep(1 + 500*1000*(clkr+1)/parent_rate);
+
+	/* take PLL out of fasten / bypass */
+	ctl1 &= ~PLL_CTL1_FASTEN_B;
+	ctl1 &= ~PLL_CTL1_BYPASS_B;
+	writel(ctl1, pll->reg + PLL_CTL1);
+
+	return 0;
+}
+
+static const struct clk_ops tz1090_clk_pll_ops = {
+	.recalc_rate	= tz1090_clk_pll_recalc_rate,
+	.round_rate	= tz1090_clk_pll_round_rate,
+	.set_rate	= tz1090_clk_pll_set_rate,
+};
+
+/**
+ * __register_pll() - register a PLL with the clock framework
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust PLL
+ *
+ * Register a TZ1090 PLL clock to the clock framework.
+ */
+static struct clk *__init __register_pll(const char *name,
+					 const char *parent_name,
+					 unsigned long flags,
+					 void __iomem *reg)
+{
+	struct tz1090_clk_pll_priv *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	/* allocate the pll */
+	pll = kzalloc(sizeof(struct tz1090_clk_pll_priv), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &tz1090_clk_pll_ops;
+	init.flags = flags | CLK_IS_BASIC;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	/* struct tz1090_clk_pll_priv assignments */
+	pll->reg = reg;
+	pll->hw.init = &init;
+
+	/* register the clock */
+	clk = clk_register(NULL, &pll->hw);
+
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+/**
+ * tz1090_clk_register_plls() - Register set of PLLs with a provider.
+ * @p:		TZ1090 clock provider.
+ * @plls:	Array of PLL descriptions.
+ * @count	Number of PLLs described in the array.
+ */
+void __init tz1090_clk_register_plls(struct tz1090_clk_provider *p,
+				     const struct tz1090_clk_pll *plls,
+				     unsigned int count)
+{
+	const struct tz1090_clk_pll *pll;
+	struct clk *clk;
+	unsigned int i;
+
+	for (pll = plls, i = 0; i < count; ++pll, ++i) {
+		clk = __register_pll(tz1090_clk_xlate(p, pll->name),
+				     tz1090_clk_xlate(p, pll->parent), 0,
+				     p->base + pll->reg_base);
+		p->clk_data.clks[pll->id] = clk;
+	}
+}
diff --git a/drivers/clk/tz1090/clk.h b/drivers/clk/tz1090/clk.h
index ca51f87..ae77ed5 100644
--- a/drivers/clk/tz1090/clk.h
+++ b/drivers/clk/tz1090/clk.h
@@ -229,4 +229,26 @@ void tz1090_clk_register_dividers(struct tz1090_clk_provider *p,
 				  const struct tz1090_clk_divider *dividers,
 				  unsigned int count);
 
+
+/* PLLs */
+
+struct tz1090_clk_pll {
+	unsigned int		id;
+	unsigned long		reg_base;
+	const char		*name;
+	const char		*parent;
+};
+
+#define PLL(_id, _parent, _name, _reg)			\
+	{						\
+		.id		= (_id),		\
+		.reg_base	= (_reg),		\
+		.name		= (_name),		\
+		.parent		= (_parent),		\
+	}
+
+void tz1090_clk_register_plls(struct tz1090_clk_provider *p,
+			      const struct tz1090_clk_pll *plls,
+			      unsigned int count);
+
 #endif
-- 
2.0.4


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

* [PATCH v2 07/16] dt: binding: add binding for TZ1090 PDC clocks
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (5 preceding siblings ...)
  2014-12-01 23:19 ` [PATCH v2 06/16] clk: tz1090: add PLL " James Hogan
@ 2014-12-01 23:19 ` James Hogan
  2014-12-01 23:19 ` [PATCH v2 08/16] clk: tz1090: add PDC clock provider driver James Hogan
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:19 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala

The TZ1090 PDC (PowerDown Controller) has a couple of clock components
in order to generate its main 32.768KHz clock which the peripherals in
the low power domain run off, especially while the SoC is otherwise
powered down.

Create a clock binding for the provider of these clocks, and a header
file in <dt-bindings/clock/> for enumerating the provided clocks.

It essentially has just two clock inputs (xtal1 and xtal3), and two
clock outputs, of which only "32khz" is likely to be used.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: linux-metag@vger.kernel.org
Cc: devicetree@vger.kernel.org
---
Changes since v1 (patch 11):
- Change the binding to conceptually represent all clocks provided by
  the PDC in TZ1090 rather than the same generic arrangement of clocks
  as the PDC in TZ1090, since the driver will use the common TZ1090
  specific clock provider helpers to provide specific clocks.
- Change compatible string from "img,tz1090-pdc-clock" to
  "img,tz1090-pdc-clocks" to match the intended purpose.
- Add header in <dt-bindings/clock/> to enumerate the provided clocks.
- Add clock-names as required property as used by common TZ1090 clock
  provider code.
- Mention standard clock-indices and clock-output-names optional
  properties for when the clocks may be used by other clock providers
  and should match the names used in the driver.
---
 .../bindings/clock/img,tz1090-pdc-clocks.txt       | 59 ++++++++++++++++++++++
 include/dt-bindings/clock/tz1090-pdc.h             | 18 +++++++
 2 files changed, 77 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-pdc-clocks.txt
 create mode 100644 include/dt-bindings/clock/tz1090-pdc.h

diff --git a/Documentation/devicetree/bindings/clock/img,tz1090-pdc-clocks.txt b/Documentation/devicetree/bindings/clock/img,tz1090-pdc-clocks.txt
new file mode 100644
index 0000000..2f3b4c9
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/img,tz1090-pdc-clocks.txt
@@ -0,0 +1,59 @@
+Binding for TZ1090 PDC clocks.
+
+This binding uses the common clock binding[1]. It represents the clocks
+required to generate the 32KHz PDC clock used by the devices in the low power
+domain:
+
+          ___________
+xtal1 ___| xtal1_div |____________________________
+         |___________|  |    ________   xtal1_div
+                        `--o| rtc_sw \____________
+xtal3 ----------------------|________/  32khz
+
+xtal1_div = xtal1 / (reg[26:16] + 1)
+xtal3 = reg[30] ? xtal3 : xtal1_div
+
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible         : Shall be "img,tz1090-pdc-clocks".
+- #clock-cells       : From common clock binding; shall be set to 1.
+- reg                : Base address for registers controlling PDC clocks.
+- clocks             : Clock specifiers for each input clock.
+- clock-names        : Labels for each input clock specified in clocks.
+                       Can contain the following entries:
+                       "xtal1" : XTAL1 oscillator.
+                       "xtal3" : XTAL3 32KHz oscillator.
+
+Optional properties:
+- clock-indices      : From common clock binding. Allows clock-output-names to
+                       be sparse.
+- clock-output-names : From common clock binding. May be used to name specific
+                       output clocks so that other clock providers can find
+                       the clocks by name before the provider has been
+                       instantiated. Can contain:
+                       "32khz"     : 32khz PDC clock.
+
+Clock Specifier Definition:
+- <1st-cell>: Output clock number. Use constants from
+              <dt-bindings/clock/tz1090-pdc.h>.
+
+Examples:
+	pdc_clks: pdc_clks {
+		compatible = "img,tz1090-pdc-clocks";
+		#clock-cells = <1>;
+		reg = <0x02006500 0x4>;	/* SOC_GPIO_CONTROL0 */
+		clocks = <&xtal1>,
+			 <&xtal3>;
+		clock-names = "xtal1",
+			      "xtal3";
+	};
+
+	ir {
+		...
+		clocks = <&pdc_clks CLK_PDC_32KHZ>,
+			 <&top_clks CLK_TOP_PDC>;
+		clock-names = "core", "sys";
+		...
+	};
diff --git a/include/dt-bindings/clock/tz1090-pdc.h b/include/dt-bindings/clock/tz1090-pdc.h
new file mode 100644
index 0000000..fa9a11c
--- /dev/null
+++ b/include/dt-bindings/clock/tz1090-pdc.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_CLK_TZ1090_PDC_H
+#define _DT_BINDINGS_CLK_TZ1090_PDC_H
+
+/* Powerdown Controller clocks */
+#define CLK_PDC_XTAL1_DIV	0
+#define CLK_PDC_32KHZ		1
+
+#define CLK_PDC_MAX		2
+
+#endif
-- 
2.0.4


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

* [PATCH v2 08/16] clk: tz1090: add PDC clock provider driver
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (6 preceding siblings ...)
  2014-12-01 23:19 ` [PATCH v2 07/16] dt: binding: add binding for TZ1090 PDC clocks James Hogan
@ 2014-12-01 23:19 ` James Hogan
  2014-12-01 23:19 ` [PATCH v2 09/16] dt: binding: add binding for TZ1090 TOP clocks James Hogan
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:19 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan

The TZ1090 PDC (PowerDown Controller) has a couple of clock components
in order to generate its main 32.768KHz clock which the peripherals in
the low power domain run off, especially while the SoC is otherwise
powered down.

It is generated either directly from the XTAL3 clock or by dividing the
XTAL1 clock. Both the divide and the mux are in a single register which
also contains GPIO output data, and may need to be used by other
non-Linux cores and threads.

Two clocks are created, a divider and a mux, both which use the TZ1090
specific wrapped versions of the generic clock drivers in order to use
the Meta exclusive lock when reconfiguring.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: linux-metag@vger.kernel.org
---
Changes since v1 (patch 12):
- Split out wrapped (meta exclusive locked) divider into patch 5.
- Switch to using common TZ1090 specific clock provider helpers,
  including for initialising divider data, changing driver to
  conceptually represent all clocks provided by the PDC in TZ1090 rather
  than the same generic arrangement of clocks as the PDC.
---
 drivers/clk/tz1090/Makefile         |  2 ++
 drivers/clk/tz1090/clk-tz1090-pdc.c | 52 +++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)
 create mode 100644 drivers/clk/tz1090/clk-tz1090-pdc.c

diff --git a/drivers/clk/tz1090/Makefile b/drivers/clk/tz1090/Makefile
index a28a5bb..a762cdf 100644
--- a/drivers/clk/tz1090/Makefile
+++ b/drivers/clk/tz1090/Makefile
@@ -6,3 +6,5 @@ obj-y		+= clk-tz1090-divider.o
 obj-y		+= clk-tz1090-gate-bank.o
 obj-y		+= clk-tz1090-mux-bank.o
 obj-y		+= clk-tz1090-pll.o
+
+obj-y		+= clk-tz1090-pdc.o
diff --git a/drivers/clk/tz1090/clk-tz1090-pdc.c b/drivers/clk/tz1090/clk-tz1090-pdc.c
new file mode 100644
index 0000000..a309eef
--- /dev/null
+++ b/drivers/clk/tz1090/clk-tz1090-pdc.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ *
+ * TZ1090 PDC Clocks.
+ */
+
+#include <dt-bindings/clock/tz1090-pdc.h>
+
+#include "clk.h"
+
+/* Register offsets into PDC SoC region */
+#define PDC_SOC0		0x00
+
+/*
+ *                  SOC_GPIO_CONTROL 0
+ *                  ==================
+ *           ___________
+ * xtal1 ___| xtal1_div |____________________________
+ *          |___________|  |    ________   xtal1_div
+ *                         `--o| rtc_sw \____________
+ * xtal3 ----------------------|________/  32khz
+ */
+
+static const struct tz1090_clk_divider tz1090_pdc_dividers[] __initconst = {
+	/*         id                  in        out         reg  width shift */
+	DIV_SHARED(CLK_PDC_XTAL1_DIV, "@xtal1", "xtal1_div", PDC_SOC0, 11, 16),
+};
+
+MUX_BANK(tz1090_pdc_mux, CLK_PDC_32KHZ, PDC_SOC0,
+	/*  bit in[0]		 in[1]		out	*/
+	MUX(30, "xtal1_div",	 "@xtal3",	"32khz")
+);
+
+static void __init tz1090_pdc_clocks_init(struct device_node *np)
+{
+	struct tz1090_clk_provider *p;
+
+	p = tz1090_clk_alloc_provider(np, CLK_PDC_MAX);
+	if (!p)
+		return;
+
+	tz1090_clk_register_dividers(p, tz1090_pdc_dividers,
+				     ARRAY_SIZE(tz1090_pdc_dividers));
+	tz1090_clk_register_mux_bank(p, &tz1090_pdc_mux);
+
+	tz1090_clk_register_provider(p);
+}
+CLK_OF_DECLARE(tz1090_pdc_clk, "img,tz1090-pdc-clocks", tz1090_pdc_clocks_init);
-- 
2.0.4


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

* [PATCH v2 09/16] dt: binding: add binding for TZ1090 TOP clocks
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (7 preceding siblings ...)
  2014-12-01 23:19 ` [PATCH v2 08/16] clk: tz1090: add PDC clock provider driver James Hogan
@ 2014-12-01 23:19 ` James Hogan
  2014-12-01 23:20 ` [PATCH v2 10/16] clk: tz1090: add TOP clock provider driver James Hogan
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:19 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala

The TZ1090 top level register region controls the majority of the SoC's
clocking infrastructure.

Create a clock binding for the provider of these clocks, and a header
file in <dt-bindings/clock/> for enumerating the provided clocks.

There are a variety of clocks provided, including from muxes, gates,
deleters, dividers, and PLLs.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: linux-metag@vger.kernel.org
Cc: devicetree@vger.kernel.org
---
Changes since v1 (patch 15):
- New patch.
- Convert explicit DT representation of clock infrastructure using
  generic bindings to several TZ1090 specific bindings representing
  groups of TZ1090 clocks.
---
 .../bindings/clock/img,tz1090-top-clocks.txt       |  68 ++++++++++++
 include/dt-bindings/clock/tz1090-top.h             | 118 +++++++++++++++++++++
 2 files changed, 186 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-top-clocks.txt
 create mode 100644 include/dt-bindings/clock/tz1090-top.h

diff --git a/Documentation/devicetree/bindings/clock/img,tz1090-top-clocks.txt b/Documentation/devicetree/bindings/clock/img,tz1090-top-clocks.txt
new file mode 100644
index 0000000..75b59f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/img,tz1090-top-clocks.txt
@@ -0,0 +1,68 @@
+Binding for TZ1090 Top level register clocks.
+
+This binding uses the common clock binding[1]. It represents the clocks
+controlled from the top level registers of the TZ1090, and encompasses most of
+the complexity of the TZ1090 clock tree:
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible         : Shall be "img,tz1090-top-clocks".
+- #clock-cells       : From common clock binding; shall be set to 1.
+- reg                : Base address for clock registers in top level register
+                       region.
+- clocks             : Clock specifiers for each input clock.
+- clock-names        : Labels for each input clock specified in clocks.
+                       Can contain the following entries:
+                       "xtal1"        : XTAL1 oscillator.
+                       "xtal3"        : XTAL2 oscillator.
+                       "ext_adc_dac"  : External ADC/DAC clock input.
+                       "ddr_en"       : Output of HEP DDR clock gate.
+                       "afe_progdiv1",
+                       "afe_progdiv3",
+                       "afe_rxsync",
+                       "afe_txsync",
+                       "iqadc_sync"   : Output clocks from AFE block.
+
+Optional properties:
+- clock-indices      : From common clock binding. Allows clock-output-names to
+                       be sparse.
+- clock-output-names : From common clock binding. May be used to name specific
+                       output clocks so that other clock providers can find
+                       the clocks by name before the provider has been
+                       instantiated. Can contain:
+                       "sys", "sys_x2_undeleted" "scb", "ext_stc0", "ext_stc1",
+                       "if1", "if0", "sys_ucc1", "sys_mtx", "meta", "ucc0",
+                       "ucc1_del", "sys_undeleted", "afe", "adcpll_div", "uart",
+                       "pdm", "spi0", "spi1", "i2sm", "usb_phy", "sdhost",
+                       "ring_osc", "i2s", "meta_trace", "pixel", "out0", "out1",
+                       "ddr", "sys_pll", "sys_pdc"
+
+Clock Specifier Definition:
+- <1st-cell>: Output clock number. Use constants from
+              <dt-bindings/clock/tz1090-top.h>.
+
+Examples:
+	top_clks: top_clks {
+		compatible = "img,tz1090-top-clocks";
+		#clock-cells = <1>;
+		reg = <0x02005900 0xb0>;
+		/* input clocks */
+		clocks = <&xtal1>, <&xtal2>, <&ext_adc_dac>,
+			 <&hep_cru CLK_HEP_DDR_EN>;
+		clock-names = "xtal1", "xtal2", "ext_adc_dac",
+			      "ddr_en";
+		/* output clocks for other clock providers */
+		clock-indices = <CLK_TOP_SYS>,
+				<CLK_TOP_SYS_X2_UNDELETED>;
+		clock-output-names = "sys",
+				     "sys_x2_undeleted";
+	};
+
+	ir {
+		...
+		clocks = <&pdc_clks CLK_PDC_32KHZ>,
+			 <&top_clks CLK_TOP_PDC>;
+		clock-names = "core", "sys";
+		...
+	};
diff --git a/include/dt-bindings/clock/tz1090-top.h b/include/dt-bindings/clock/tz1090-top.h
new file mode 100644
index 0000000..effb06a
--- /dev/null
+++ b/include/dt-bindings/clock/tz1090-top.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_CLK_TZ1090_TOP_H
+#define _DT_BINDINGS_CLK_TZ1090_TOP_H
+
+/* Ranges of top level clock numbers */
+#define CLK_TOP_CLKSWITCH_BASE		0
+#define CLK_TOP_CLKENAB_BASE		(CLK_TOP_CLKSWITCH_BASE  + 27)
+#define CLK_TOP_CLKSWITCH2_BASE		(CLK_TOP_CLKENAB_BASE    +  9)
+#define CLK_TOP_CLKENAB2_BASE		(CLK_TOP_CLKSWITCH2_BASE + 10)
+#define CLK_TOP_DEL_BASE		(CLK_TOP_CLKENAB2_BASE   +  7)
+#define CLK_TOP_DIV_BASE		(CLK_TOP_DEL_BASE        +  4)
+#define CLK_TOP_PLL_BASE		(CLK_TOP_DIV_BASE        + 18)
+#define CLK_TOP_CLKEN_BASE		(CLK_TOP_PLL_BASE        +  2)
+#define CLK_TOP_MAX			(CLK_TOP_CLKEN_BASE      +  1)
+
+
+/* CR_TOP_CLKSWITCH clocks */
+#define CLK_TOP_SYS_SW			(CLK_TOP_CLKSWITCH_BASE + 0)
+#define CLK_TOP_SYS_X2_UNDELETED	(CLK_TOP_CLKSWITCH_BASE + 1)
+#define CLK_TOP_OUT0_SW0		(CLK_TOP_CLKSWITCH_BASE + 2)
+#define CLK_TOP_OUT0_SW1		(CLK_TOP_CLKSWITCH_BASE + 3)
+#define CLK_TOP_OUT0_SW2		(CLK_TOP_CLKSWITCH_BASE + 4)
+#define CLK_TOP_OUT0_SW3		(CLK_TOP_CLKSWITCH_BASE + 5)
+#define CLK_TOP_OUT1_SW0		(CLK_TOP_CLKSWITCH_BASE + 6)
+#define CLK_TOP_OUT1_SW1		(CLK_TOP_CLKSWITCH_BASE + 7)
+#define CLK_TOP_OUT1_SW2		(CLK_TOP_CLKSWITCH_BASE + 8)
+#define CLK_TOP_OUT1_SW3		(CLK_TOP_CLKSWITCH_BASE + 9)
+#define CLK_TOP_I2S_SW2			(CLK_TOP_CLKSWITCH_BASE + 10)
+#define CLK_TOP_I2S_SW0			(CLK_TOP_CLKSWITCH_BASE + 11)
+#define CLK_TOP_I2S_SW1			(CLK_TOP_CLKSWITCH_BASE + 12)
+#define CLK_TOP_SCB_SW			(CLK_TOP_CLKSWITCH_BASE + 13)
+#define CLK_TOP_UART_SW			(CLK_TOP_CLKSWITCH_BASE + 14)
+#define CLK_TOP_EXT_STC0_SW		(CLK_TOP_CLKSWITCH_BASE + 15)
+#define CLK_TOP_EXT_STC1_SW		(CLK_TOP_CLKSWITCH_BASE + 16)
+#define CLK_TOP_USB_SW0			(CLK_TOP_CLKSWITCH_BASE + 17)
+#define CLK_TOP_USB_SW1			(CLK_TOP_CLKSWITCH_BASE + 18)
+#define CLK_TOP_AFE_SW0			(CLK_TOP_CLKSWITCH_BASE + 19)
+#define CLK_TOP_AFE_SW1			(CLK_TOP_CLKSWITCH_BASE + 20)
+#define CLK_TOP_ADCPLL_SW0		(CLK_TOP_CLKSWITCH_BASE + 21)
+#define CLK_TOP_ADCPLL_SW1		(CLK_TOP_CLKSWITCH_BASE + 22)
+#define CLK_TOP_ADCPLL_SW2		(CLK_TOP_CLKSWITCH_BASE + 23)
+#define CLK_TOP_ADCPLL_SW3		(CLK_TOP_CLKSWITCH_BASE + 24)
+#define CLK_TOP_USB_SW2			(CLK_TOP_CLKSWITCH_BASE + 25)
+#define CLK_TOP_USB_SW3			(CLK_TOP_CLKSWITCH_BASE + 26)
+
+/* CR_TOP_CLKENAB clocks */
+#define CLK_TOP_OUT0_EN			(CLK_TOP_CLKENAB_BASE + 0)
+#define CLK_TOP_OUT1_EN			(CLK_TOP_CLKENAB_BASE + 1)
+#define CLK_TOP_I2S_EN			(CLK_TOP_CLKENAB_BASE + 2)
+#define CLK_TOP_SCB			(CLK_TOP_CLKENAB_BASE + 3)
+#define CLK_TOP_UART_EN			(CLK_TOP_CLKENAB_BASE + 4)
+#define CLK_TOP_EXT_STC0		(CLK_TOP_CLKENAB_BASE + 5)
+#define CLK_TOP_EXT_STC1		(CLK_TOP_CLKENAB_BASE + 6)
+#define CLK_TOP_USB_EN			(CLK_TOP_CLKENAB_BASE + 7)
+#define CLK_TOP_ADCPLL_EN		(CLK_TOP_CLKENAB_BASE + 8)
+
+/* CR_TOP_CLKSWITCH2 clocks */
+#define CLK_TOP_PIXEL_SW0		(CLK_TOP_CLKSWITCH2_BASE + 0)
+#define CLK_TOP_PIXEL_SW1		(CLK_TOP_CLKSWITCH2_BASE + 1)
+#define CLK_TOP_PIXEL_SW2		(CLK_TOP_CLKSWITCH2_BASE + 2)
+#define CLK_TOP_PIXEL_SW3		(CLK_TOP_CLKSWITCH2_BASE + 3)
+#define CLK_TOP_PIXEL_SW4		(CLK_TOP_CLKSWITCH2_BASE + 4)
+#define CLK_TOP_IF1_SW			(CLK_TOP_CLKSWITCH2_BASE + 5)
+#define CLK_TOP_IF0_SW			(CLK_TOP_CLKSWITCH2_BASE + 6)
+#define CLK_TOP_DAC0_SW			(CLK_TOP_CLKSWITCH2_BASE + 7)
+#define CLK_TOP_UCC1_SW			(CLK_TOP_CLKSWITCH2_BASE + 8)
+#define CLK_TOP_UCC0_SW			(CLK_TOP_CLKSWITCH2_BASE + 9)
+
+/* CR_TOP_CLKENAB2 clocks */
+#define CLK_TOP_PIXEL_EN		(CLK_TOP_CLKENAB2_BASE + 0)
+#define CLK_TOP_IF1			(CLK_TOP_CLKENAB2_BASE + 1)
+#define CLK_TOP_IF0			(CLK_TOP_CLKENAB2_BASE + 2)
+#define CLK_TOP_EXT_ADC_EN		(CLK_TOP_CLKENAB2_BASE + 3)
+#define CLK_TOP_DAC0			(CLK_TOP_CLKENAB2_BASE + 4)
+#define CLK_TOP_SYS_UCC1		(CLK_TOP_CLKENAB2_BASE + 5)
+#define CLK_TOP_SYS_MTX			(CLK_TOP_CLKENAB2_BASE + 6)
+
+/* Clock deleters */
+#define CLK_TOP_SYS			(CLK_TOP_DEL_BASE + 0)
+#define CLK_TOP_META			(CLK_TOP_DEL_BASE + 1)
+#define CLK_TOP_UCC0			(CLK_TOP_DEL_BASE + 2)
+#define CLK_TOP_UCC1_DEL		(CLK_TOP_DEL_BASE + 3)
+
+/* Clock dividers */
+#define CLK_TOP_SYS_DIV			(CLK_TOP_DIV_BASE +  0)
+#define CLK_TOP_SYS_UNDELETED		(CLK_TOP_DIV_BASE +  1)
+#define CLK_TOP_AFE			(CLK_TOP_DIV_BASE +  2)
+#define CLK_TOP_ADCPLL_DIV		(CLK_TOP_DIV_BASE +  3)
+#define CLK_TOP_UART			(CLK_TOP_DIV_BASE +  4)
+#define CLK_TOP_PDM			(CLK_TOP_DIV_BASE +  5)
+#define CLK_TOP_SPI0			(CLK_TOP_DIV_BASE +  6)
+#define CLK_TOP_SPI1			(CLK_TOP_DIV_BASE +  7)
+#define CLK_TOP_I2SM			(CLK_TOP_DIV_BASE +  8)
+#define CLK_TOP_USB_PHY			(CLK_TOP_DIV_BASE +  9)
+#define CLK_TOP_SDHOST			(CLK_TOP_DIV_BASE + 10)
+#define CLK_TOP_RING_OSC		(CLK_TOP_DIV_BASE + 11)
+#define CLK_TOP_I2S			(CLK_TOP_DIV_BASE + 12)
+#define CLK_TOP_META_TRACE		(CLK_TOP_DIV_BASE + 13)
+#define CLK_TOP_PIXEL			(CLK_TOP_DIV_BASE + 14)
+#define CLK_TOP_OUT0			(CLK_TOP_DIV_BASE + 15)
+#define CLK_TOP_OUT1			(CLK_TOP_DIV_BASE + 16)
+#define CLK_TOP_DDR			(CLK_TOP_DIV_BASE + 17)
+
+/* PLL clocks */
+#define CLK_TOP_SYSPLL			(CLK_TOP_PLL_BASE + 0)
+#define CLK_TOP_ADCPLL			(CLK_TOP_PLL_BASE + 1)
+
+/* CR_TOP_CLKEN clocks */
+#define CLK_TOP_PDC			(CLK_TOP_CLKEN_BASE + 0)
+
+#endif
-- 
2.0.4


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

* [PATCH v2 10/16] clk: tz1090: add TOP clock provider driver
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (8 preceding siblings ...)
  2014-12-01 23:19 ` [PATCH v2 09/16] dt: binding: add binding for TZ1090 TOP clocks James Hogan
@ 2014-12-01 23:20 ` James Hogan
  2014-12-01 23:20 ` [PATCH v2 11/16] dt: binding: add binding for TZ1090 HEP clocks James Hogan
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:20 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan

The TZ1090 top level register region controls the majority of the SoC's
clocking infrastructure.

Most of the complexity comes from the description of the 2 main banks of
clock muxes (TOP_CLKSWITCH, TOP_CLKSWITCH2), with 2 banks of clock gates
(TOP_CLKENAB, TOP_CLKENAB2) which roughly speaking gate the outputs of
the muxes.

Also included are a variety of deleters, dividers, and PLLs.

The only clock specific policy decisions applied (so far) are:
- The UART divider which is flagged with CLK_SET_RATE_PARENT so that
  clock changes propagate up to the uart_sw mux so that the higher
  frequency system clock can be used as a source rather than the main
  external oscillator, in order to get a more accurate baud rate.
- The main system clock divider which is flagged with
  CLK_DIVIDER_READ_ONLY to prevent the system clock being altered.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: linux-metag@vger.kernel.org
---
Changes since v1 (patch 15):
- New patch.
- Convert explicit DT representation of clock infrastructure using
  generic bindings to several TZ1090 specific bindings representing
  groups of TZ1090 clocks.
- Add divider specific flags (policy) which were previously in divider
  DT driver.
- Tweak various clock names. A couple were wrong, some had the slightly
  redundant text "clk" in them, and others were output clocks so were
  better named without the "_en" which the output of clock gates tend to
  be called.
- Add TOP_CLKEN register which gates system clock to PDC.
- Tweak ascii art a little.
---
 drivers/clk/tz1090/Makefile         |   1 +
 drivers/clk/tz1090/clk-tz1090-top.c | 364 ++++++++++++++++++++++++++++++++++++
 2 files changed, 365 insertions(+)
 create mode 100644 drivers/clk/tz1090/clk-tz1090-top.c

diff --git a/drivers/clk/tz1090/Makefile b/drivers/clk/tz1090/Makefile
index a762cdf..873a8f6 100644
--- a/drivers/clk/tz1090/Makefile
+++ b/drivers/clk/tz1090/Makefile
@@ -8,3 +8,4 @@ obj-y		+= clk-tz1090-mux-bank.o
 obj-y		+= clk-tz1090-pll.o
 
 obj-y		+= clk-tz1090-pdc.o
+obj-y		+= clk-tz1090-top.o
diff --git a/drivers/clk/tz1090/clk-tz1090-top.c b/drivers/clk/tz1090/clk-tz1090-top.c
new file mode 100644
index 0000000..4f7316b
--- /dev/null
+++ b/drivers/clk/tz1090/clk-tz1090-top.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ *
+ * TZ1090 TOP Clocks
+ */
+
+#include <dt-bindings/clock/tz1090-top.h>
+
+#include "clk.h"
+
+/* Register offsets into top level memory region */
+#define TOP_CLKEN		0x00
+#define TOP_CLKSTATUS		0x04
+#define TOP_CLKSWITCH		0x08
+#define TOP_CLKENAB		0x0c
+#define TOP_CLKDELETE		0x10
+#define TOP_SYSCLK_DIV		0x14
+#define TOP_META_CLKDIV		0x18
+#define TOP_META_CLKDELETE	0x1c
+#define TOP_AFE_DIV		0x20
+#define TOP_ADCPLL_DIV		0x24
+#define TOP_UARTCLK_DIV		0x28
+#define TOP_PDMCK_CTL		0x30
+#define TOP_SPICLK_DIV		0x34
+#define TOP_SPI1CLK_DIV		0x38
+#define TOP_I2SCLK_DIV		0x3c
+#define TOP_USB_PLLDIV		0x40
+#define TOP_SDHOSTCLK_DIV	0x44
+#define TOP_RING_OP_DIV		0x48
+#define TOP_SYSPLL_CTL0		0x50
+#define TOP_ADCPLL_CTL0		0x58
+#define TOP_META_CLK		0x80
+#define TOP_CLKSWITCH2		0x88
+#define TOP_CLKENAB2		0x8c
+#define TOP_I2S_DIV2		0x90
+#define TOP_META_TRACE_CLK_DIV	0x94
+#define TOP_PIXEL_CLK_DIV	0x98
+#define TOP_CLKOUT0_DIV		0x9c
+#define TOP_CLKOUT1_DIV		0xa0
+#define TOP_UCC0_CLKDELETE	0xa4
+#define TOP_UCC1_CLKDELETE	0xa8
+#define TOP_DDR_CLKDIV		0xac
+
+/*
+ *                    CR_TOP_CLKSWITCH
+ *                    ================
+ *                       ___________        _________   _____________
+ * xtal1         ------o| sys_sw    \______| sys_pll |_| sys_clk_div |__
+ * xtal2         -------|___________/  0   |_________| |_____________|  |
+ *                    __________________________________________________|
+ *                   |   ___________
+ * xtal1         ----|-o|sysclk1_sw \____________________________
+ * sys_clk_div       `--|___________/  1 sys_clk_x2_undeleted
+ * xtal1         ------o|clkout0_sw0\______
+ * afe_progdiv1  -------|___________/  2   |
+ * sys_undeleted ------o|clkout0_sw1\____  |
+ * if0_sw        -------|___________/  3 | |   CR_TOP_CLKENAB
+ *                 ,-;==================='-'   ==============
+ *                 | |   ___________            ___________
+ * clkout0_sw0     | `-o|clkout0_sw2\____     _| out0_inv  \_____
+ * xtal2         --|----|___________/  4 |   | |___________/  4
+ *                 |  ___________________|   |__________________
+ *                 | |   ___________            ___________     |
+ * clkout0_sw2     | `-o|clkout0_sw3\__________| out0_en   \____|
+ * clkout0_sw1     `----|___________/  5       |___________/  5
+ * xtal1         ------o|clkout1_sw0\______     .
+ * xtal2         -------|___________/  6   |    .
+ * sys_undeleted ------o|clkout1_sw1\____  |    .
+ * if1_sw        -------|___________/  7 | |    .
+ *                 ,-;==================='-'    .
+ *                 | |   ___________            ___________
+ * adcpll_clk    --|-|-o|clkout1_sw2\____     _| out1_inv  \_____
+ * clkout1_sw1     `-|--|___________/  8 |   | |___________/  8
+ *                  _|___________________|   |__________________
+ *                 | |   ___________            ___________     |
+ * clkout1_sw0     | `-o|clkout1_sw3\__________| out1_en   \____|
+ * clkout1_sw2     `----|___________/  9       |___________/  9
+ * xtal1         ------o| i2s_sw2   \______     .
+ * sys_undeleted -------|___________/ 10   |    .
+ * xtal2         ------o| i2s_sw0   \____  |    .
+ * adcpll_clk    -------|___________/ 11 | |    .
+ *                 ,-;==================='-'    .
+ *                 | |   ___________            ___________
+ * i2s_sw2         | `-o| i2s_sw1   \__________| i2s_en    \_____
+ * i2s_sw0         `----|___________/ 12       |___________/ 12
+ * xtal1         ------o| scb_sw    \__________| scb_en    \_____
+ * sys_undeleted -------|___________/ 13       |___________/ 13
+ * xtal1         ------o| uart_sw   \__________| uart_en   \_____
+ * sys_undeleted -------|___________/ 14       |___________/ 14
+ * xtal1         ------o|ext_stc0_sw\__________|ext_stc0_en\_____
+ * xtal2         -------|___________/ 16       |___________/ 16
+ * xtal1         ------o|ext_stc1_sw\__________|ext_stc1_en\_____
+ * xtal2         -------|___________/ 17       |___________/ 17
+ * adcpll_clk    ------o|  usb_sw0  \____       .
+ * afe_progdiv3  -------|___________/ 18 |      .
+ *                    ___________________|      .
+ *                   |   ___________            ___________
+ * usb_sw3         ,-|-o|  usb_sw1  \__________| usb_en    \_____
+ * usb_sw0         | `--|___________/ 19       |___________/ 19
+ * xtal1         --|---o|  afe_sw0  \________________
+ * afe_sw1       ,-|----|___________/ 20        .    |    _____________
+ *               `-`=====================:-.    .    |___| afe_clk_div |________
+ *                       ___________     | |    .        |_____________| afe_clk
+ * adcpll_en       ,---o|  afe_sw1  \____| |    .
+ * xtal2         --|----|___________/ 21   |    .         ________
+ * xtal1         --|---o|adcpll_sw0 \______|_____________| adcpll |_____________
+ * xtal2         --|----|___________/ 22   |    .        |________| adcpll_clk
+ * xtal1         --|---o|adcpll_sw1 \____  |    .
+ * xtal2         --|----|___________/ 23 | |    .
+ *                 |  ___________________| |    .
+ *                 | |   ___________       |    .         ________________
+ * adcpll_en       +-|-o|adcpll_sw2 \______|_____________| adcpll_clk_div |_____
+ * adcpll_sw1      | `--|___________/ 24   |    .        |________________|
+ *                 |_______________________|_____________________
+ *                       ___________       |    ___________      |
+ * sys_undeleted -------|adcpll_sw3 \______|___| adcpll_en \_____|
+ * adcpll_clk    -------|___________/ 25   |   |___________/ 25
+ * xtal1         -------|  usb_sw2  \____  |
+ * xtal2         -------|___________/ 28 | |
+ *                    ___________________| |
+ *                   |   ___________       |
+ * usb_sw2           `--|  usb_sw3  \______|
+ * sys_undeleted -------|___________/ 29
+ */
+MUX_BANK(tz1090_top_clkswitch, CLK_TOP_CLKSWITCH_BASE, TOP_CLKSWITCH,
+	/*  bit in[0]		 in[1]			out	*/
+	MUX( 0, "@xtal1",	 "@xtal2",		"sys_sw")
+	MUX( 1, "@xtal1",	 "sys_div",		"sys_x2_undeleted")
+	MUX( 2, "@xtal1",	 "@afe_progdiv1",	"out0_sw0")
+	MUX( 3, "sys_undeleted", "if0_sw",		"out0_sw1")
+	MUX( 4, "out0_sw0",	 "@xtal2",		"out0_sw2")
+	MUX( 5, "out0_sw2",	 "out0_sw1",		"out0_sw3")
+	MUX( 6, "@xtal1",	 "@xtal2",		"out1_sw0")
+	MUX( 7, "sys_undeleted", "if1_sw",		"out1_sw1")
+	MUX( 8, "adcpll",	 "out1_sw1",		"out1_sw2")
+	MUX( 9, "out1_sw0",	 "out1_sw2",		"out1_sw3")
+	MUX(10, "@xtal1",	 "sys_undeleted",	"i2s_sw2")
+	MUX(11, "@xtal2",	 "adcpll",		"i2s_sw0")
+	MUX(12, "i2s_sw2",	 "i2s_sw0",		"i2s_sw1")
+	MUX(13, "@xtal1",	 "sys_undeleted",	"scb_sw")
+	MUX(14, "@xtal1",	 "sys_undeleted",	"uart_sw")
+	/* bit 15 unused */
+	MUX(16, "@xtal1",	 "@xtal2",		"ext_stc0_sw")
+	MUX(17, "@xtal1",	 "@xtal2",		"ext_stc1_sw")
+	MUX(18, "adcpll",	 "@afe_progdiv3",	"usb_sw0")
+	MUX(19, "usb_sw3",	 "usb_sw0",		"usb_sw1")
+	MUX(20, "@xtal1",	 "afe_sw1",		"afe_sw0")
+	MUX(21, "adcpll_en",	 "@xtal2",		"afe_sw1")
+	MUX(22, "@xtal1",	 "@xtal2",		"adcpll_sw0")
+	MUX(23, "@xtal1",	 "@xtal2",		"adcpll_sw1")
+	MUX(24, "adcpll_en",	 "adcpll_sw1",		"adcpll_sw2")
+	MUX(25, "sys_undeleted", "adcpll",		"adcpll_sw3")
+	/* bits 26..27 unused */
+	MUX(28, "@xtal1",	 "@xtal2",		"usb_sw2")
+	MUX(29, "usb_sw2",	 "sys_undeleted",	"usb_sw3")
+	/* bits 30..31 unused */
+);
+
+GATE_BANK(tz1090_top_clkenab, CLK_TOP_CLKENAB_BASE, TOP_CLKENAB,
+	/*   bit in			out	*/
+	/* bits 0..4 unused */
+	GATE( 5, "out0_sw3",		"out0_en")
+	/* bits 6..8 unused */
+	GATE( 9, "out1_sw3",		"out1_en")
+	/* bits 10..11 unused */
+	GATE(12, "i2s_sw1",		"i2s_en")
+	GATE(13, "scb_sw",		"scb")
+	GATE(14, "uart_sw",		"uart_en")
+	/* bit 15 unused */
+	GATE(16, "ext_stc0_sw",		"ext_stc0")
+	GATE(17, "ext_stc1_sw",		"ext_stc1")
+	/* bit 18 unused */
+	GATE(19, "usb_sw1",		"usb_en")
+	/* bits 20..24 unused */
+	GATE(25, "adcpll_sw3",		"adcpll_en")
+	/* bits 26..31 unused */
+);
+
+/*
+ *                    CR_TOP_CLKSWITCH2
+ *                    =================
+ *                       ___________
+ * xtal1         ------o| pixel_sw0 \______
+ * pixel_sw3       ,----|___________/  0   |
+ * sys_undeleted --+---o| pixel_sw1 \____  |
+ * pixel_sw4       | ,--|___________/  1 | |
+ *                 `-`===================|=|=:-.  CR_TOP_CLKENAB2
+ *                 ,-;==================='-' | |  ===============
+ *                 | |   ___________         | |    __________
+ * pixel_sw0       | `-o| pixel_sw2 \________|_|___| pixel_en \_____
+ * pixel_sw1       `----|___________/  2     | |   |__________/  2
+ * adcpll_clk    ------o| pixel_sw3 \________| |    .
+ * afe_progdiv3  -------|___________/  3       |    .
+ * usb_phy_clk   ------o| pixel_sw4 \__________|    .
+ * xtal2         -------|___________/  4            __________
+ * iqadc_sync    ------o| if1_sw    \______________| if1_en   \_____
+ * ext_adc_dac   --+----|___________/  5           |__________/  5
+ * afe_rxsync    --|---o| if0_sw    \______________| if0_en   \_____
+ * ext_adc_dac     |`---|___________/  6      _____|__________/  6
+ *                 |.________________________| ext_adc_dac_en \_____
+ *                 |     ___________         |________________/  7
+ * afe_txsync    --|---o| dac0_sw   \______________| dac0_en  \_____
+ * ext_adc_dac     `----|___________/  8           |__________/  8
+ * ucc1_clk_del  ------o| ucc1_sw   \______________| ucc1_en  \_____
+ * ucc0_clk_del  --+----|___________/  9           |__________/  9
+ * ucc0_clk_del    `---o| ucc0_sw   \______________| ucc0_en  \_____
+ * sys_clk       -------|___________/ 10           |__________/ 10
+ */
+MUX_BANK(tz1090_top_clkswitch2, CLK_TOP_CLKSWITCH2_BASE, TOP_CLKSWITCH2,
+	/*  bit in[0]			in[1]			out	*/
+	MUX( 0, "@xtal1",		"pixel_sw3",		"pixel_sw0")
+	MUX( 1, "sys_undeleted",	"pixel_sw4",		"pixel_sw1")
+	MUX( 2, "pixel_sw0",		"pixel_sw1",		"pixel_sw2")
+	MUX( 3, "adcpll",		"@afe_progdiv3",	"pixel_sw3")
+	MUX( 4, "usb_phy",		"@xtal2",		"pixel_sw4")
+	MUX( 5, "@iqadc_sync",		"@ext_adc_dac",		"if1_sw")
+	MUX( 6, "@afe_rxsync",		"@ext_adc_dac",		"if0_sw")
+	/* bit 7 unused */
+	MUX( 8, "@afe_txsync",		"@ext_adc_dac",		"dac0_sw")
+	MUX( 9, "ucc1_del",		"ucc0",			"ucc1_sw")
+	MUX(10, "ucc0",			"sys",			"ucc0_sw")
+	/* bits 11..31 unused */
+);
+
+GATE_BANK(tz1090_top_clkenab2, CLK_TOP_CLKENAB2_BASE, TOP_CLKENAB2,
+	/*   bit in			out	*/
+	/* bits 0..1 unused */
+	GATE( 2, "pixel_sw2",		"pixel_en")
+	/* bits 3..4 unused */
+	GATE( 5, "if1_sw",		"if1")
+	GATE( 6, "if0_sw",		"if0")
+	GATE( 7, "@ext_adc_dac",	"ext_adc_dac_en")
+	GATE( 8, "dac0_sw",		"dac0")
+	GATE( 9, "ucc1_sw",		"sys_ucc1")
+	GATE(10, "ucc0_sw",		"sys_mtx")
+	/* bits 11..31 unused */
+);
+
+/*
+ *                       Deleters
+ *                       ========
+ *
+ * sys_undeleted    ---[ clkdelete      ]--- sys_clk
+ * sys_x2_undeleted ---[ meta_clkdelete ]--- meta_core_clk
+ * sys_undeleted    ---[ clkdelete      ]--- ucc0_clk_del
+ * sys_undeleted    ---[ clkdelete      ]--- ucc1_clk_del
+ */
+
+static const struct tz1090_clk_deleter tz1090_top_deleters[] __initconst = {
+	DEL(CLK_TOP_SYS,      "sys_undeleted",    "sys",      TOP_CLKDELETE),
+	DEL(CLK_TOP_META,     "sys_x2_undeleted", "meta",     TOP_META_CLKDELETE),
+	DEL(CLK_TOP_UCC0,     "sys_undeleted",    "ucc0",     TOP_UCC0_CLKDELETE),
+	DEL(CLK_TOP_UCC1_DEL, "sys_undeleted",    "ucc1_del", TOP_UCC1_CLKDELETE),
+};
+
+/*
+ *                       Dividers
+ *                       ========
+ *
+ * sys_pll          ---[ sys_clk_div        ]--- sys_div
+ * sys_x2_undeleted ---[ meta_clk_div       ]--- sys_undeleted
+ * afe_sw0          ---[ afe_clk_div        ]--- afe_clk
+ * adcpll_sw2       ---[ adcpll_clk_div     ]--- adcpll_div
+ * uart_en          ---[ uart_clk_div       ]--- uart_clk
+ * sys_undeleted    ---[ pdm_clk_div        ]--- pdm_clk
+ * sys_undeleted    ---[ spi0_clk_div       ]--- spi0_clk
+ * sys_undeleted    ---[ spi1_clk_div       ]--- spi1_clk
+ * i2s_en           ---[ i2sm_clk_div       ]--- i2sm
+ * usb_en           ---[ usbpll_clk_div     ]--- usb_phy_clk
+ * sys_undeleted    ---[ sdhost_clk_div     ]--- sdhost_clk
+ * sys_undeleted    ---[ ring_osc_clk_div   ]--- ring_osc_clk
+ * i2sm_clk         ---[ i2s_clk_div2       ]--- i2s_clk
+ * sys_undeleted    ---[ meta_trace_clk_div ]--- meta_trace_clk
+ * pixel_en         ---[ pixel_clk_div      ]--- pixel_clk
+ * clkout0_en       ---[ clkout0_clk_div    ]--- clkout0
+ * clkout1_en       ---[ clkout1_clk_div    ]--- clkout1
+ * ddr_en           ---[ ddr_clk_div        ]--- ddr_clk
+ */
+
+static const struct tz1090_clk_divider tz1090_top_dividers[] __initconst = {
+	DIV(CLK_TOP_SYS_DIV,    "sys_pll",       "sys_div",    TOP_SYSCLK_DIV,         8),
+	/*
+	 * CLK_DIVIDER_READ_ONLY: sys_undeleted is set up by the bootloader
+	 * along with sys_pll, and has a whole bunch of derivative peripheral
+	 * clocks. It would be really bad for it to change on the fly.
+	 */
+	DIV_FLAGS(CLK_TOP_SYS_UNDELETED, "sys_x2_undeleted", "sys_undeleted", TOP_META_CLKDIV, 2,
+		  0, CLK_DIVIDER_READ_ONLY),
+	DIV(CLK_TOP_AFE,        "afe_sw0",       "afe",        TOP_AFE_DIV,            8),
+	DIV(CLK_TOP_ADCPLL_DIV, "adcpll_sw2",    "adcpll_div", TOP_ADCPLL_DIV,         8),
+	/*
+	 * CLK_SET_RATE_PARENT: UART clock changes must propagate up to uart_sw,
+	 * which muxes between XTAL1 and sys_undeleted, in order to get enough
+	 * precision.
+	 */
+	DIV_FLAGS(CLK_TOP_UART, "uart_en",       "uart",       TOP_UARTCLK_DIV,        8,
+		  CLK_SET_RATE_PARENT, 0),
+	DIV(CLK_TOP_PDM,        "sys_undeleted", "pdm",        TOP_PDMCK_CTL,          3),
+	DIV(CLK_TOP_SPI0,       "sys_undeleted", "spi0",       TOP_SPICLK_DIV,         8),
+	DIV(CLK_TOP_SPI1,       "sys_undeleted", "spi1",       TOP_SPI1CLK_DIV,        8),
+	DIV(CLK_TOP_I2SM,       "i2s_en",        "i2sm",       TOP_I2SCLK_DIV,         8),
+	DIV(CLK_TOP_USB_PHY,    "usb_en",        "usb_phy",    TOP_USB_PLLDIV,         8),
+	DIV(CLK_TOP_SDHOST,     "sys_undeleted", "sdhost",     TOP_SDHOSTCLK_DIV,      8),
+	DIV(CLK_TOP_RING_OSC,   "sys_undeleted", "ring_osc",   TOP_RING_OP_DIV,        4),
+	DIV(CLK_TOP_I2S,        "i2sm",          "i2s",        TOP_I2S_DIV2,           8),
+	DIV(CLK_TOP_META_TRACE, "sys_undeleted", "meta_trace", TOP_META_TRACE_CLK_DIV, 8),
+	DIV(CLK_TOP_PIXEL,      "pixel_en",      "pixel",      TOP_PIXEL_CLK_DIV,      8),
+	DIV(CLK_TOP_OUT0,       "out0_en",       "out0",       TOP_CLKOUT0_DIV,        8),
+	DIV(CLK_TOP_OUT1,       "out1_en",       "out1",       TOP_CLKOUT1_DIV,        8),
+	DIV(CLK_TOP_DDR,        "@ddr_en",       "ddr",        TOP_DDR_CLKDIV,         8),
+};
+
+/*
+ *                 PLLs
+ *                 ====
+ *
+ * sys_sw     ---[ sys_pll ]---
+ * adcpll_sw0 ---[ adcpll  ]---
+ */
+
+static const struct tz1090_clk_pll tz1090_top_plls[] __initconst = {
+	PLL(CLK_TOP_SYSPLL, "sys_sw",     "sys_pll", TOP_SYSPLL_CTL0),
+	PLL(CLK_TOP_ADCPLL, "adcpll_sw0", "adcpll",  TOP_ADCPLL_CTL0),
+};
+
+/*
+ *          CR_TOP_CLKEN
+ *          ============
+ *
+ * sys ----[ pdc_sys_en ]--- 0 sys_pdc
+ */
+GATE_BANK(tz1090_top_clken, CLK_TOP_CLKEN_BASE, TOP_CLKEN,
+	/*   bit in	out	*/
+	GATE( 0, "sys",	"sys_pdc")
+	/* bits 1..31 unused */
+);
+
+static void __init tz1090_top_clk_init(struct device_node *np)
+{
+	struct tz1090_clk_provider *p;
+
+	p = tz1090_clk_alloc_provider(np, CLK_TOP_MAX);
+	if (!p)
+		return;
+
+	tz1090_clk_register_mux_bank(p, &tz1090_top_clkswitch);
+	tz1090_clk_register_mux_bank(p, &tz1090_top_clkswitch2);
+	tz1090_clk_register_gate_bank(p, &tz1090_top_clkenab);
+	tz1090_clk_register_gate_bank(p, &tz1090_top_clkenab2);
+	tz1090_clk_register_gate_bank(p, &tz1090_top_clken);
+	tz1090_clk_register_deleters(p, tz1090_top_deleters,
+				     ARRAY_SIZE(tz1090_top_deleters));
+	tz1090_clk_register_dividers(p, tz1090_top_dividers,
+				     ARRAY_SIZE(tz1090_top_dividers));
+	tz1090_clk_register_plls(p, tz1090_top_plls,
+				 ARRAY_SIZE(tz1090_top_plls));
+
+	tz1090_clk_register_provider(p);
+}
+CLK_OF_DECLARE(tz1090_top_clk, "img,tz1090-top-clocks", tz1090_top_clk_init);
-- 
2.0.4


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

* [PATCH v2 11/16] dt: binding: add binding for TZ1090 HEP clocks
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (9 preceding siblings ...)
  2014-12-01 23:20 ` [PATCH v2 10/16] clk: tz1090: add TOP clock provider driver James Hogan
@ 2014-12-01 23:20 ` James Hogan
  2014-12-01 23:20 ` [PATCH v2 12/16] clk: tz1090: add HEP clock provider driver James Hogan
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:20 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala

The TZ1090 High End Peripheral (HEP) register region controls several
clocks for the HEP peripherals.

Create a clock binding for the provider of these clocks, and a header
file in <dt-bindings/clock/> for enumerating the provided clocks.

There are 3 clocks provided, the 2D block clock, the PDP/PDI clocks, and
the DDR enable clock which is fed back into the TOP clocks for dividing
down.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: linux-metag@vger.kernel.org
Cc: devicetree@vger.kernel.org
---
Changes since v1 (patch 15):
- New patch.
- Convert explicit DT representation of clock infrastructure using
  generic bindings to several TZ1090 specific bindings representing
  groups of TZ1090 clocks.
---
 .../bindings/clock/img,tz1090-hep-cru.txt          | 53 ++++++++++++++++++++++
 include/dt-bindings/clock/tz1090-hep.h             | 19 ++++++++
 2 files changed, 72 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-hep-cru.txt
 create mode 100644 include/dt-bindings/clock/tz1090-hep.h

diff --git a/Documentation/devicetree/bindings/clock/img,tz1090-hep-cru.txt b/Documentation/devicetree/bindings/clock/img,tz1090-hep-cru.txt
new file mode 100644
index 0000000..e5acdd6
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/img,tz1090-hep-cru.txt
@@ -0,0 +1,53 @@
+Binding for TZ1090 High end peripheral clocks.
+
+This binding uses the common clock binding[1]. It represents the clocks
+controlled from the high end peripheral registers of the TZ1090:
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible         : Shall be "img,tz1090-hep-cru".
+- #clock-cells       : From common clock binding; shall be set to 1.
+- reg                : Base address for clock registers in high end peripheral
+                       register region.
+- clocks             : Clock specifiers for each input clock.
+- clock-names        : Labels for each input clock specified in clocks.
+                       Can contain the following entries:
+                       "sys"              : Main system clock.
+                       "sys_x2_undeleted" : System clock before division and
+                                            deletion.
+
+Optional properties:
+- clock-indices      : From common clock binding. Allows clock-output-names to
+                       be sparse.
+- clock-output-names : From common clock binding. May be used to name specific
+                       output clocks so that other clock providers can find
+                       the clocks by name before the provider has been
+                       instantiated. Can contain:
+                       "sys_2d", "ddr_en", "sys_pdp"
+
+Clock Specifier Definition:
+- <1st-cell>: Output clock number. Use constants from
+              <dt-bindings/clock/tz1090-hep.h>.
+
+Examples:
+	hep_cru: hep_cru {
+		compatible = "img,tz1090-hep-cru";
+		#clock-cells = <1>;
+		reg = <0x02008c00 0x08>;
+		/* input clocks */
+		clocks = <&top_clks CLK_TOP_SYS>,
+			 <&top_clks CLK_TOP_SYS_X2_UNDELETED>;
+		clock-names = "sys",
+			      "sys_x2_undeleted";
+		/* output clocks for other clock providers */
+		clock-indices = <CLK_HEP_DDR_EN>;
+		clock-output-names = "ddr_en";
+	};
+
+	pdp {
+		...
+		clocks = <&hep_clks CLK_HEP_PDP>;
+		clock-names = "pdp";
+		...
+	};
diff --git a/include/dt-bindings/clock/tz1090-hep.h b/include/dt-bindings/clock/tz1090-hep.h
new file mode 100644
index 0000000..44398ef
--- /dev/null
+++ b/include/dt-bindings/clock/tz1090-hep.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_CLK_TZ1090_HEP_H
+#define _DT_BINDINGS_CLK_TZ1090_HEP_H
+
+/* CR_HEP_CLK_EN - High End Peripheral clocks */
+#define CLK_HEP_2D		0
+#define CLK_HEP_DDR_EN		1
+#define CLK_HEP_PDP		2
+
+#define CLK_HEP_MAX		3
+
+#endif
-- 
2.0.4


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

* [PATCH v2 12/16] clk: tz1090: add HEP clock provider driver
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (10 preceding siblings ...)
  2014-12-01 23:20 ` [PATCH v2 11/16] dt: binding: add binding for TZ1090 HEP clocks James Hogan
@ 2014-12-01 23:20 ` James Hogan
  2014-12-01 23:20 ` [PATCH v2 13/16] dt: binding: add binding for TZ1090 PERIP clocks James Hogan
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:20 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan

The TZ1090 High End Peripheral (HEP) register region controls several
clocks for the HEP peripherals.

The set up is pretty straight forward, with only a clock gate bank
(HEP_CLK_EN) needing to be configured.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: linux-metag@vger.kernel.org
---
Changes since v1 (patch 15):
- New patch.
- Convert explicit DT representation of clock infrastructure using
  generic bindings to several TZ1090 specific bindings representing
  groups of TZ1090 clocks.
---
 drivers/clk/tz1090/Makefile         |  1 +
 drivers/clk/tz1090/clk-tz1090-hep.c | 46 +++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+)
 create mode 100644 drivers/clk/tz1090/clk-tz1090-hep.c

diff --git a/drivers/clk/tz1090/Makefile b/drivers/clk/tz1090/Makefile
index 873a8f6..1d3cd32 100644
--- a/drivers/clk/tz1090/Makefile
+++ b/drivers/clk/tz1090/Makefile
@@ -7,5 +7,6 @@ obj-y		+= clk-tz1090-gate-bank.o
 obj-y		+= clk-tz1090-mux-bank.o
 obj-y		+= clk-tz1090-pll.o
 
+obj-y		+= clk-tz1090-hep.o
 obj-y		+= clk-tz1090-pdc.o
 obj-y		+= clk-tz1090-top.o
diff --git a/drivers/clk/tz1090/clk-tz1090-hep.c b/drivers/clk/tz1090/clk-tz1090-hep.c
new file mode 100644
index 0000000..e5585b4
--- /dev/null
+++ b/drivers/clk/tz1090/clk-tz1090-hep.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ *
+ * TZ1090 High End Peripheral (HEP) Clocks
+ */
+
+#include <dt-bindings/clock/tz1090-hep.h>
+
+#include "clk.h"
+
+/* Register offsets into high end peripheral memory region */
+#define HEP_CLK_EN		0x04
+
+/*
+ *                      CR_HEP_CLK_EN
+ *                      =============
+ *
+ * sys              -+--[ 2d_en      ]--- 0 sys_2d
+ * sys_x2_undeleted -|--[ ddr_en     ]--- 1 ddr_en
+ * sys               `--[ pdp_pdi_en ]--- 2 sys_pdp
+ */
+GATE_BANK(tz1090_hep_clken, 0, HEP_CLK_EN,
+	/*   bit in			out	*/
+	GATE( 0, "@sys",		"sys_2d")
+	GATE( 1, "@sys_x2_undeleted",	"ddr_en")
+	GATE( 2, "@sys",		"sys_pdp")
+	/* bits 3..31 unused */
+);
+
+static void __init tz1090_hep_cru_init(struct device_node *np)
+{
+	struct tz1090_clk_provider *p;
+
+	p = tz1090_clk_alloc_provider(np, CLK_HEP_MAX);
+	if (!p)
+		return;
+
+	tz1090_clk_register_gate_bank(p, &tz1090_hep_clken);
+
+	tz1090_clk_register_provider(p);
+}
+CLK_OF_DECLARE(tz1090_hep_cru, "img,tz1090-hep-cru", tz1090_hep_cru_init);
-- 
2.0.4


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

* [PATCH v2 13/16] dt: binding: add binding for TZ1090 PERIP clocks
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (11 preceding siblings ...)
  2014-12-01 23:20 ` [PATCH v2 12/16] clk: tz1090: add HEP clock provider driver James Hogan
@ 2014-12-01 23:20 ` James Hogan
  2014-12-01 23:20 ` [PATCH v2 14/16] clk: tz1090: add PERIP clock provider driver James Hogan
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:20 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala

The TZ1090 peripheral (PERIP) register region controls a bank of system
clock gates for individual peripherals.

Create a clock binding for the provider of these clocks, and a header
file in <dt-bindings/clock/> for enumerating the provided clocks.

There is a single input clock, the main system clock, and multiple
peripheral specific system clocks provided which should be referenced by
the relevant peripheral device nodes.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: linux-metag@vger.kernel.org
Cc: devicetree@vger.kernel.org
---
Changes since v1 (patch 15):
- New patch.
- Convert explicit DT representation of clock infrastructure using
  generic bindings to several TZ1090 specific bindings representing
  groups of TZ1090 clocks.
---
 .../bindings/clock/img,tz1090-perip-cru.txt        | 49 ++++++++++++++++++++++
 include/dt-bindings/clock/tz1090-perip.h           | 30 +++++++++++++
 2 files changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-perip-cru.txt
 create mode 100644 include/dt-bindings/clock/tz1090-perip.h

diff --git a/Documentation/devicetree/bindings/clock/img,tz1090-perip-cru.txt b/Documentation/devicetree/bindings/clock/img,tz1090-perip-cru.txt
new file mode 100644
index 0000000..3517737
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/img,tz1090-perip-cru.txt
@@ -0,0 +1,49 @@
+Binding for TZ1090 Peripheral register clocks.
+
+This binding uses the common clock binding[1]. It represents the clocks
+controlled from the peripheral registers of the TZ1090:
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible         : Shall be "img,tz1090-perip-cru".
+- #clock-cells       : From common clock binding; shall be set to 1.
+- reg                : Base address for clock registers in peripheral register
+                       region.
+- clocks             : Clock specifiers for each input clock.
+- clock-names        : Labels for each input clock specified in clocks.
+                       Can contain the following entries:
+                       "sys" : Main system clock.
+
+Optional properties:
+- clock-indices      : From common clock binding. Allows clock-output-names to
+                       be sparse.
+- clock-output-names : From common clock binding. May be used to name specific
+                       output clocks so that other clock providers can find
+                       the clocks by name before the provider has been
+                       instantiated. Can contain:
+                       "sys_scb0", "sys_scb1", "sys_scb2", "sys_sdio",
+                       "sys_uart0", "sys_uart1", "sys_spim", "sys_spis",
+                       "sys_spim1", "sys_i2sout", "sys_i2sin", "sys_lcd",
+                       "sys_sdhost", "sys_usb"
+
+Clock Specifier Definition:
+- <1st-cell>: Output clock number. Use constants from
+              <dt-bindings/clock/tz1090-perip.h>.
+
+Examples:
+	perip_cru: perip_cru {
+		compatible = "img,tz1090-perip-cru";
+		#clock-cells = <1>;
+		reg = <0x02004000 0x18>;
+		clocks = <&top_clks CLK_TOP_SYS>;
+		clock-names = "sys";
+	};
+
+	i2c {
+		...
+		clocks = <&top_clks CLK_TOP_SCB>,
+			 <&perip_cru CLK_PERIP_SCB0>;
+		clock-names = "scb", "sys";
+		...
+	};
diff --git a/include/dt-bindings/clock/tz1090-perip.h b/include/dt-bindings/clock/tz1090-perip.h
new file mode 100644
index 0000000..b2990ea
--- /dev/null
+++ b/include/dt-bindings/clock/tz1090-perip.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_CLK_TZ1090_PERIP_H
+#define _DT_BINDINGS_CLK_TZ1090_PERIP_H
+
+/* CR_PERIP_CLKEN - Peripheral system clocks */
+#define CLK_PERIP_SCB0		 0
+#define CLK_PERIP_SCB1		 1
+#define CLK_PERIP_SCB2		 2
+#define CLK_PERIP_SDIO		 3
+#define CLK_PERIP_UART0		 4
+#define CLK_PERIP_UART1		 5
+#define CLK_PERIP_SPIM		 6
+#define CLK_PERIP_SPIS		 7
+#define CLK_PERIP_SPIM1		 8
+#define CLK_PERIP_I2SOUT	 9
+#define CLK_PERIP_I2SIN		10
+#define CLK_PERIP_LCD		11
+#define CLK_PERIP_SDHOST	12
+#define CLK_PERIP_USB		13
+
+#define CLK_PERIP_MAX		14
+
+#endif
-- 
2.0.4


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

* [PATCH v2 14/16] clk: tz1090: add PERIP clock provider driver
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (12 preceding siblings ...)
  2014-12-01 23:20 ` [PATCH v2 13/16] dt: binding: add binding for TZ1090 PERIP clocks James Hogan
@ 2014-12-01 23:20 ` James Hogan
  2014-12-01 23:20 ` [PATCH v2 15/16] metag: tz1090: add TZ1090 clocks to device tree James Hogan
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:20 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan

The TZ1090 peripheral (PERIP) register region controls a bank of system
clock gates for individual peripherals.

The set up is pretty straight forward, with only a clock gate bank
(PERIP_CLKEN) needing to be configured, with all the gates using the
same external system clock as input.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: linux-metag@vger.kernel.org
---
Changes since v1 (patch 15):
- New patch.
- Convert explicit DT representation of clock infrastructure using
  generic bindings to several TZ1090 specific bindings representing
  groups of TZ1090 clocks.
---
 drivers/clk/tz1090/Makefile           |  1 +
 drivers/clk/tz1090/clk-tz1090-perip.c | 57 +++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)
 create mode 100644 drivers/clk/tz1090/clk-tz1090-perip.c

diff --git a/drivers/clk/tz1090/Makefile b/drivers/clk/tz1090/Makefile
index 1d3cd32..1df6b8a 100644
--- a/drivers/clk/tz1090/Makefile
+++ b/drivers/clk/tz1090/Makefile
@@ -9,4 +9,5 @@ obj-y		+= clk-tz1090-pll.o
 
 obj-y		+= clk-tz1090-hep.o
 obj-y		+= clk-tz1090-pdc.o
+obj-y		+= clk-tz1090-perip.o
 obj-y		+= clk-tz1090-top.o
diff --git a/drivers/clk/tz1090/clk-tz1090-perip.c b/drivers/clk/tz1090/clk-tz1090-perip.c
new file mode 100644
index 0000000..dbf8a25
--- /dev/null
+++ b/drivers/clk/tz1090/clk-tz1090-perip.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * 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.
+ *
+ * TZ1090 Peripheral Clocks
+ */
+
+#include <dt-bindings/clock/tz1090-perip.h>
+
+#include "clk.h"
+
+/* Register offsets into peripheral memory region */
+#define PERIP_SRST		0x00
+#define PERIP_CLKEN		0x10
+#define PERIP_CLKSTATUS		0x14
+
+/*
+ *            CR_PERIP_CLKEN
+ *            ==============
+ *
+ * sys ---[CR_PERIP_*_SYS_CLK_EN]--- sys_*
+ */
+GATE_BANK(tz1090_perip_clken, 0, PERIP_CLKEN,
+	/*   bit in      out */
+	GATE( 0, "@sys", "sys_scb0")
+	GATE( 1, "@sys", "sys_scb1")
+	GATE( 2, "@sys", "sys_scb2")
+	GATE( 3, "@sys", "sys_sdio")
+	GATE( 4, "@sys", "sys_uart0")
+	GATE( 5, "@sys", "sys_uart1")
+	GATE( 6, "@sys", "sys_spim")
+	GATE( 7, "@sys", "sys_spis")
+	GATE( 8, "@sys", "sys_spim1")
+	GATE( 9, "@sys", "sys_i2sout")
+	GATE(10, "@sys", "sys_i2sin")
+	GATE(11, "@sys", "sys_lcd")
+	GATE(12, "@sys", "sys_sdhost")
+	GATE(13, "@sys", "sys_usb")
+	/* bits 14..31 unused */
+);
+
+static void __init tz1090_perip_cru_init(struct device_node *np)
+{
+	struct tz1090_clk_provider *p;
+
+	p = tz1090_clk_alloc_provider(np, CLK_PERIP_MAX);
+	if (!p)
+		return;
+
+	tz1090_clk_register_gate_bank(p, &tz1090_perip_clken);
+
+	tz1090_clk_register_provider(p);
+}
+CLK_OF_DECLARE(tz1090_perip_cru, "img,tz1090-perip-cru", tz1090_perip_cru_init);
-- 
2.0.4


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

* [PATCH v2 15/16] metag: tz1090: add TZ1090 clocks to device tree
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (13 preceding siblings ...)
  2014-12-01 23:20 ` [PATCH v2 14/16] clk: tz1090: add PERIP clock provider driver James Hogan
@ 2014-12-01 23:20 ` James Hogan
  2014-12-01 23:20 ` [PATCH v2 16/16] metag: tz1090: connect Meta core clock James Hogan
  2015-01-09 15:10 ` [PATCH v2 00/16] tz1090: add clock components James Hogan
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:20 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala

Enable the common clock framework for the TZ1090 SoC, and add a
tz1090_clk device tree file instantiating and connecting together the
clock providers.

Most of the clock graph is represented, apart from the AFE output clocks
which aren't usually of much interest to Linux. These are represented
with a single placeholder clock for now, but in reality it is a whole IP
block with multiple clocks and a PLL.

Provided clocks include external oscillators:
- xtal1 (specified-clock)
- xtal2 (fixed-rate, rate to be specified by board dts if fitted)
- xtal3 (fixed-rate, rate to be specified by board dts if fitted)
External clock inputs:
- ext_adc_dac (0 Hz fixed-rate placeholder)
Internal groups of clocks
- afe_clks (0 Hz fixed-rate placeholder for multiple output clocks)
- pdc_clks (img,tz1090-pdc-clocks, mainly for 32khz low power clock)
- top_clks (img,tz1090-top-clocks, majority of clocking infrastructure)
- hep_cru (img,tz1090-hep-cru, high end peripheral clocks)
- perip_cru (img,tz1090-perip-cru, system clock to peripherals)

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: linux-metag@vger.kernel.org
Cc: devicetree@vger.kernel.org
---
Changes since v1 (patch 15):
- Convert explicit DT representation of clock infrastructure using
  generic bindings to several TZ1090 specific bindings representing
  groups of TZ1090 clocks.
- Combine unrepresented AFE block clocks into single fixed-clock
  placeholder.
- Split out use of Meta core clock into separate patch 16.
---
 arch/metag/Kconfig.soc              |   1 +
 arch/metag/boot/dts/tz1090.dtsi     |   1 +
 arch/metag/boot/dts/tz1090_clk.dtsi | 143 ++++++++++++++++++++++++++++++++++++
 3 files changed, 145 insertions(+)
 create mode 100644 arch/metag/boot/dts/tz1090_clk.dtsi

diff --git a/arch/metag/Kconfig.soc b/arch/metag/Kconfig.soc
index 973640f..93c21c3 100644
--- a/arch/metag/Kconfig.soc
+++ b/arch/metag/Kconfig.soc
@@ -17,6 +17,7 @@ config META21_FPGA
 config SOC_TZ1090
 	bool "Toumaz Xenif TZ1090 SoC (Comet)"
 	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select COMMON_CLK
 	select IMGPDC_IRQ
 	select METAG_LNKGET_AROUND_CACHE
 	select METAG_META21
diff --git a/arch/metag/boot/dts/tz1090.dtsi b/arch/metag/boot/dts/tz1090.dtsi
index 24ea7d2..48aa8b1 100644
--- a/arch/metag/boot/dts/tz1090.dtsi
+++ b/arch/metag/boot/dts/tz1090.dtsi
@@ -9,6 +9,7 @@
 #include "skeleton.dtsi"
 
 #include <dt-bindings/interrupt-controller/irq.h>
+#include "tz1090_clk.dtsi"
 
 / {
 	compatible = "toumaz,tz1090", "img,meta";
diff --git a/arch/metag/boot/dts/tz1090_clk.dtsi b/arch/metag/boot/dts/tz1090_clk.dtsi
new file mode 100644
index 0000000..2a98d60
--- /dev/null
+++ b/arch/metag/boot/dts/tz1090_clk.dtsi
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2013 Imagination Technologies Ltd.
+ *
+ * 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 <dt-bindings/clock/tz1090-top.h>
+#include <dt-bindings/clock/tz1090-hep.h>
+#include <dt-bindings/clock/tz1090-perip.h>
+#include <dt-bindings/clock/tz1090-pdc.h>
+
+/ {
+	soc {
+		/*
+		 * ============ EXTERNAL CLOCKS/OSCILLATORS ============
+		 */
+
+		/* XTAL1 frequency is specified in reset bootstrap config */
+		xtal1: xtal1 {
+			compatible = "specified-clock";
+			#clock-cells = <0>;
+			reg = <0x02004004 0x4>;	/* CR_PERIP_RESET_CFG */
+			bit-mask = <0x00000f00>;	/* FXTAL */
+			/*	 FXTAL	Frequency */
+			table = <0	16384000>,
+				<1	19200000>,
+				<2	24000000>,
+				<3	24576000>,
+				<4	26000000>,
+				<5	36000000>,
+				<6	36864000>,
+				<7	38400000>,
+				<8	40000000>,
+				<9	48000000>;
+			clock-output-names = "xtal1";
+		};
+
+		/* XTAL2 oscillator (board specific, but 12MHz recommended) */
+		xtal2: xtal2 {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <0>;
+			clock-output-names = "xtal2";
+		};
+
+		/* XTAL3 oscillator (32.768KHz if fitted, assume not fitted) */
+		xtal3: xtal3 {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <0>;
+			clock-output-names = "xtal3";
+		};
+
+		ext_adc_dac: ext_adc_dac {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <0>;
+			clock-output-names = "ext_adc_dac";
+		};
+
+
+		/*
+		 * ============ POWERDOWN CONTROLLER CLOCKS ============
+		 */
+
+		pdc_clks: pdc_clks {
+			compatible = "img,tz1090-pdc-clocks";
+			#clock-cells = <1>;
+			reg = <0x02006500 0x4>;	/* SOC_GPIO_CONTROL0 */
+			clocks = <&xtal1>,
+				 <&xtal3>;
+			clock-names = "xtal1",
+				      "xtal3";
+		};
+
+
+		/*
+		 * ============ AFE CLOCKS ============
+		 */
+
+		afe_clks: afe_clks {
+			/* This is just a placeholder at the moment */
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <0>;
+		};
+
+
+		/*
+		 * ============ TOP LEVEL CLOCKS ============
+		 */
+
+		top_clks: top_clks {
+			compatible = "img,tz1090-top-clocks";
+			#clock-cells = <1>;
+			reg = <0x02005900 0xb0>;
+			clocks = <&xtal1>, <&xtal2>, <&ext_adc_dac>,
+				 <&hep_cru CLK_HEP_DDR_EN>,
+				 <&afe_clks>, <&afe_clks>,
+				 <&afe_clks>, <&afe_clks>, <&afe_clks>;
+			clock-names = "xtal1", "xtal2", "ext_adc_dac",
+				      "ddr_en",
+				      "afe_progdiv1", "afe_progdiv3",
+				      "afe_rxsync", "afe_txsync", "iqadc_sync";
+			clock-indices = <CLK_TOP_SYS>,
+					<CLK_TOP_SYS_X2_UNDELETED>;
+			clock-output-names = "sys",
+					     "sys_x2_undeleted";
+		};
+
+
+		/*
+		 * ============ HIGH LEVEL PERIPHERAL CLOCKS ============
+		 */
+
+		hep_cru: hep_cru {
+			compatible = "img,tz1090-hep-cru";
+			#clock-cells = <1>;
+			reg = <0x02008c00 0x08>;
+			clocks = <&top_clks CLK_TOP_SYS>,
+				 <&top_clks CLK_TOP_SYS_X2_UNDELETED>;
+			clock-names = "sys",
+				      "sys_x2_undeleted";
+			clock-indices = <CLK_HEP_DDR_EN>;
+			clock-output-names = "ddr_en";
+		};
+
+		/*
+		 * ============ PERIPHERAL CLOCKS ============
+		 */
+
+		perip_cru: perip_cru {
+			compatible = "img,tz1090-perip-cru";
+			#clock-cells = <1>;
+			reg = <0x02004000 0x18>;
+			clocks = <&top_clks CLK_TOP_SYS>;
+			clock-names = "sys";
+		};
+
+	};
+};
-- 
2.0.4


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

* [PATCH v2 16/16] metag: tz1090: connect Meta core clock
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (14 preceding siblings ...)
  2014-12-01 23:20 ` [PATCH v2 15/16] metag: tz1090: add TZ1090 clocks to device tree James Hogan
@ 2014-12-01 23:20 ` James Hogan
  2015-01-09 15:10 ` [PATCH v2 00/16] tz1090: add clock components James Hogan
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2014-12-01 23:20 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, James Hogan, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala

Connect the Meta core clock to the root DT node so that the precise rate
of the Meta timer can be determined.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: linux-metag@vger.kernel.org
Cc: devicetree@vger.kernel.org
---
Changes since v1 (patch 15):
- Split out linking of Meta core clock in DT into this new patch.
---
 arch/metag/boot/dts/tz1090.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/metag/boot/dts/tz1090.dtsi b/arch/metag/boot/dts/tz1090.dtsi
index 48aa8b1..9b37642 100644
--- a/arch/metag/boot/dts/tz1090.dtsi
+++ b/arch/metag/boot/dts/tz1090.dtsi
@@ -16,6 +16,9 @@
 
 	interrupt-parent = <&intc>;
 
+	clocks = <&top_clks CLK_TOP_META>;
+	clock-names = "core";
+
 	intc: interrupt-controller {
 		compatible = "img,meta-intc";
 		interrupt-controller;
-- 
2.0.4


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

* Re: [PATCH v2 00/16] tz1090: add clock components
  2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
                   ` (15 preceding siblings ...)
  2014-12-01 23:20 ` [PATCH v2 16/16] metag: tz1090: connect Meta core clock James Hogan
@ 2015-01-09 15:10 ` James Hogan
  16 siblings, 0 replies; 18+ messages in thread
From: James Hogan @ 2015-01-09 15:10 UTC (permalink / raw)
  To: Mike Turquette, linux-metag, linux-kernel, devicetree
  Cc: Heiko Stuebner, Ian Campbell, Kumar Gala, Mark Rutland,
	Pawel Moll, Rob Herring, Stephen Boyd

[-- Attachment #1: Type: text/plain, Size: 8653 bytes --]

Hi,

On 01/12/14 23:19, James Hogan wrote:
> This patchset adds common clock framework support for the TZ1090 SoC.

Any further comments on these patches? It'd be nice to be able to get
them into v3.20 if possible.

Cheers
James

> 
> Patch 1 adds common code to simplify TZ1090 clock providers.
> 
> Patches 2 to 6 add TZ1090 clock types, specifically:
> * Gate banks (a register containing clock gate bits)
> * Mux banks (a register containing clock mux bits)
> * Clock deleters (delete up to 1023 out of every 1024 clocks)
> * PLLs (True Circuits, but TZ1090 specific register interface)
> * Divider clock (pretty basic divider, but specific to TZ1090)
> 
> Patches 7 to 14 add clock providers and DT bindings:
> * Top level register  (TOP) clocks
> * High end peripheral (HEP) clocks
> * Peripheral (PERIP) clocks
> * PowerDown Controller (PDC) clocks
> 
> Finally patch 15 defines most of the TZ1090 clocks in DT using these
> clock providers, with a few placeholders for less interesting clocks
> from more complex components, and patch 16 hooks up the Meta core clock
> so that the precise frequency of the Meta clock source can be
> determined. These are mostly for reference to give an idea how the clock
> components are intended to be used, and I'll take this one through the
> metag tree when the drivers/clk/ stuff is accepted.
> 
> Changes since v1:
> 
> Rework (the main change):
> - Convert explicit DT representation of clock infrastructure using
>   generic bindings for individual components to several TZ1090 specific
>   bindings representing groups of TZ1090 clocks (thanks Heiko). This
>   results in more lines of code overall, but it is nicer and more
>   maintainable.
> - Add common code for allocating and registering TZ1090 specific clock
>   providers. Various tz1090_clk_register_*() helper functions are
>   provided to conveniently register various low level TZ1090 clocks in a
>   clock provider from static initialisation data, which can be
>   initialised statically using provided macros.
> - Drop DT bindings for TZ1090 gate banks, mux banks, deleters, dividers
>   and PLLs as they will be instantiated directly from a larger clock
>   provider rather than individually from DT.
> - Switch back to using clk_divider::width rather than clk_divider::mask.
>   Mask was only added to make it easier to be exposed in a DT binding,
>   which is no longer required.
> - Add DT bindings and clock providers for TZ1090 top level register
>   clocks (TOP), high end peripheral clocks (HEP), peripheral (PERIP)
>   clocks, and powerdown controller clocks (PDC).
> - Add headers in <dt-bindings/clock/> to enumerate provided clocks.
> - Move divider specific flags (policy) to clock providers as dividers
>   will be instantiated by a provider rather than directly from DT.
> 
> Functional changes and corrections:
> - Tweak various clock names. A couple were wrong, some had the slightly
>   redundant text "clk" in them, and others were output clocks so were
>   better named without the "_en" which the output of clock gates tend to
>   be called.
> - Add TOP_CLKEN register to top clocks, which gates system clock to PDC.
> - Combine unrepresented AFE block clocks into single fixed-clock
>   placeholder.
> 
> Other cleanups and refactorings:
> - Split out wrapped (meta exclusive locked) divider driver from PDC
>   clock driver to clk-tz1090-divider.c.
> - Change the PDC clocks DT bindings and driver to conceptually represent
>   all clocks provided by the PDC in TZ1090 rather than the same generic
>   arrangement of clocks as the PDC in TZ1090, since the driver will use
>   the common TZ1090 specific clock provider helpers to provide specific
>   clocks.
> - Change PDC clocks compatible string from "img,tz1090-pdc-clock" to
>   "img,tz1090-pdc-clocks" to match the intended purpose.
> - Add clock-names as required property to PDC clocks DT binding as used
>   by common TZ1090 clock provider code.
> - Mention standard clock-indices and clock-output-names in PDC clocks DT
>   binding as optional properties for when the clocks may be used by
>   other clock providers and should match the names used in the driver.
> - Split out use of Meta core clock into separate patch 16.
> - Renamed function prefixes from clk_tz1090_ to tz1090_clk_ for
>   consistency with the rest.
> - Tweak ascii art clock diagrams a little.
> 
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
> Cc: Kumar Gala <galak@codeaurora.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Cc: linux-metag@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> 
> James Hogan (16):
>   clk: tz1090: add clock provider common code
>   clk: tz1090: add gate bank clock driver
>   clk: tz1090: add mux bank clock driver
>   clk: tz1090: add deleter clock driver
>   clk: tz1090: add divider clock driver
>   clk: tz1090: add PLL clock driver
>   dt: binding: add binding for TZ1090 PDC clocks
>   clk: tz1090: add PDC clock provider driver
>   dt: binding: add binding for TZ1090 TOP clocks
>   clk: tz1090: add TOP clock provider driver
>   dt: binding: add binding for TZ1090 HEP clocks
>   clk: tz1090: add HEP clock provider driver
>   dt: binding: add binding for TZ1090 PERIP clocks
>   clk: tz1090: add PERIP clock provider driver
>   metag: tz1090: add TZ1090 clocks to device tree
>   metag: tz1090: connect Meta core clock
> 
>  .../bindings/clock/img,tz1090-hep-cru.txt          |  53 +++
>  .../bindings/clock/img,tz1090-pdc-clocks.txt       |  59 ++++
>  .../bindings/clock/img,tz1090-perip-cru.txt        |  49 +++
>  .../bindings/clock/img,tz1090-top-clocks.txt       |  68 ++++
>  arch/metag/Kconfig.soc                             |   1 +
>  arch/metag/boot/dts/tz1090.dtsi                    |   4 +
>  arch/metag/boot/dts/tz1090_clk.dtsi                | 143 ++++++++
>  drivers/clk/Makefile                               |   1 +
>  drivers/clk/tz1090/Makefile                        |  13 +
>  drivers/clk/tz1090/clk-tz1090-deleter.c            | 132 ++++++++
>  drivers/clk/tz1090/clk-tz1090-divider.c            | 151 +++++++++
>  drivers/clk/tz1090/clk-tz1090-gate-bank.c          | 149 +++++++++
>  drivers/clk/tz1090/clk-tz1090-hep.c                |  46 +++
>  drivers/clk/tz1090/clk-tz1090-mux-bank.c           | 139 ++++++++
>  drivers/clk/tz1090/clk-tz1090-pdc.c                |  52 +++
>  drivers/clk/tz1090/clk-tz1090-perip.c              |  57 ++++
>  drivers/clk/tz1090/clk-tz1090-pll.c                | 276 ++++++++++++++++
>  drivers/clk/tz1090/clk-tz1090-top.c                | 364 +++++++++++++++++++++
>  drivers/clk/tz1090/clk.c                           |  89 +++++
>  drivers/clk/tz1090/clk.h                           | 254 ++++++++++++++
>  include/dt-bindings/clock/tz1090-hep.h             |  19 ++
>  include/dt-bindings/clock/tz1090-pdc.h             |  18 +
>  include/dt-bindings/clock/tz1090-perip.h           |  30 ++
>  include/dt-bindings/clock/tz1090-top.h             | 118 +++++++
>  24 files changed, 2285 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-hep-cru.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-pdc-clocks.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-perip-cru.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/img,tz1090-top-clocks.txt
>  create mode 100644 arch/metag/boot/dts/tz1090_clk.dtsi
>  create mode 100644 drivers/clk/tz1090/Makefile
>  create mode 100644 drivers/clk/tz1090/clk-tz1090-deleter.c
>  create mode 100644 drivers/clk/tz1090/clk-tz1090-divider.c
>  create mode 100644 drivers/clk/tz1090/clk-tz1090-gate-bank.c
>  create mode 100644 drivers/clk/tz1090/clk-tz1090-hep.c
>  create mode 100644 drivers/clk/tz1090/clk-tz1090-mux-bank.c
>  create mode 100644 drivers/clk/tz1090/clk-tz1090-pdc.c
>  create mode 100644 drivers/clk/tz1090/clk-tz1090-perip.c
>  create mode 100644 drivers/clk/tz1090/clk-tz1090-pll.c
>  create mode 100644 drivers/clk/tz1090/clk-tz1090-top.c
>  create mode 100644 drivers/clk/tz1090/clk.c
>  create mode 100644 drivers/clk/tz1090/clk.h
>  create mode 100644 include/dt-bindings/clock/tz1090-hep.h
>  create mode 100644 include/dt-bindings/clock/tz1090-pdc.h
>  create mode 100644 include/dt-bindings/clock/tz1090-perip.h
>  create mode 100644 include/dt-bindings/clock/tz1090-top.h
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

end of thread, other threads:[~2015-01-09 15:10 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-01 23:19 [PATCH v2 00/16] tz1090: add clock components James Hogan
2014-12-01 23:19 ` [PATCH v2 01/16] clk: tz1090: add clock provider common code James Hogan
2014-12-01 23:19 ` [PATCH v2 02/16] clk: tz1090: add gate bank clock driver James Hogan
2014-12-01 23:19 ` [PATCH v2 03/16] clk: tz1090: add mux " James Hogan
2014-12-01 23:19 ` [PATCH v2 04/16] clk: tz1090: add deleter " James Hogan
2014-12-01 23:19 ` [PATCH v2 05/16] clk: tz1090: add divider " James Hogan
2014-12-01 23:19 ` [PATCH v2 06/16] clk: tz1090: add PLL " James Hogan
2014-12-01 23:19 ` [PATCH v2 07/16] dt: binding: add binding for TZ1090 PDC clocks James Hogan
2014-12-01 23:19 ` [PATCH v2 08/16] clk: tz1090: add PDC clock provider driver James Hogan
2014-12-01 23:19 ` [PATCH v2 09/16] dt: binding: add binding for TZ1090 TOP clocks James Hogan
2014-12-01 23:20 ` [PATCH v2 10/16] clk: tz1090: add TOP clock provider driver James Hogan
2014-12-01 23:20 ` [PATCH v2 11/16] dt: binding: add binding for TZ1090 HEP clocks James Hogan
2014-12-01 23:20 ` [PATCH v2 12/16] clk: tz1090: add HEP clock provider driver James Hogan
2014-12-01 23:20 ` [PATCH v2 13/16] dt: binding: add binding for TZ1090 PERIP clocks James Hogan
2014-12-01 23:20 ` [PATCH v2 14/16] clk: tz1090: add PERIP clock provider driver James Hogan
2014-12-01 23:20 ` [PATCH v2 15/16] metag: tz1090: add TZ1090 clocks to device tree James Hogan
2014-12-01 23:20 ` [PATCH v2 16/16] metag: tz1090: connect Meta core clock James Hogan
2015-01-09 15:10 ` [PATCH v2 00/16] tz1090: add clock components James Hogan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).