aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-04-19 02:33:45 -0400
committerSascha Hauer <s.hauer@pengutronix.de>2012-05-02 06:08:13 -0400
commitb75c015143a4a6021731ff3e36718896381be94f (patch)
tree120a964bf4213ac2180c03f138f0e749253b4db2 /arch/arm/mach-imx
parenta3f6b9dbf2a964b85f0523e577807d6f63d6b29d (diff)
ARM i.MX: Add common clock support for 2bit gate
This gate consists of two bits: 0b00: clk disabled 0b01: clk enabled in run mode and disabled in sleep mode 0b11: clk enabled Currently only disabled and enabled are supported. As it's unlikely that we find something like this in another SoC create a i.MX specific clk helper for this. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/clk-gate2.c118
-rw-r--r--arch/arm/mach-imx/clk.h12
3 files changed, 131 insertions, 1 deletions
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 66bc6bed0bcd..1b3f2aea8f48 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-i
11 11
12obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o 12obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
13 13
14obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o 14obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o
15 15
16# Support for CMOS sensor interface 16# Support for CMOS sensor interface
17obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o 17obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
new file mode 100644
index 000000000000..3c1b8ff9a0a6
--- /dev/null
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -0,0 +1,118 @@
1/*
2 * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
3 * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Gated clock implementation
10 */
11
12#include <linux/clk-provider.h>
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/io.h>
16#include <linux/err.h>
17#include <linux/string.h>
18
19/**
20 * DOC: basic gatable clock which can gate and ungate it's ouput
21 *
22 * Traits of this clock:
23 * prepare - clk_(un)prepare only ensures parent is (un)prepared
24 * enable - clk_enable and clk_disable are functional & control gating
25 * rate - inherits rate from parent. No clk_set_rate support
26 * parent - fixed parent. No clk_set_parent support
27 */
28
29#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
30
31static int clk_gate2_enable(struct clk_hw *hw)
32{
33 struct clk_gate *gate = to_clk_gate(hw);
34 u32 reg;
35 unsigned long flags = 0;
36
37 if (gate->lock)
38 spin_lock_irqsave(gate->lock, flags);
39
40 reg = readl(gate->reg);
41 reg |= 3 << gate->bit_idx;
42 writel(reg, gate->reg);
43
44 if (gate->lock)
45 spin_unlock_irqrestore(gate->lock, flags);
46
47 return 0;
48}
49
50static void clk_gate2_disable(struct clk_hw *hw)
51{
52 struct clk_gate *gate = to_clk_gate(hw);
53 u32 reg;
54 unsigned long flags = 0;
55
56 if (gate->lock)
57 spin_lock_irqsave(gate->lock, flags);
58
59 reg = readl(gate->reg);
60 reg &= ~(3 << gate->bit_idx);
61 writel(reg, gate->reg);
62
63 if (gate->lock)
64 spin_unlock_irqrestore(gate->lock, flags);
65}
66
67static int clk_gate2_is_enabled(struct clk_hw *hw)
68{
69 u32 reg;
70 struct clk_gate *gate = to_clk_gate(hw);
71
72 reg = readl(gate->reg);
73
74 if (((reg >> gate->bit_idx) & 3) == 3)
75 return 1;
76
77 return 0;
78}
79
80static struct clk_ops clk_gate2_ops = {
81 .enable = clk_gate2_enable,
82 .disable = clk_gate2_disable,
83 .is_enabled = clk_gate2_is_enabled,
84};
85
86struct clk *clk_register_gate2(struct device *dev, const char *name,
87 const char *parent_name, unsigned long flags,
88 void __iomem *reg, u8 bit_idx,
89 u8 clk_gate2_flags, spinlock_t *lock)
90{
91 struct clk_gate *gate;
92 struct clk *clk;
93 struct clk_init_data init;
94
95 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
96 if (!gate)
97 return ERR_PTR(-ENOMEM);
98
99 /* struct clk_gate assignments */
100 gate->reg = reg;
101 gate->bit_idx = bit_idx;
102 gate->flags = clk_gate2_flags;
103 gate->lock = lock;
104
105 init.name = name;
106 init.ops = &clk_gate2_ops;
107 init.flags = flags;
108 init.parent_names = parent_name ? &parent_name : NULL;
109 init.num_parents = parent_name ? 1 : 0;
110
111 gate->hw.init = &init;
112
113 clk = clk_register(dev, &gate->hw);
114 if (IS_ERR(clk))
115 kfree(clk);
116
117 return clk;
118}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 331316d6a4de..5f6e435da4ae 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -24,6 +24,18 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
24 const char *parent_name, void __iomem *base, u32 gate_mask, 24 const char *parent_name, void __iomem *base, u32 gate_mask,
25 u32 div_mask); 25 u32 div_mask);
26 26
27struct clk *clk_register_gate2(struct device *dev, const char *name,
28 const char *parent_name, unsigned long flags,
29 void __iomem *reg, u8 bit_idx,
30 u8 clk_gate_flags, spinlock_t *lock);
31
32static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
33 void __iomem *reg, u8 shift)
34{
35 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
36 shift, 0, &imx_ccm_lock);
37}
38
27static inline struct clk *imx_clk_fixed(const char *name, int rate) 39static inline struct clk *imx_clk_fixed(const char *name, int rate)
28{ 40{
29 return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); 41 return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);