linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 0/4] clk: ti: add support for clkctrl clocks
@ 2017-05-17 15:50 Tero Kristo
  2017-05-17 15:50 ` [PATCHv3 1/4] Documentation: dt-bindings: Add binding documentation for TI " Tero Kristo
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Tero Kristo @ 2017-05-17 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Basically a rebase on top of 4.12-rc1, with some minor fixes.
This series is now against the clock driver only, and should be ready
to pull in.

Changes compared to v2:

Patch #1: fixed the typo for #clock-cells property in the example
Patch #2: fixed a compile bug detected by kbuild bot, basically added
	  default clkctrl data, and moved the registration of omap4
	  version of the same to patch #4
Patch #3: grouped the macro definitions based on clock instance and
	  added header rows before the clock instances
Patch #4: Moved the registration of the clkctrl data under this patch

Dropped rest of the patches from series to be reviewed / pulled separately
by Tony, as they are all against mach-omap2 / omap DTS. I will post the
remaining patches separately on linux-omap list only.

Boot testing done against:
am335x-evm, am335x-evmsk, am37x-evm, am437x-sk, am43x-epos-evm,
am437x-gp-evm, omap3-beagle-xm, omap3-beagle, am335x-boneblack,
am335x-bone, craneboard, dra72x-evm, dra7xx-evm, omap3-n900,
omap5-uevm, omap4-panda-es, omap4-panda, omap2430-sdp,
omap3430-sdp, omap4-sdp-es23plus

Boot failures detected on:
am335x-evm, am43x-epos-evm, dra72x-evm, dra7xx-evm

  => all board fail to mount NFS rootfs but are otherwise fine
  => same failure seen on same boards on plain 4.12-rc1 also

Basic suspend-resume test done on omap4-panda-es.

Public branch:
tree: https://github.com/t-kristo/linux-pm.git
branch: 4.12-rc1-clkctrl

-Tero

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

* [PATCHv3 1/4] Documentation: dt-bindings: Add binding documentation for TI clkctrl clocks
  2017-05-17 15:50 [PATCHv3 0/4] clk: ti: add support for clkctrl clocks Tero Kristo
@ 2017-05-17 15:50 ` Tero Kristo
  2017-05-17 15:50 ` [PATCHv3 2/4] clk: ti: add support for " Tero Kristo
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Tero Kristo @ 2017-05-17 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tony Lindgren <tony@atomide.com>

Texas Instruments omap variant SoCs starting with omap4 have a clkctrl
clock controller instance for each interconnect target module. The clkctrl
controls functional and interface clocks for the module.

The clkctrl clocks are currently handled by arch/arm/mach-omap2 hwmod code.
With this binding and a related clock device driver we can start moving the
clkctrl clock handling to live in drivers/clk/ti.

Note that this binding allows keeping the clockdomain related parts out of
drivers/clock. The CLKCTCTRL and DYNAMICDEP registers can be handled by
a separate driver in drivers/soc/ti and genpd. If the clockdomain driver
needs to know it's clocks, we can just set the the clkctrl device
instances to be children of the related clockdomain device.

Each clkctrl clock can have multiple optional gate clocks, and multiple
optional mux clocks. To represent this in device tree, it seems that
it is best done using four clock cells #clock-cells = <2> property.

The reasons for using #clock-cells = <2> are:

1. We need to specify the clkctrl offset from the instance base. Otherwise
   we end up with a large number of device tree nodes that need to be
   patched when new clocks are discovered in a clkctrl clock with minor
   hardware revision changes for example

2. On omap5 CM_L3INIT_USB_HOST_HS_CLKCTRL has ten OPTFCLKEN bits. So we
   need to use a separate cell for optional gate clocks to avoid address
   space conflicts

There is probably no need to list input clocks for each clkctrl clock
instance in the binding. If we want to add them, the standard clocks
binding can be used for that.

For hardware reference, see omap4430 TRM "Table 3-1312. L4PER_CM2 Registers
Mapping Summary" for example. It shows one instance of a clkctrl clock
controller with multiple clkctrl registers.

Cc: Paul Walmsley <paul@pwsan.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 .../devicetree/bindings/clock/ti-clkctrl.txt       | 56 ++++++++++++++++++++++
 1 file changed, 56 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/ti-clkctrl.txt

diff --git a/Documentation/devicetree/bindings/clock/ti-clkctrl.txt b/Documentation/devicetree/bindings/clock/ti-clkctrl.txt
new file mode 100644
index 0000000..48ee699
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti-clkctrl.txt
@@ -0,0 +1,56 @@
+Texas Instruments clkctrl clock binding
+
+Texas Instruments SoCs can have a clkctrl clock controller for each
+interconnect target module. The clkctrl clock controller manages functional
+and interface clocks for each module. Each clkctrl controller can also
+gate one or more optional functional clocks for a module, and can have one
+or more clock muxes. There is a clkctrl clock controller typically for each
+interconnect target module on omap4 and later variants.
+
+The clock consumers can specify the index of the clkctrl clock using
+the hardware offset from the clkctrl instance register space. The optional
+clocks can be specified by clkctrl hardware offset and the index of the
+optional clock.
+
+For more information, please see the Linux clock framework binding at
+Documentation/devicetree/bindings/clock/clock-bindings.txt.
+
+Required properties :
+- compatible : shall be "ti,clkctrl"
+- #clock-cells : shall contain 2 with the first entry being the instance
+		 offset from the clock domain base and the second being the
+		 clock index
+
+Example: Clock controller node on omap 4430:
+
+&cm2 {
+	l4per: cm at 1400 {
+		cm_l4per at 0 {
+			cm_l4per_clkctrl: clk at 20 {
+				compatible = "ti,clkctrl";
+				reg = <0x20 0x1b0>;
+				#clock-cells = <2>;
+			};
+		};
+	};
+};
+
+Example: Preprocessor helper macros in dt-bindings/clock/ti-clkctrl.h
+
+#define OMAP4_CLKCTRL_OFFSET		0x20
+#define OMAP4_CLKCTRL_INDEX(offset)	((offset) - OMAP4_CLKCTRL_OFFSET)
+#define MODULEMODE_HWCTRL		1
+#define MODULEMODE_SWCTRL		2
+
+#define OMAP4_GPTIMER10_CLKTRL		OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_GPTIMER11_CLKTRL		OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_GPTIMER2_CLKTRL		OMAP4_CLKCTRL_INDEX(0x38)
+...
+#define OMAP4_GPIO2_CLKCTRL		OMAP_CLKCTRL_INDEX(0x60)
+
+Example: Clock consumer node for GPIO2:
+
+&gpio2 {
+       clocks = <&cm_l4per_clkctrl OMAP4_GPIO2_CLKCTRL 0
+		 &cm_l4per_clkctrl OMAP4_GPIO2_CLKCTRL 8>;
+};
-- 
1.9.1

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

* [PATCHv3 2/4] clk: ti: add support for clkctrl clocks
  2017-05-17 15:50 [PATCHv3 0/4] clk: ti: add support for clkctrl clocks Tero Kristo
  2017-05-17 15:50 ` [PATCHv3 1/4] Documentation: dt-bindings: Add binding documentation for TI " Tero Kristo
@ 2017-05-17 15:50 ` Tero Kristo
  2017-05-19 22:14   ` Tony Lindgren
  2017-05-17 15:50 ` [PATCHv3 3/4] dt-bindings: clk: add omap4 clkctrl definitions Tero Kristo
  2017-05-17 15:50 ` [PATCHv3 4/4] clk: ti: omap4: add clkctrl clock data Tero Kristo
  3 siblings, 1 reply; 7+ messages in thread
From: Tero Kristo @ 2017-05-17 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

Previously, hwmod core has been used for controlling the hwmod level
clocks directly. This has certain drawbacks, like being unable to share
the clocks for multiple users, missing usecounting and generally being
totally incompatible with the common clock framework.

This patch adds support for clkctrl clocks for addressing the above
issues. These support the modulemode handling, which will replace the
direct hwmod clkctrl linkage. Any optional clocks are also supported,
gate, mux and divider.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/Makefile  |   3 +-
 drivers/clk/ti/clkctrl.c | 481 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/ti/clock.h   |  29 +++
 3 files changed, 512 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/ti/clkctrl.c

diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index 0deac98..edb9f47 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -3,7 +3,8 @@ ifeq ($(CONFIG_ARCH_OMAP2PLUS), y)
 obj-y					+= clk.o autoidle.o clockdomain.o
 clk-common				= dpll.o composite.o divider.o gate.o \
 					  fixed-factor.o mux.o apll.o \
-					  clkt_dpll.o clkt_iclk.o clkt_dflt.o
+					  clkt_dpll.o clkt_iclk.o clkt_dflt.o \
+					  clkctrl.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(clk-common) clk-33xx.o dpll3xxx.o
 obj-$(CONFIG_SOC_TI81XX)		+= $(clk-common) fapll.o clk-814x.o clk-816x.o
 obj-$(CONFIG_ARCH_OMAP2)		+= $(clk-common) interface.o clk-2xxx.o
diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c
new file mode 100644
index 0000000..cfdd97f
--- /dev/null
+++ b/drivers/clk/ti/clkctrl.c
@@ -0,0 +1,481 @@
+/*
+ * OMAP clkctrl clock support
+ *
+ * Copyright (C) 2017 Texas Instruments, Inc.
+ *
+ * Tero Kristo <t-kristo@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk/ti.h>
+#include <linux/delay.h>
+#include "clock.h"
+
+#define NO_IDLEST			0x1
+
+#define OMAP4_MODULEMODE_MASK		0x3
+
+#define MODULEMODE_HWCTRL		0x1
+#define MODULEMODE_SWCTRL		0x2
+
+#define OMAP4_IDLEST_MASK		(0x3 << 16)
+#define OMAP4_IDLEST_SHIFT		16
+
+#define CLKCTRL_IDLEST_FUNCTIONAL	0x0
+#define CLKCTRL_IDLEST_INTERFACE_IDLE	0x2
+#define CLKCTRL_IDLEST_DISABLED		0x3
+
+/* These timeouts are in us */
+#define OMAP4_MAX_MODULE_READY_TIME	2000
+#define OMAP4_MAX_MODULE_DISABLE_TIME	5000
+
+static bool _early_timeout = true;
+
+struct omap_clkctrl_provider {
+	void __iomem *base;
+	struct list_head clocks;
+};
+
+struct omap_clkctrl_clk {
+	struct clk_hw *clk;
+	u16 reg_offset;
+	int bit_offset;
+	struct list_head node;
+};
+
+union omap4_timeout {
+	u32 cycles;
+	ktime_t start;
+};
+
+static const struct omap_clkctrl_data default_clkctrl_data[] __initconst = {
+	{ 0 },
+};
+
+static u32 _omap4_idlest(u32 val)
+{
+	val &= OMAP4_IDLEST_MASK;
+	val >>= OMAP4_IDLEST_SHIFT;
+
+	return val;
+}
+
+static bool _omap4_is_idle(u32 val)
+{
+	val = _omap4_idlest(val);
+
+	return val == CLKCTRL_IDLEST_DISABLED;
+}
+
+static bool _omap4_is_ready(u32 val)
+{
+	val = _omap4_idlest(val);
+
+	return val == CLKCTRL_IDLEST_FUNCTIONAL ||
+	       val == CLKCTRL_IDLEST_INTERFACE_IDLE;
+}
+
+static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout)
+{
+	if (unlikely(_early_timeout)) {
+		if (time->cycles++ < timeout) {
+			udelay(1);
+			return false;
+		}
+	} else {
+		if (!ktime_to_ns(time->start)) {
+			time->start = ktime_get();
+			return false;
+		}
+
+		if (ktime_us_delta(ktime_get(), time->start) < timeout) {
+			cpu_relax();
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static int __init _omap4_disable_early_timeout(void)
+{
+	_early_timeout = false;
+
+	return 0;
+}
+arch_initcall(_omap4_disable_early_timeout);
+
+static int _omap4_clkctrl_clk_enable(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+	int ret;
+	union omap4_timeout timeout = { 0 };
+
+	if (!clk->enable_bit)
+		return 0;
+
+	if (clk->clkdm) {
+		ret = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk);
+		if (ret) {
+			WARN(1,
+			     "%s: could not enable %s's clockdomain %s: %d\n",
+			     __func__, clk_hw_get_name(hw),
+			     clk->clkdm_name, ret);
+			return ret;
+		}
+	}
+
+	val = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
+
+	val &= ~OMAP4_MODULEMODE_MASK;
+	val |= clk->enable_bit;
+
+	ti_clk_ll_ops->clk_writel(val, &clk->enable_reg);
+
+	if (clk->flags & NO_IDLEST)
+		return 0;
+
+	/* Wait until module is enabled */
+	while (!_omap4_is_ready(ti_clk_ll_ops->clk_readl(&clk->enable_reg))) {
+		if (_omap4_is_timeout(&timeout, OMAP4_MAX_MODULE_READY_TIME)) {
+			pr_err("%s: failed to enable\n", clk_hw_get_name(hw));
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static void _omap4_clkctrl_clk_disable(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+	union omap4_timeout timeout = { 0 };
+
+	if (!clk->enable_bit)
+		return;
+
+	val = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
+
+	val &= ~OMAP4_MODULEMODE_MASK;
+
+	ti_clk_ll_ops->clk_writel(val, &clk->enable_reg);
+
+	if (clk->flags & NO_IDLEST)
+		goto exit;
+
+	/* Wait until module is disabled */
+	while (!_omap4_is_idle(ti_clk_ll_ops->clk_readl(&clk->enable_reg))) {
+		if (_omap4_is_timeout(&timeout,
+				      OMAP4_MAX_MODULE_DISABLE_TIME)) {
+			pr_err("%s: failed to disable\n", clk_hw_get_name(hw));
+			break;
+		}
+	}
+
+exit:
+	if (clk->clkdm)
+		ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
+}
+
+static int _omap4_clkctrl_clk_is_enabled(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 val;
+
+	val = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
+
+	if (val & clk->enable_bit)
+		return 1;
+
+	return 0;
+}
+
+static const struct clk_ops omap4_clkctrl_clk_ops = {
+	.enable		= _omap4_clkctrl_clk_enable,
+	.disable	= _omap4_clkctrl_clk_disable,
+	.is_enabled	= _omap4_clkctrl_clk_is_enabled,
+};
+
+static struct clk_hw *_ti_omap4_clkctrl_xlate(struct of_phandle_args *clkspec,
+					      void *data)
+{
+	struct omap_clkctrl_provider *provider = data;
+	struct omap_clkctrl_clk *entry;
+
+	if (clkspec->args_count != 2)
+		return ERR_PTR(-EINVAL);
+
+	pr_debug("%s: looking for %x:%x\n", __func__,
+		 clkspec->args[0], clkspec->args[1]);
+
+	list_for_each_entry(entry, &provider->clocks, node) {
+		if (entry->reg_offset == clkspec->args[0] &&
+		    entry->bit_offset == clkspec->args[1])
+			break;
+	}
+
+	if (!entry)
+		return ERR_PTR(-EINVAL);
+
+	return entry->clk;
+}
+
+static int __init
+_ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider,
+			 struct device_node *node, struct clk_hw *clk_hw,
+			 u16 offset, u8 bit, const char * const *parents,
+			 int num_parents, const struct clk_ops *ops)
+{
+	struct clk_init_data init = { NULL };
+	struct clk *clk;
+	struct omap_clkctrl_clk *clkctrl_clk;
+
+	init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", node->parent->name,
+			      node->name, offset, bit);
+	clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL);
+	if (!init.name || !clkctrl_clk) {
+		kfree(init.name);
+		return -ENOMEM;
+	}
+
+	clk_hw->init = &init;
+	init.parent_names = parents;
+	init.num_parents = num_parents;
+	init.ops = ops;
+	init.flags = CLK_IS_BASIC;
+
+	clk = ti_clk_register(NULL, clk_hw, init.name);
+
+	if (IS_ERR_OR_NULL(clk))
+		return -EINVAL;
+
+	clkctrl_clk->reg_offset = offset;
+	clkctrl_clk->bit_offset = bit;
+	clkctrl_clk->clk = clk_hw;
+
+	list_add(&clkctrl_clk->node, &provider->clocks);
+
+	return 0;
+}
+
+static void __init
+_ti_clkctrl_setup_gate(struct omap_clkctrl_provider *provider,
+		       struct device_node *node, u16 offset,
+		       const struct omap_clkctrl_bit_data *data,
+		       void __iomem *reg)
+{
+	struct clk_hw_omap *clk_hw;
+
+	clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
+	if (!clk_hw)
+		return;
+
+	clk_hw->enable_bit = data->bit;
+	clk_hw->enable_reg.ptr = reg;
+
+	if (_ti_clkctrl_clk_register(provider, node, &clk_hw->hw, offset,
+				     data->bit, data->parents, 1,
+				     &omap_gate_clk_ops))
+		kfree(clk_hw);
+}
+
+static void __init
+_ti_clkctrl_setup_mux(struct omap_clkctrl_provider *provider,
+		      struct device_node *node, u16 offset,
+		      const struct omap_clkctrl_bit_data *data,
+		      void __iomem *reg)
+{
+	struct clk_omap_mux *mux;
+	int num_parents = 0;
+	const char * const *pname;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return;
+
+	pname = data->parents;
+	while (*pname) {
+		num_parents++;
+		pname++;
+	}
+
+	mux->mask = num_parents;
+	mux->mask = (1 << fls(mux->mask)) - 1;
+
+	mux->shift = data->bit;
+	mux->reg.ptr = reg;
+
+	if (_ti_clkctrl_clk_register(provider, node, &mux->hw, offset,
+				     data->bit, data->parents, num_parents,
+				     &ti_clk_mux_ops))
+		kfree(mux);
+}
+
+static void __init
+_ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider,
+		      struct device_node *node, u16 offset,
+		      const struct omap_clkctrl_bit_data *data,
+		      void __iomem *reg)
+{
+	struct clk_omap_divider *div;
+	const struct omap_clkctrl_div_data *div_data = data->data;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return;
+
+	div->reg.ptr = reg;
+	div->shift = data->bit;
+
+	if (ti_clk_parse_divider_data((int *)div_data->dividers,
+				      div_data->max_div, 0, 0,
+				      &div->width, &div->table)) {
+		pr_err("%s: Data parsing for %s:%04x:%d failed\n", __func__,
+		       node->name, offset, data->bit);
+		kfree(div);
+		return;
+	}
+
+	if (_ti_clkctrl_clk_register(provider, node, &div->hw, offset,
+				     data->bit, data->parents, 1,
+				     &ti_clk_divider_ops))
+		kfree(div);
+}
+
+static void __init
+_ti_clkctrl_setup_subclks(struct omap_clkctrl_provider *provider,
+			  struct device_node *node,
+			  const struct omap_clkctrl_reg_data *data,
+			  void __iomem *reg)
+{
+	const struct omap_clkctrl_bit_data *bits = data->bit_data;
+
+	if (!bits)
+		return;
+
+	while (bits->bit) {
+		switch (bits->type) {
+		case TI_CLK_GATE:
+			_ti_clkctrl_setup_gate(provider, node, data->offset,
+					       bits, reg);
+			break;
+
+		case TI_CLK_DIVIDER:
+			_ti_clkctrl_setup_div(provider, node, data->offset,
+					      bits, reg);
+			break;
+
+		case TI_CLK_MUX:
+			_ti_clkctrl_setup_mux(provider, node, data->offset,
+					      bits, reg);
+			break;
+
+		default:
+			pr_err("%s: bad subclk type: %d\n", __func__,
+			       bits->type);
+			return;
+		}
+		bits++;
+	}
+}
+
+static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
+{
+	struct omap_clkctrl_provider *provider;
+	const struct omap_clkctrl_data *data = default_clkctrl_data;
+	const struct omap_clkctrl_reg_data *reg_data;
+	struct clk_init_data init = { NULL };
+	struct clk_hw_omap *hw;
+	struct clk *clk;
+	struct omap_clkctrl_clk *clkctrl_clk;
+	const __be32 *addrp;
+	u32 addr;
+
+	addrp = of_get_address(node, 0, NULL, NULL);
+	addr = (u32)of_translate_address(node, addrp);
+
+	while (data->addr) {
+		if (addr == data->addr)
+			break;
+
+		data++;
+	}
+
+	if (!data->addr) {
+		pr_err("%s not found from clkctrl data.\n", node->name);
+		return;
+	}
+
+	provider = kzalloc(sizeof(*provider), GFP_KERNEL);
+	if (!provider)
+		return;
+
+	provider->base = of_iomap(node, 0);
+
+	INIT_LIST_HEAD(&provider->clocks);
+
+	/* Generate clocks */
+	reg_data = data->regs;
+
+	while (reg_data->parent) {
+		hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+		if (!hw)
+			return;
+
+		hw->enable_reg.ptr = provider->base + reg_data->offset;
+
+		_ti_clkctrl_setup_subclks(provider, node, reg_data,
+					  hw->enable_reg.ptr);
+
+		if (reg_data->flags & CLKF_SW_SUP)
+			hw->enable_bit = MODULEMODE_SWCTRL;
+		if (reg_data->flags & CLKF_HW_SUP)
+			hw->enable_bit = MODULEMODE_HWCTRL;
+		if (reg_data->flags & CLKF_NO_IDLEST)
+			hw->flags |= NO_IDLEST;
+
+		init.parent_names = &reg_data->parent;
+		init.num_parents = 1;
+		init.flags = 0;
+		init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d",
+				      node->parent->name, node->name,
+				      reg_data->offset, 0);
+		clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL);
+		if (!init.name || !clkctrl_clk) {
+			kfree(init.name);
+			kfree(hw);
+			return;
+		}
+		init.ops = &omap4_clkctrl_clk_ops;
+		hw->hw.init = &init;
+
+		clk = ti_clk_register(NULL, &hw->hw, init.name);
+		if (IS_ERR_OR_NULL(clk))
+			return;
+
+		clkctrl_clk->reg_offset = reg_data->offset;
+		clkctrl_clk->clk = &hw->hw;
+
+		list_add(&clkctrl_clk->node, &provider->clocks);
+
+		reg_data++;
+	}
+
+	of_clk_add_hw_provider(node, _ti_omap4_clkctrl_xlate, provider);
+}
+CLK_OF_DECLARE(ti_omap4_clkctrl_clock, "ti,clkctrl",
+	       _ti_omap4_clkctrl_setup);
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 3f7b265..1aa8d57 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -203,6 +203,35 @@ struct ti_dt_clk {
 		.node_name = name,	\
 	}
 
+/* CLKCTRL type definitions */
+struct omap_clkctrl_div_data {
+	const int *dividers;
+	int max_div;
+};
+
+struct omap_clkctrl_bit_data {
+	u8 bit;
+	u8 type;
+	const char * const *parents;
+	const void *data;
+};
+
+struct omap_clkctrl_reg_data {
+	u16 offset;
+	const struct omap_clkctrl_bit_data *bit_data;
+	u16 flags;
+	const char *parent;
+};
+
+struct omap_clkctrl_data {
+	u32 addr;
+	const struct omap_clkctrl_reg_data *regs;
+};
+
+#define CLKF_SW_SUP	BIT(0)
+#define CLKF_HW_SUP	BIT(1)
+#define CLKF_NO_IDLEST	BIT(2)
+
 typedef void (*ti_of_clk_init_cb_t)(struct clk_hw *, struct device_node *);
 
 struct clk *ti_clk_register_gate(struct ti_clk *setup);
-- 
1.9.1

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

* [PATCHv3 3/4] dt-bindings: clk: add omap4 clkctrl definitions
  2017-05-17 15:50 [PATCHv3 0/4] clk: ti: add support for clkctrl clocks Tero Kristo
  2017-05-17 15:50 ` [PATCHv3 1/4] Documentation: dt-bindings: Add binding documentation for TI " Tero Kristo
  2017-05-17 15:50 ` [PATCHv3 2/4] clk: ti: add support for " Tero Kristo
@ 2017-05-17 15:50 ` Tero Kristo
  2017-05-17 15:50 ` [PATCHv3 4/4] clk: ti: omap4: add clkctrl clock data Tero Kristo
  3 siblings, 0 replies; 7+ messages in thread
From: Tero Kristo @ 2017-05-17 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

Contains offsets for all omap4 clkctrl main and optional clocks.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 include/dt-bindings/clock/omap4.h | 146 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 146 insertions(+)
 create mode 100644 include/dt-bindings/clock/omap4.h

diff --git a/include/dt-bindings/clock/omap4.h b/include/dt-bindings/clock/omap4.h
new file mode 100644
index 0000000..e86c758
--- /dev/null
+++ b/include/dt-bindings/clock/omap4.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2017 Texas Instruments, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __DT_BINDINGS_CLK_OMAP4_H
+#define __DT_BINDINGS_CLK_OMAP4_H
+
+#define OMAP4_CLKCTRL_OFFSET	0x20
+#define OMAP4_CLKCTRL_INDEX(offset)	((offset) - OMAP4_CLKCTRL_OFFSET)
+
+/* mpuss clocks */
+#define OMAP4_MPU_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+
+/* tesla clocks */
+#define OMAP4_DSP_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+
+/* abe clocks */
+#define OMAP4_L4_ABE_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_AESS_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_MCPDM_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_DMIC_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x38)
+#define OMAP4_MCASP_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x40)
+#define OMAP4_MCBSP1_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x48)
+#define OMAP4_MCBSP2_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x50)
+#define OMAP4_MCBSP3_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x58)
+#define OMAP4_SLIMBUS1_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x60)
+#define OMAP4_TIMER5_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x68)
+#define OMAP4_TIMER6_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x70)
+#define OMAP4_TIMER7_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x78)
+#define OMAP4_TIMER8_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x80)
+#define OMAP4_WD_TIMER3_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x88)
+
+/* l4_ao clocks */
+#define OMAP4_SMARTREFLEX_MPU_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_SMARTREFLEX_IVA_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_SMARTREFLEX_CORE_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x38)
+
+/* l3_1 clocks */
+#define OMAP4_L3_MAIN_1_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l3_2 clocks */
+#define OMAP4_L3_MAIN_2_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_GPMC_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_OCMC_RAM_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x30)
+
+/* ducati clocks */
+#define OMAP4_IPU_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l3_dma clocks */
+#define OMAP4_DMA_SYSTEM_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l3_emif clocks */
+#define OMAP4_DMM_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_EMIF1_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_EMIF2_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x38)
+
+/* d2d clocks */
+#define OMAP4_C2C_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l4_cfg clocks */
+#define OMAP4_L4_CFG_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_SPINLOCK_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_MAILBOX_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x30)
+
+/* l3_instr clocks */
+#define OMAP4_L3_MAIN_3_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_L3_INSTR_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_OCP_WP_NOC_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x40)
+
+/* ivahd clocks */
+#define OMAP4_IVA_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_SL2IF_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x28)
+
+/* iss clocks */
+#define OMAP4_ISS_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_FDIF_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x28)
+
+/* l3_dss clocks */
+#define OMAP4_DSS_CORE_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l3_gfx clocks */
+#define OMAP4_GPU_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l3_init clocks */
+#define OMAP4_MMC1_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_MMC2_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_HSI_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x38)
+#define OMAP4_USB_HOST_HS_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x58)
+#define OMAP4_USB_OTG_HS_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x60)
+#define OMAP4_USB_TLL_HS_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x68)
+#define OMAP4_USB_HOST_FS_CLKCTRL	OMAP4_CLKCTRL_INDEX(0xd0)
+#define OMAP4_OCP2SCP_USB_PHY_CLKCTRL	OMAP4_CLKCTRL_INDEX(0xe0)
+
+/* l4_per clocks */
+#define OMAP4_TIMER10_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_TIMER11_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_TIMER2_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x38)
+#define OMAP4_TIMER3_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x40)
+#define OMAP4_TIMER4_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x48)
+#define OMAP4_TIMER9_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x50)
+#define OMAP4_ELM_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x58)
+#define OMAP4_GPIO2_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x60)
+#define OMAP4_GPIO3_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x68)
+#define OMAP4_GPIO4_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x70)
+#define OMAP4_GPIO5_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x78)
+#define OMAP4_GPIO6_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x80)
+#define OMAP4_HDQ1W_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x88)
+#define OMAP4_I2C1_CLKCTRL	OMAP4_CLKCTRL_INDEX(0xa0)
+#define OMAP4_I2C2_CLKCTRL	OMAP4_CLKCTRL_INDEX(0xa8)
+#define OMAP4_I2C3_CLKCTRL	OMAP4_CLKCTRL_INDEX(0xb0)
+#define OMAP4_I2C4_CLKCTRL	OMAP4_CLKCTRL_INDEX(0xb8)
+#define OMAP4_L4_PER_CLKCTRL	OMAP4_CLKCTRL_INDEX(0xc0)
+#define OMAP4_MCBSP4_CLKCTRL	OMAP4_CLKCTRL_INDEX(0xe0)
+#define OMAP4_MCSPI1_CLKCTRL	OMAP4_CLKCTRL_INDEX(0xf0)
+#define OMAP4_MCSPI2_CLKCTRL	OMAP4_CLKCTRL_INDEX(0xf8)
+#define OMAP4_MCSPI3_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x100)
+#define OMAP4_MCSPI4_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x108)
+#define OMAP4_MMC3_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x120)
+#define OMAP4_MMC4_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x128)
+#define OMAP4_SLIMBUS2_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x138)
+#define OMAP4_UART1_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x140)
+#define OMAP4_UART2_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x148)
+#define OMAP4_UART3_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x150)
+#define OMAP4_UART4_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x158)
+#define OMAP4_MMC5_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x160)
+
+/* l4_wkup clocks */
+#define OMAP4_L4_WKUP_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_WD_TIMER2_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_GPIO1_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x38)
+#define OMAP4_TIMER1_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x40)
+#define OMAP4_COUNTER_32K_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x50)
+#define OMAP4_KBD_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x78)
+
+/* emu_sys clocks */
+#define OMAP4_DEBUGSS_CLKCTRL	OMAP4_CLKCTRL_INDEX(0x20)
+
+#endif
-- 
1.9.1

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

* [PATCHv3 4/4] clk: ti: omap4: add clkctrl clock data
  2017-05-17 15:50 [PATCHv3 0/4] clk: ti: add support for clkctrl clocks Tero Kristo
                   ` (2 preceding siblings ...)
  2017-05-17 15:50 ` [PATCHv3 3/4] dt-bindings: clk: add omap4 clkctrl definitions Tero Kristo
@ 2017-05-17 15:50 ` Tero Kristo
  2017-05-19 22:15   ` Tony Lindgren
  3 siblings, 1 reply; 7+ messages in thread
From: Tero Kristo @ 2017-05-17 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

Add data for omap4 clkctrl clocks, and register it within the clkctrl
driver.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/ti/clk-44xx.c | 663 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/ti/clkctrl.c  |   5 +
 drivers/clk/ti/clock.h    |   2 +
 3 files changed, 670 insertions(+)

diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index 1c8bb83..2005f03 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -15,6 +15,7 @@
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clk/ti.h>
+#include <dt-bindings/clock/omap4.h>
 
 #include "clock.h"
 
@@ -33,6 +34,668 @@
  */
 #define OMAP4_DPLL_USB_DEFFREQ				960000000
 
+static const struct omap_clkctrl_reg_data omap4_mpuss_clkctrl_regs[] __initconst = {
+	{ OMAP4_MPU_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_mpu_m2_ck" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_tesla_clkctrl_regs[] __initconst = {
+	{ OMAP4_DSP_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_m4x2_ck" },
+	{ 0 },
+};
+
+static const char * const omap4_aess_fclk_parents[] __initconst = {
+	"abe_clk",
+	NULL,
+};
+
+static const struct omap_clkctrl_div_data omap4_aess_fclk_data __initconst = {
+	.max_div = 2,
+};
+
+static const struct omap_clkctrl_bit_data omap4_aess_bit_data[] __initconst = {
+	{ 24, TI_CLK_DIVIDER, omap4_aess_fclk_parents, &omap4_aess_fclk_data },
+	{ 0 },
+};
+
+static const char * const omap4_func_dmic_abe_gfclk_parents[] __initconst = {
+	"dmic_sync_mux_ck",
+	"pad_clks_ck",
+	"slimbus_clk",
+	NULL,
+};
+
+static const char * const omap4_dmic_sync_mux_ck_parents[] __initconst = {
+	"abe_24m_fclk",
+	"syc_clk_div_ck",
+	"func_24m_clk",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_dmic_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_func_dmic_abe_gfclk_parents, NULL },
+	{ 26, TI_CLK_MUX, omap4_dmic_sync_mux_ck_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_func_mcasp_abe_gfclk_parents[] __initconst = {
+	"mcasp_sync_mux_ck",
+	"pad_clks_ck",
+	"slimbus_clk",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mcasp_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_func_mcasp_abe_gfclk_parents, NULL },
+	{ 26, TI_CLK_MUX, omap4_dmic_sync_mux_ck_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_func_mcbsp1_gfclk_parents[] __initconst = {
+	"mcbsp1_sync_mux_ck",
+	"pad_clks_ck",
+	"slimbus_clk",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mcbsp1_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_func_mcbsp1_gfclk_parents, NULL },
+	{ 26, TI_CLK_MUX, omap4_dmic_sync_mux_ck_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_func_mcbsp2_gfclk_parents[] __initconst = {
+	"mcbsp2_sync_mux_ck",
+	"pad_clks_ck",
+	"slimbus_clk",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mcbsp2_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_func_mcbsp2_gfclk_parents, NULL },
+	{ 26, TI_CLK_MUX, omap4_dmic_sync_mux_ck_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_func_mcbsp3_gfclk_parents[] __initconst = {
+	"mcbsp3_sync_mux_ck",
+	"pad_clks_ck",
+	"slimbus_clk",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mcbsp3_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_func_mcbsp3_gfclk_parents, NULL },
+	{ 26, TI_CLK_MUX, omap4_dmic_sync_mux_ck_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_slimbus1_fclk_0_parents[] __initconst = {
+	"abe_24m_fclk",
+	NULL,
+};
+
+static const char * const omap4_slimbus1_fclk_1_parents[] __initconst = {
+	"func_24m_clk",
+	NULL,
+};
+
+static const char * const omap4_slimbus1_fclk_2_parents[] __initconst = {
+	"pad_clks_ck",
+	NULL,
+};
+
+static const char * const omap4_slimbus1_slimbus_clk_parents[] __initconst = {
+	"slimbus_clk",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_slimbus1_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_slimbus1_fclk_0_parents, NULL },
+	{ 9, TI_CLK_GATE, omap4_slimbus1_fclk_1_parents, NULL },
+	{ 10, TI_CLK_GATE, omap4_slimbus1_fclk_2_parents, NULL },
+	{ 11, TI_CLK_GATE, omap4_slimbus1_slimbus_clk_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_timer5_sync_mux_parents[] __initconst = {
+	"syc_clk_div_ck",
+	"sys_32k_ck",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer5_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_timer5_sync_mux_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer6_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_timer5_sync_mux_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer7_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_timer5_sync_mux_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer8_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_timer5_sync_mux_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_abe_clkctrl_regs[] __initconst = {
+	{ OMAP4_L4_ABE_CLKCTRL, NULL, 0, "ocp_abe_iclk" },
+	{ OMAP4_AESS_CLKCTRL, omap4_aess_bit_data, CLKF_SW_SUP, "aess_fclk" },
+	{ OMAP4_MCPDM_CLKCTRL, NULL, CLKF_SW_SUP, "pad_clks_ck" },
+	{ OMAP4_DMIC_CLKCTRL, omap4_dmic_bit_data, CLKF_SW_SUP, "func_dmic_abe_gfclk" },
+	{ OMAP4_MCASP_CLKCTRL, omap4_mcasp_bit_data, CLKF_SW_SUP, "func_mcasp_abe_gfclk" },
+	{ OMAP4_MCBSP1_CLKCTRL, omap4_mcbsp1_bit_data, CLKF_SW_SUP, "func_mcbsp1_gfclk" },
+	{ OMAP4_MCBSP2_CLKCTRL, omap4_mcbsp2_bit_data, CLKF_SW_SUP, "func_mcbsp2_gfclk" },
+	{ OMAP4_MCBSP3_CLKCTRL, omap4_mcbsp3_bit_data, CLKF_SW_SUP, "func_mcbsp3_gfclk" },
+	{ OMAP4_SLIMBUS1_CLKCTRL, omap4_slimbus1_bit_data, CLKF_SW_SUP, "slimbus1_fclk_0" },
+	{ OMAP4_TIMER5_CLKCTRL, omap4_timer5_bit_data, CLKF_SW_SUP, "timer5_sync_mux" },
+	{ OMAP4_TIMER6_CLKCTRL, omap4_timer6_bit_data, CLKF_SW_SUP, "timer6_sync_mux" },
+	{ OMAP4_TIMER7_CLKCTRL, omap4_timer7_bit_data, CLKF_SW_SUP, "timer7_sync_mux" },
+	{ OMAP4_TIMER8_CLKCTRL, omap4_timer8_bit_data, CLKF_SW_SUP, "timer8_sync_mux" },
+	{ OMAP4_WD_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l4_ao_clkctrl_regs[] __initconst = {
+	{ OMAP4_SMARTREFLEX_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "l4_wkup_clk_mux_ck" },
+	{ OMAP4_SMARTREFLEX_IVA_CLKCTRL, NULL, CLKF_SW_SUP, "l4_wkup_clk_mux_ck" },
+	{ OMAP4_SMARTREFLEX_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "l4_wkup_clk_mux_ck" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_1_clkctrl_regs[] __initconst = {
+	{ OMAP4_L3_MAIN_1_CLKCTRL, NULL, 0, "l3_div_ck" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_2_clkctrl_regs[] __initconst = {
+	{ OMAP4_L3_MAIN_2_CLKCTRL, NULL, 0, "l3_div_ck" },
+	{ OMAP4_GPMC_CLKCTRL, NULL, CLKF_HW_SUP, "l3_div_ck" },
+	{ OMAP4_OCMC_RAM_CLKCTRL, NULL, 0, "l3_div_ck" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_ducati_clkctrl_regs[] __initconst = {
+	{ OMAP4_IPU_CLKCTRL, NULL, CLKF_HW_SUP, "ducati_clk_mux_ck" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_dma_clkctrl_regs[] __initconst = {
+	{ OMAP4_DMA_SYSTEM_CLKCTRL, NULL, 0, "l3_div_ck" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_emif_clkctrl_regs[] __initconst = {
+	{ OMAP4_DMM_CLKCTRL, NULL, 0, "l3_div_ck" },
+	{ OMAP4_EMIF1_CLKCTRL, NULL, CLKF_HW_SUP, "ddrphy_ck" },
+	{ OMAP4_EMIF2_CLKCTRL, NULL, CLKF_HW_SUP, "ddrphy_ck" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_d2d_clkctrl_regs[] __initconst = {
+	{ OMAP4_C2C_CLKCTRL, NULL, 0, "div_core_ck" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l4_cfg_clkctrl_regs[] __initconst = {
+	{ OMAP4_L4_CFG_CLKCTRL, NULL, 0, "l4_div_ck" },
+	{ OMAP4_SPINLOCK_CLKCTRL, NULL, 0, "l4_div_ck" },
+	{ OMAP4_MAILBOX_CLKCTRL, NULL, 0, "l4_div_ck" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_instr_clkctrl_regs[] __initconst = {
+	{ OMAP4_L3_MAIN_3_CLKCTRL, NULL, CLKF_HW_SUP, "l3_div_ck" },
+	{ OMAP4_L3_INSTR_CLKCTRL, NULL, CLKF_HW_SUP, "l3_div_ck" },
+	{ OMAP4_OCP_WP_NOC_CLKCTRL, NULL, CLKF_HW_SUP, "l3_div_ck" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_ivahd_clkctrl_regs[] __initconst = {
+	{ OMAP4_IVA_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_m5x2_ck" },
+	{ OMAP4_SL2IF_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_m5x2_ck" },
+	{ 0 },
+};
+
+static const char * const omap4_iss_ctrlclk_parents[] __initconst = {
+	"func_96m_fclk",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_iss_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_iss_ctrlclk_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_fdif_fck_parents[] __initconst = {
+	"dpll_per_m4x2_ck",
+	NULL,
+};
+
+static const struct omap_clkctrl_div_data omap4_fdif_fck_data __initconst = {
+	.max_div = 4,
+};
+
+static const struct omap_clkctrl_bit_data omap4_fdif_bit_data[] __initconst = {
+	{ 24, TI_CLK_DIVIDER, omap4_fdif_fck_parents, &omap4_fdif_fck_data },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_iss_clkctrl_regs[] __initconst = {
+	{ OMAP4_ISS_CLKCTRL, omap4_iss_bit_data, CLKF_SW_SUP, "ducati_clk_mux_ck" },
+	{ OMAP4_FDIF_CLKCTRL, omap4_fdif_bit_data, CLKF_SW_SUP, "fdif_fck" },
+	{ 0 },
+};
+
+static const char * const omap4_dss_dss_clk_parents[] __initconst = {
+	"dpll_per_m5x2_ck",
+	NULL,
+};
+
+static const char * const omap4_dss_48mhz_clk_parents[] __initconst = {
+	"func_48mc_fclk",
+	NULL,
+};
+
+static const char * const omap4_dss_sys_clk_parents[] __initconst = {
+	"syc_clk_div_ck",
+	NULL,
+};
+
+static const char * const omap4_dss_tv_clk_parents[] __initconst = {
+	"extalt_clkin_ck",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_dss_core_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_dss_dss_clk_parents, NULL },
+	{ 9, TI_CLK_GATE, omap4_dss_48mhz_clk_parents, NULL },
+	{ 10, TI_CLK_GATE, omap4_dss_sys_clk_parents, NULL },
+	{ 11, TI_CLK_GATE, omap4_dss_tv_clk_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_dss_clkctrl_regs[] __initconst = {
+	{ OMAP4_DSS_CORE_CLKCTRL, omap4_dss_core_bit_data, CLKF_SW_SUP, "dss_dss_clk" },
+	{ 0 },
+};
+
+static const char * const omap4_sgx_clk_mux_parents[] __initconst = {
+	"dpll_core_m7x2_ck",
+	"dpll_per_m7x2_ck",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpu_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_sgx_clk_mux_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_gfx_clkctrl_regs[] __initconst = {
+	{ OMAP4_GPU_CLKCTRL, omap4_gpu_bit_data, CLKF_SW_SUP, "sgx_clk_mux" },
+	{ 0 },
+};
+
+static const char * const omap4_hsmmc1_fclk_parents[] __initconst = {
+	"func_64m_fclk",
+	"func_96m_fclk",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mmc1_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_hsmmc1_fclk_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_mmc2_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_hsmmc1_fclk_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_hsi_fck_parents[] __initconst = {
+	"dpll_per_m2x2_ck",
+	NULL,
+};
+
+static const struct omap_clkctrl_div_data omap4_hsi_fck_data __initconst = {
+	.max_div = 4,
+};
+
+static const struct omap_clkctrl_bit_data omap4_hsi_bit_data[] __initconst = {
+	{ 24, TI_CLK_DIVIDER, omap4_hsi_fck_parents, &omap4_hsi_fck_data },
+	{ 0 },
+};
+
+static const char * const omap4_usb_host_hs_utmi_p1_clk_parents[] __initconst = {
+	"utmi_p1_gfclk",
+	NULL,
+};
+
+static const char * const omap4_usb_host_hs_utmi_p2_clk_parents[] __initconst = {
+	"utmi_p2_gfclk",
+	NULL,
+};
+
+static const char * const omap4_usb_host_hs_utmi_p3_clk_parents[] __initconst = {
+	"init_60m_fclk",
+	NULL,
+};
+
+static const char * const omap4_usb_host_hs_hsic480m_p1_clk_parents[] __initconst = {
+	"dpll_usb_m2_ck",
+	NULL,
+};
+
+static const char * const omap4_utmi_p1_gfclk_parents[] __initconst = {
+	"init_60m_fclk",
+	"xclk60mhsp1_ck",
+	NULL,
+};
+
+static const char * const omap4_utmi_p2_gfclk_parents[] __initconst = {
+	"init_60m_fclk",
+	"xclk60mhsp2_ck",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_usb_host_hs_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_usb_host_hs_utmi_p1_clk_parents, NULL },
+	{ 9, TI_CLK_GATE, omap4_usb_host_hs_utmi_p2_clk_parents, NULL },
+	{ 10, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+	{ 11, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+	{ 12, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+	{ 13, TI_CLK_GATE, omap4_usb_host_hs_hsic480m_p1_clk_parents, NULL },
+	{ 14, TI_CLK_GATE, omap4_usb_host_hs_hsic480m_p1_clk_parents, NULL },
+	{ 15, TI_CLK_GATE, omap4_dss_48mhz_clk_parents, NULL },
+	{ 24, TI_CLK_MUX, omap4_utmi_p1_gfclk_parents, NULL },
+	{ 25, TI_CLK_MUX, omap4_utmi_p2_gfclk_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_usb_otg_hs_xclk_parents[] __initconst = {
+	"otg_60m_gfclk",
+	NULL,
+};
+
+static const char * const omap4_otg_60m_gfclk_parents[] __initconst = {
+	"utmi_phy_clkout_ck",
+	"xclk60motg_ck",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_usb_otg_hs_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_usb_otg_hs_xclk_parents, NULL },
+	{ 24, TI_CLK_MUX, omap4_otg_60m_gfclk_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_usb_tll_hs_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+	{ 9, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+	{ 10, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_ocp2scp_usb_phy_phy_48m_parents[] __initconst = {
+	"func_48m_fclk",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_ocp2scp_usb_phy_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_ocp2scp_usb_phy_phy_48m_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_init_clkctrl_regs[] __initconst = {
+	{ OMAP4_MMC1_CLKCTRL, omap4_mmc1_bit_data, CLKF_SW_SUP, "hsmmc1_fclk" },
+	{ OMAP4_MMC2_CLKCTRL, omap4_mmc2_bit_data, CLKF_SW_SUP, "hsmmc2_fclk" },
+	{ OMAP4_HSI_CLKCTRL, omap4_hsi_bit_data, CLKF_HW_SUP, "hsi_fck" },
+	{ OMAP4_USB_HOST_HS_CLKCTRL, omap4_usb_host_hs_bit_data, CLKF_SW_SUP, "init_60m_fclk" },
+	{ OMAP4_USB_OTG_HS_CLKCTRL, omap4_usb_otg_hs_bit_data, CLKF_HW_SUP, "l3_div_ck" },
+	{ OMAP4_USB_TLL_HS_CLKCTRL, omap4_usb_tll_hs_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+	{ OMAP4_USB_HOST_FS_CLKCTRL, NULL, CLKF_SW_SUP, "func_48mc_fclk" },
+	{ OMAP4_OCP2SCP_USB_PHY_CLKCTRL, omap4_ocp2scp_usb_phy_bit_data, CLKF_HW_SUP, "ocp2scp_usb_phy_phy_48m" },
+	{ 0 },
+};
+
+static const char * const omap4_cm2_dm10_mux_parents[] __initconst = {
+	"sys_clkin_ck",
+	"sys_32k_ck",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer10_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer11_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer2_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer3_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer4_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer9_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_gpio2_dbclk_parents[] __initconst = {
+	"sys_32k_ck",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio2_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio3_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio4_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio5_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio6_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_per_mcbsp4_gfclk_parents[] __initconst = {
+	"mcbsp4_sync_mux_ck",
+	"pad_clks_ck",
+	NULL,
+};
+
+static const char * const omap4_mcbsp4_sync_mux_ck_parents[] __initconst = {
+	"func_96m_fclk",
+	"per_abe_nc_fclk",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mcbsp4_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_per_mcbsp4_gfclk_parents, NULL },
+	{ 25, TI_CLK_MUX, omap4_mcbsp4_sync_mux_ck_parents, NULL },
+	{ 0 },
+};
+
+static const char * const omap4_slimbus2_fclk_0_parents[] __initconst = {
+	"func_24mc_fclk",
+	NULL,
+};
+
+static const char * const omap4_slimbus2_fclk_1_parents[] __initconst = {
+	"per_abe_24m_fclk",
+	NULL,
+};
+
+static const char * const omap4_slimbus2_slimbus_clk_parents[] __initconst = {
+	"pad_slimbus_core_clks_ck",
+	NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_slimbus2_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_slimbus2_fclk_0_parents, NULL },
+	{ 9, TI_CLK_GATE, omap4_slimbus2_fclk_1_parents, NULL },
+	{ 10, TI_CLK_GATE, omap4_slimbus2_slimbus_clk_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l4_per_clkctrl_regs[] __initconst = {
+	{ OMAP4_TIMER10_CLKCTRL, omap4_timer10_bit_data, CLKF_SW_SUP, "cm2_dm10_mux" },
+	{ OMAP4_TIMER11_CLKCTRL, omap4_timer11_bit_data, CLKF_SW_SUP, "cm2_dm11_mux" },
+	{ OMAP4_TIMER2_CLKCTRL, omap4_timer2_bit_data, CLKF_SW_SUP, "cm2_dm2_mux" },
+	{ OMAP4_TIMER3_CLKCTRL, omap4_timer3_bit_data, CLKF_SW_SUP, "cm2_dm3_mux" },
+	{ OMAP4_TIMER4_CLKCTRL, omap4_timer4_bit_data, CLKF_SW_SUP, "cm2_dm4_mux" },
+	{ OMAP4_TIMER9_CLKCTRL, omap4_timer9_bit_data, CLKF_SW_SUP, "cm2_dm9_mux" },
+	{ OMAP4_ELM_CLKCTRL, NULL, 0, "l4_div_ck" },
+	{ OMAP4_GPIO2_CLKCTRL, omap4_gpio2_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+	{ OMAP4_GPIO3_CLKCTRL, omap4_gpio3_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+	{ OMAP4_GPIO4_CLKCTRL, omap4_gpio4_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+	{ OMAP4_GPIO5_CLKCTRL, omap4_gpio5_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+	{ OMAP4_GPIO6_CLKCTRL, omap4_gpio6_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+	{ OMAP4_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_fclk" },
+	{ OMAP4_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+	{ OMAP4_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+	{ OMAP4_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+	{ OMAP4_I2C4_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+	{ OMAP4_L4_PER_CLKCTRL, NULL, 0, "l4_div_ck" },
+	{ OMAP4_MCBSP4_CLKCTRL, omap4_mcbsp4_bit_data, CLKF_SW_SUP, "per_mcbsp4_gfclk" },
+	{ OMAP4_MCSPI1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+	{ OMAP4_MCSPI2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+	{ OMAP4_MCSPI3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+	{ OMAP4_MCSPI4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+	{ OMAP4_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+	{ OMAP4_MMC4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+	{ OMAP4_SLIMBUS2_CLKCTRL, omap4_slimbus2_bit_data, CLKF_SW_SUP, "slimbus2_fclk_0" },
+	{ OMAP4_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+	{ OMAP4_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+	{ OMAP4_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+	{ OMAP4_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+	{ OMAP4_MMC5_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio1_bit_data[] __initconst = {
+	{ 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer1_bit_data[] __initconst = {
+	{ 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l4_wkup_clkctrl_regs[] __initconst = {
+	{ OMAP4_L4_WKUP_CLKCTRL, NULL, 0, "l4_wkup_clk_mux_ck" },
+	{ OMAP4_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
+	{ OMAP4_GPIO1_CLKCTRL, omap4_gpio1_bit_data, CLKF_HW_SUP, "l4_wkup_clk_mux_ck" },
+	{ OMAP4_TIMER1_CLKCTRL, omap4_timer1_bit_data, CLKF_SW_SUP, "dmt1_clk_mux" },
+	{ OMAP4_COUNTER_32K_CLKCTRL, NULL, 0, "sys_32k_ck" },
+	{ OMAP4_KBD_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
+	{ 0 },
+};
+
+static const char * const omap4_pmd_stm_clock_mux_ck_parents[] __initconst = {
+	"sys_clkin_ck",
+	"dpll_core_m6x2_ck",
+	"tie_low_clock_ck",
+	NULL,
+};
+
+static const char * const omap4_trace_clk_div_div_ck_parents[] __initconst = {
+	"pmd_trace_clk_mux_ck",
+	NULL,
+};
+
+static const int omap4_trace_clk_div_div_ck_divs[] __initconst = {
+	0,
+	1,
+	2,
+	0,
+	4,
+	-1,
+};
+
+static const struct omap_clkctrl_div_data omap4_trace_clk_div_div_ck_data __initconst = {
+	.dividers = omap4_trace_clk_div_div_ck_divs,
+};
+
+static const char * const omap4_stm_clk_div_ck_parents[] __initconst = {
+	"pmd_stm_clock_mux_ck",
+	NULL,
+};
+
+static const struct omap_clkctrl_div_data omap4_stm_clk_div_ck_data __initconst = {
+	.max_div = 64,
+};
+
+static const struct omap_clkctrl_bit_data omap4_debugss_bit_data[] __initconst = {
+	{ 20, TI_CLK_MUX, omap4_pmd_stm_clock_mux_ck_parents, NULL },
+	{ 22, TI_CLK_MUX, omap4_pmd_stm_clock_mux_ck_parents, NULL },
+	{ 24, TI_CLK_DIVIDER, omap4_trace_clk_div_div_ck_parents, &omap4_trace_clk_div_div_ck_data },
+	{ 27, TI_CLK_DIVIDER, omap4_stm_clk_div_ck_parents, &omap4_stm_clk_div_ck_data },
+	{ 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_emu_sys_clkctrl_regs[] __initconst = {
+	{ OMAP4_DEBUGSS_CLKCTRL, omap4_debugss_bit_data, 0, "trace_clk_div_ck" },
+	{ 0 },
+};
+
+const struct omap_clkctrl_data omap4_clkctrl_data[] __initconst = {
+	{ 0x4a004320, omap4_mpuss_clkctrl_regs },
+	{ 0x4a004420, omap4_tesla_clkctrl_regs },
+	{ 0x4a004520, omap4_abe_clkctrl_regs },
+	{ 0x4a008620, omap4_l4_ao_clkctrl_regs },
+	{ 0x4a008720, omap4_l3_1_clkctrl_regs },
+	{ 0x4a008820, omap4_l3_2_clkctrl_regs },
+	{ 0x4a008920, omap4_ducati_clkctrl_regs },
+	{ 0x4a008a20, omap4_l3_dma_clkctrl_regs },
+	{ 0x4a008b20, omap4_l3_emif_clkctrl_regs },
+	{ 0x4a008c20, omap4_d2d_clkctrl_regs },
+	{ 0x4a008d20, omap4_l4_cfg_clkctrl_regs },
+	{ 0x4a008e20, omap4_l3_instr_clkctrl_regs },
+	{ 0x4a008f20, omap4_ivahd_clkctrl_regs },
+	{ 0x4a009020, omap4_iss_clkctrl_regs },
+	{ 0x4a009120, omap4_l3_dss_clkctrl_regs },
+	{ 0x4a009220, omap4_l3_gfx_clkctrl_regs },
+	{ 0x4a009320, omap4_l3_init_clkctrl_regs },
+	{ 0x4a009420, omap4_l4_per_clkctrl_regs },
+	{ 0x4a307820, omap4_l4_wkup_clkctrl_regs },
+	{ 0x4a307a20, omap4_emu_sys_clkctrl_regs },
+	{ 0 },
+};
+
 static struct ti_dt_clk omap44xx_clks[] = {
 	DT_CLK("smp_twd", NULL, "mpu_periphclk"),
 	DT_CLK("omapdss_dss", "ick", "dss_fck"),
diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c
index cfdd97f..00332a6 100644
--- a/drivers/clk/ti/clkctrl.c
+++ b/drivers/clk/ti/clkctrl.c
@@ -408,6 +408,11 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
 	addrp = of_get_address(node, 0, NULL, NULL);
 	addr = (u32)of_translate_address(node, addrp);
 
+#ifdef CONFIG_ARCH_OMAP4
+	if (of_machine_is_compatible("ti,omap4"))
+		data = omap4_clkctrl_data;
+#endif
+
 	while (data->addr) {
 		if (addr == data->addr)
 			break;
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 1aa8d57..561dbe9 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -228,6 +228,8 @@ struct omap_clkctrl_data {
 	const struct omap_clkctrl_reg_data *regs;
 };
 
+extern const struct omap_clkctrl_data omap4_clkctrl_data[];
+
 #define CLKF_SW_SUP	BIT(0)
 #define CLKF_HW_SUP	BIT(1)
 #define CLKF_NO_IDLEST	BIT(2)
-- 
1.9.1

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

* [PATCHv3 2/4] clk: ti: add support for clkctrl clocks
  2017-05-17 15:50 ` [PATCHv3 2/4] clk: ti: add support for " Tero Kristo
@ 2017-05-19 22:14   ` Tony Lindgren
  0 siblings, 0 replies; 7+ messages in thread
From: Tony Lindgren @ 2017-05-19 22:14 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [170517 08:54]:
> Previously, hwmod core has been used for controlling the hwmod level
> clocks directly. This has certain drawbacks, like being unable to share
> the clocks for multiple users, missing usecounting and generally being
> totally incompatible with the common clock framework.
> 
> This patch adds support for clkctrl clocks for addressing the above
> issues. These support the modulemode handling, which will replace the
> direct hwmod clkctrl linkage. Any optional clocks are also supported,
> gate, mux and divider.

Acked-by: Tony Lindgren <tony@atomide.com>

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

* [PATCHv3 4/4] clk: ti: omap4: add clkctrl clock data
  2017-05-17 15:50 ` [PATCHv3 4/4] clk: ti: omap4: add clkctrl clock data Tero Kristo
@ 2017-05-19 22:15   ` Tony Lindgren
  0 siblings, 0 replies; 7+ messages in thread
From: Tony Lindgren @ 2017-05-19 22:15 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [170517 08:55]:
> Add data for omap4 clkctrl clocks, and register it within the clkctrl
> driver.

Acked-by: Tony Lindgren <tony@atomide.com>

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

end of thread, other threads:[~2017-05-19 22:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-17 15:50 [PATCHv3 0/4] clk: ti: add support for clkctrl clocks Tero Kristo
2017-05-17 15:50 ` [PATCHv3 1/4] Documentation: dt-bindings: Add binding documentation for TI " Tero Kristo
2017-05-17 15:50 ` [PATCHv3 2/4] clk: ti: add support for " Tero Kristo
2017-05-19 22:14   ` Tony Lindgren
2017-05-17 15:50 ` [PATCHv3 3/4] dt-bindings: clk: add omap4 clkctrl definitions Tero Kristo
2017-05-17 15:50 ` [PATCHv3 4/4] clk: ti: omap4: add clkctrl clock data Tero Kristo
2017-05-19 22:15   ` Tony Lindgren

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).