Skip to content

Commit

Permalink
clk: add support for Rockchip gate clocks
Browse files Browse the repository at this point in the history
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>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
  • Loading branch information
Heiko Stübner authored and Mike Turquette committed Jun 20, 2013
1 parent c7f6e2d commit 646572c
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 0 deletions.
74 changes: 74 additions & 0 deletions Documentation/devicetree/bindings/clock/rockchip.txt
Original file line number Diff line number Diff line change
@@ -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>;
};
1 change: 1 addition & 0 deletions drivers/clk/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions drivers/clk/rockchip/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#
# Rockchip Clock specific Makefile
#

obj-y += clk-rockchip.o
94 changes: 94 additions & 0 deletions drivers/clk/rockchip/clk-rockchip.c
Original file line number Diff line number Diff line change
@@ -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);

0 comments on commit 646572c

Please sign in to comment.