All of lore.kernel.org
 help / color / mirror / Atom feed
From: heiko@sntech.de (Heiko Stübner)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 1/4] clk: add support for Rockchip gate clocks
Date: Thu, 13 Jun 2013 16:59:40 +0200	[thread overview]
Message-ID: <201306131659.40802.heiko@sntech.de> (raw)
In-Reply-To: <201306131658.36584.heiko@sntech.de>

This adds basic support for gate-clocks on Rockchip SoCs.
There are 16 gates in each register and use the HIWORD_MASK
mechanism for changing gate settings.

The gate registers form a continuos block which makes the dt node
structure a matter of taste, as either all 160 gates can be put into
one gate clock spanning all registers or they can be divided into
the 10 individual gates containing 16 clocks each.
The code supports both approaches.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 .../devicetree/bindings/clock/rockchip.txt         |   74 +++++++++++++++
 drivers/clk/Makefile                               |    1 +
 drivers/clk/rockchip/Makefile                      |    5 ++
 drivers/clk/rockchip/clk-rockchip.c                |   94 ++++++++++++++++++++
 4 files changed, 174 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip.txt
 create mode 100644 drivers/clk/rockchip/Makefile
 create mode 100644 drivers/clk/rockchip/clk-rockchip.c

diff --git a/Documentation/devicetree/bindings/clock/rockchip.txt b/Documentation/devicetree/bindings/clock/rockchip.txt
new file mode 100644
index 0000000..a891c82
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip.txt
@@ -0,0 +1,74 @@
+Device Tree Clock bindings for arch-rockchip
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+== Gate clocks ==
+
+The gate registers form a continuos block which makes the dt node
+structure a matter of taste, as either all gates can be put into
+one gate clock spanning all registers or they can be divided into
+the 10 individual gates containing 16 clocks each.
+The code supports both approaches.
+
+Required properties:
+- compatible : "rockchip,rk2928-gate-clk"
+- reg : shall be the control register address(es) for the clock.
+- #clock-cells : from common clock binding; shall be set to 1
+- clock-output-names : the corresponding gate names that the clock controls
+- clocks : should contain the parent clock for each individual gate,
+  therefore the number of clocks elements should match the number of
+  clock-output-names
+
+Example using multiple gate clocks:
+
+		clk_gates0: gate-clk at 200000d0 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000d0 0x4>;
+			clocks = <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>;
+
+			clock-output-names =
+				"gate_core_periph", "gate_cpu_gpll",
+				"gate_ddrphy", "gate_aclk_cpu",
+				"gate_hclk_cpu", "gate_pclk_cpu",
+				"gate_atclk_cpu", "gate_i2s0",
+				"gate_i2s0_frac", "gate_i2s1",
+				"gate_i2s1_frac", "gate_i2s2",
+				"gate_i2s2_frac", "gate_spdif",
+				"gate_spdif_frac", "gate_testclk";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates1: gate-clk at 200000d4 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000d4 0x4>;
+			clocks = <&xin24m>, <&xin24m>,
+				 <&xin24m>, <&dummy>,
+				 <&dummy>, <&xin24m>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>;
+
+			clock-output-names =
+				"gate_timer0", "gate_timer1",
+				"gate_timer2", "gate_jtag",
+				"gate_aclk_lcdc1_src", "gate_otgphy0",
+				"gate_otgphy1", "gate_ddr_gpll",
+				"gate_uart0", "gate_frac_uart0",
+				"gate_uart1", "gate_frac_uart1",
+				"gate_uart2", "gate_frac_uart2",
+				"gate_uart3", "gate_frac_uart3";
+
+			#clock-cells = <1>;
+		};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f51b52b..2e2e957 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -25,6 +25,7 @@ ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)		+= mmp/
 endif
 obj-$(CONFIG_MACH_LOONGSON1)	+= clk-ls1x.o
+obj-$(CONFIG_ARCH_ROCKCHIP)	+= rockchip/
 obj-$(CONFIG_ARCH_SUNXI)	+= sunxi/
 obj-$(CONFIG_ARCH_U8500)	+= ux500/
 obj-$(CONFIG_ARCH_VT8500)	+= clk-vt8500.o
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
new file mode 100644
index 0000000..8d3aefa
--- /dev/null
+++ b/drivers/clk/rockchip/Makefile
@@ -0,0 +1,5 @@
+#
+# Rockchip Clock specific Makefile
+#
+
+obj-y	+= clk-rockchip.o
diff --git a/drivers/clk/rockchip/clk-rockchip.c b/drivers/clk/rockchip/clk-rockchip.c
new file mode 100644
index 0000000..ff990c4
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rockchip.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+static DEFINE_SPINLOCK(clk_lock);
+
+/*
+ * Gate clocks
+ */
+
+static void __init rk2928_gate_clk_init(struct device_node *node,
+					 void *data)
+{
+	struct clk_onecell_data *clk_data;
+	const char *clk_parent;
+	const char *clk_name;
+	void __iomem *reg;
+	void __iomem *reg_idx;
+	int flags;
+	int qty;
+	int reg_bit;
+	int clkflags = CLK_SET_RATE_PARENT;
+	int i;
+
+	qty = of_property_count_strings(node, "clock-output-names");
+	if (qty < 0) {
+		pr_err("%s: error in clock-output-names %d\n", __func__, qty);
+		return;
+	}
+
+	if (qty == 0) {
+		pr_info("%s: nothing to do\n", __func__);
+		return;
+	}
+
+	reg = of_iomap(node, 0);
+
+	clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+	if (!clk_data)
+		return;
+
+	clk_data->clks = kzalloc(qty * sizeof(struct clk *), GFP_KERNEL);
+	if (!clk_data->clks) {
+		kfree(clk_data);
+		return;
+	}
+
+	flags = CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE;
+
+	for (i = 0; i < qty; i++) {
+		of_property_read_string_index(node, "clock-output-names",
+					      i, &clk_name);
+
+		/* ignore empty slots */
+		if (!strcmp("reserved", clk_name))
+			continue;
+
+		clk_parent = of_clk_get_parent_name(node, i);
+
+		/* keep all gates untouched for now */
+		clkflags |= CLK_IGNORE_UNUSED;
+
+		reg_idx = reg + (4 * (i / 16));
+		reg_bit = (i % 16);
+
+		clk_data->clks[i] = clk_register_gate(NULL, clk_name,
+						      clk_parent, clkflags,
+						      reg_idx, reg_bit,
+						      flags,
+						      &clk_lock);
+		WARN_ON(IS_ERR(clk_data->clks[i]));
+	}
+
+	clk_data->clk_num = qty;
+
+	of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+CLK_OF_DECLARE(rk2928_gate, "rockchip,rk2928-gate-clk", rk2928_gate_clk_init);
-- 
1.7.10.4

WARNING: multiple messages have this Message-ID (diff)
From: "Heiko Stübner" <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
To: "linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org"
	<linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org>
Cc: Mike Turquette
	<mturquette-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
	Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>,
	Grant Likely
	<grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Subject: [PATCH v4 1/4] clk: add support for Rockchip gate clocks
Date: Thu, 13 Jun 2013 16:59:40 +0200	[thread overview]
Message-ID: <201306131659.40802.heiko@sntech.de> (raw)
In-Reply-To: <201306131658.36584.heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>

This adds basic support for gate-clocks on Rockchip SoCs.
There are 16 gates in each register and use the HIWORD_MASK
mechanism for changing gate settings.

The gate registers form a continuos block which makes the dt node
structure a matter of taste, as either all 160 gates can be put into
one gate clock spanning all registers or they can be divided into
the 10 individual gates containing 16 clocks each.
The code supports both approaches.

Signed-off-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
---
 .../devicetree/bindings/clock/rockchip.txt         |   74 +++++++++++++++
 drivers/clk/Makefile                               |    1 +
 drivers/clk/rockchip/Makefile                      |    5 ++
 drivers/clk/rockchip/clk-rockchip.c                |   94 ++++++++++++++++++++
 4 files changed, 174 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip.txt
 create mode 100644 drivers/clk/rockchip/Makefile
 create mode 100644 drivers/clk/rockchip/clk-rockchip.c

diff --git a/Documentation/devicetree/bindings/clock/rockchip.txt b/Documentation/devicetree/bindings/clock/rockchip.txt
new file mode 100644
index 0000000..a891c82
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip.txt
@@ -0,0 +1,74 @@
+Device Tree Clock bindings for arch-rockchip
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+== Gate clocks ==
+
+The gate registers form a continuos block which makes the dt node
+structure a matter of taste, as either all gates can be put into
+one gate clock spanning all registers or they can be divided into
+the 10 individual gates containing 16 clocks each.
+The code supports both approaches.
+
+Required properties:
+- compatible : "rockchip,rk2928-gate-clk"
+- reg : shall be the control register address(es) for the clock.
+- #clock-cells : from common clock binding; shall be set to 1
+- clock-output-names : the corresponding gate names that the clock controls
+- clocks : should contain the parent clock for each individual gate,
+  therefore the number of clocks elements should match the number of
+  clock-output-names
+
+Example using multiple gate clocks:
+
+		clk_gates0: gate-clk@200000d0 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000d0 0x4>;
+			clocks = <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>;
+
+			clock-output-names =
+				"gate_core_periph", "gate_cpu_gpll",
+				"gate_ddrphy", "gate_aclk_cpu",
+				"gate_hclk_cpu", "gate_pclk_cpu",
+				"gate_atclk_cpu", "gate_i2s0",
+				"gate_i2s0_frac", "gate_i2s1",
+				"gate_i2s1_frac", "gate_i2s2",
+				"gate_i2s2_frac", "gate_spdif",
+				"gate_spdif_frac", "gate_testclk";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates1: gate-clk@200000d4 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000d4 0x4>;
+			clocks = <&xin24m>, <&xin24m>,
+				 <&xin24m>, <&dummy>,
+				 <&dummy>, <&xin24m>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>;
+
+			clock-output-names =
+				"gate_timer0", "gate_timer1",
+				"gate_timer2", "gate_jtag",
+				"gate_aclk_lcdc1_src", "gate_otgphy0",
+				"gate_otgphy1", "gate_ddr_gpll",
+				"gate_uart0", "gate_frac_uart0",
+				"gate_uart1", "gate_frac_uart1",
+				"gate_uart2", "gate_frac_uart2",
+				"gate_uart3", "gate_frac_uart3";
+
+			#clock-cells = <1>;
+		};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f51b52b..2e2e957 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -25,6 +25,7 @@ ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)		+= mmp/
 endif
 obj-$(CONFIG_MACH_LOONGSON1)	+= clk-ls1x.o
+obj-$(CONFIG_ARCH_ROCKCHIP)	+= rockchip/
 obj-$(CONFIG_ARCH_SUNXI)	+= sunxi/
 obj-$(CONFIG_ARCH_U8500)	+= ux500/
 obj-$(CONFIG_ARCH_VT8500)	+= clk-vt8500.o
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
new file mode 100644
index 0000000..8d3aefa
--- /dev/null
+++ b/drivers/clk/rockchip/Makefile
@@ -0,0 +1,5 @@
+#
+# Rockchip Clock specific Makefile
+#
+
+obj-y	+= clk-rockchip.o
diff --git a/drivers/clk/rockchip/clk-rockchip.c b/drivers/clk/rockchip/clk-rockchip.c
new file mode 100644
index 0000000..ff990c4
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rockchip.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+static DEFINE_SPINLOCK(clk_lock);
+
+/*
+ * Gate clocks
+ */
+
+static void __init rk2928_gate_clk_init(struct device_node *node,
+					 void *data)
+{
+	struct clk_onecell_data *clk_data;
+	const char *clk_parent;
+	const char *clk_name;
+	void __iomem *reg;
+	void __iomem *reg_idx;
+	int flags;
+	int qty;
+	int reg_bit;
+	int clkflags = CLK_SET_RATE_PARENT;
+	int i;
+
+	qty = of_property_count_strings(node, "clock-output-names");
+	if (qty < 0) {
+		pr_err("%s: error in clock-output-names %d\n", __func__, qty);
+		return;
+	}
+
+	if (qty == 0) {
+		pr_info("%s: nothing to do\n", __func__);
+		return;
+	}
+
+	reg = of_iomap(node, 0);
+
+	clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+	if (!clk_data)
+		return;
+
+	clk_data->clks = kzalloc(qty * sizeof(struct clk *), GFP_KERNEL);
+	if (!clk_data->clks) {
+		kfree(clk_data);
+		return;
+	}
+
+	flags = CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE;
+
+	for (i = 0; i < qty; i++) {
+		of_property_read_string_index(node, "clock-output-names",
+					      i, &clk_name);
+
+		/* ignore empty slots */
+		if (!strcmp("reserved", clk_name))
+			continue;
+
+		clk_parent = of_clk_get_parent_name(node, i);
+
+		/* keep all gates untouched for now */
+		clkflags |= CLK_IGNORE_UNUSED;
+
+		reg_idx = reg + (4 * (i / 16));
+		reg_bit = (i % 16);
+
+		clk_data->clks[i] = clk_register_gate(NULL, clk_name,
+						      clk_parent, clkflags,
+						      reg_idx, reg_bit,
+						      flags,
+						      &clk_lock);
+		WARN_ON(IS_ERR(clk_data->clks[i]));
+	}
+
+	clk_data->clk_num = qty;
+
+	of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+CLK_OF_DECLARE(rk2928_gate, "rockchip,rk2928-gate-clk", rk2928_gate_clk_init);
-- 
1.7.10.4

  reply	other threads:[~2013-06-13 14:59 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-13 14:58 [PATCH v4 0/4] arm: add basic support for Rockchip Cortex-A9 SoCs Heiko Stübner
2013-06-13 14:58 ` Heiko Stübner
2013-06-13 14:59 ` Heiko Stübner [this message]
2013-06-13 14:59   ` [PATCH v4 1/4] clk: add support for Rockchip gate clocks Heiko Stübner
2013-06-20 23:29   ` Mike Turquette
2013-06-20 23:29     ` Mike Turquette
2013-06-13 15:00 ` [PATCH v4 2/4] arm: Add basic clocks for Rockchip rk3066a SoCs Heiko Stübner
2013-06-13 15:00   ` Heiko Stübner
2013-06-13 15:00 ` [PATCH v4 3/4] arm: add debug uarts for rockchip rk29xx and rk3xxx series Heiko Stübner
2013-06-13 15:00   ` Heiko Stübner
2013-06-13 15:02 ` [PATCH v4 4/4] arm: add basic support for Rockchip RK3066a boards Heiko Stübner
2013-06-13 15:02   ` Heiko Stübner
2013-06-17 21:35   ` Olof Johansson
2013-06-17 21:35     ` Olof Johansson
2013-06-17 22:26     ` Heiko Stübner
2013-06-17 22:26       ` Heiko Stübner
2013-06-18 14:13       ` Arnd Bergmann
2013-06-18 14:13         ` Arnd Bergmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201306131659.40802.heiko@sntech.de \
    --to=heiko@sntech.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.