diff options
author | Stefan Agner <stefan@agner.ch> | 2016-03-09 21:16:47 -0500 |
---|---|---|
committer | Shawn Guo <shawnguo@kernel.org> | 2016-03-31 05:01:55 -0400 |
commit | 456829228f96702ca281b65e11d11e8c09ca9da0 (patch) | |
tree | 65784e1d35f7199f9daf3cc363269a7982b48dfb | |
parent | 0b55257ebc66d333e86415b0fdf46450ca807059 (diff) |
clk: imx: clk-gate2: allow custom gate configuration
The 2-bit gates found i.MX and Vybrid SoC support different clock
configuration:
0b00: clk disabled
0b01: clk enabled in RUN mode but disabled in WAIT and STOP mode
0b10: clk enabled in RUN, WAIT and STOP mode (only Vybrid)
0b11: clk enabled in RUN and WAIT mode
For some clocks, we might want to configure different behaviour,
e.g. a memory clock should be on even in STOP mode. Add a new
function imx_clk_gate2_cgr which allow to configure specific
gate values through the cgr_val parameter.
Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
-rw-r--r-- | drivers/clk/imx/clk-gate2.c | 7 | ||||
-rw-r--r-- | drivers/clk/imx/clk.h | 13 |
2 files changed, 15 insertions, 5 deletions
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index 8935bff99fe7..db44a198a0d9 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c | |||
@@ -31,6 +31,7 @@ struct clk_gate2 { | |||
31 | struct clk_hw hw; | 31 | struct clk_hw hw; |
32 | void __iomem *reg; | 32 | void __iomem *reg; |
33 | u8 bit_idx; | 33 | u8 bit_idx; |
34 | u8 cgr_val; | ||
34 | u8 flags; | 35 | u8 flags; |
35 | spinlock_t *lock; | 36 | spinlock_t *lock; |
36 | unsigned int *share_count; | 37 | unsigned int *share_count; |
@@ -50,7 +51,8 @@ static int clk_gate2_enable(struct clk_hw *hw) | |||
50 | goto out; | 51 | goto out; |
51 | 52 | ||
52 | reg = readl(gate->reg); | 53 | reg = readl(gate->reg); |
53 | reg |= 3 << gate->bit_idx; | 54 | reg &= ~(3 << gate->bit_idx); |
55 | reg |= gate->cgr_val << gate->bit_idx; | ||
54 | writel(reg, gate->reg); | 56 | writel(reg, gate->reg); |
55 | 57 | ||
56 | out: | 58 | out: |
@@ -125,7 +127,7 @@ static struct clk_ops clk_gate2_ops = { | |||
125 | 127 | ||
126 | struct clk *clk_register_gate2(struct device *dev, const char *name, | 128 | struct clk *clk_register_gate2(struct device *dev, const char *name, |
127 | const char *parent_name, unsigned long flags, | 129 | const char *parent_name, unsigned long flags, |
128 | void __iomem *reg, u8 bit_idx, | 130 | void __iomem *reg, u8 bit_idx, u8 cgr_val, |
129 | u8 clk_gate2_flags, spinlock_t *lock, | 131 | u8 clk_gate2_flags, spinlock_t *lock, |
130 | unsigned int *share_count) | 132 | unsigned int *share_count) |
131 | { | 133 | { |
@@ -140,6 +142,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, | |||
140 | /* struct clk_gate2 assignments */ | 142 | /* struct clk_gate2 assignments */ |
141 | gate->reg = reg; | 143 | gate->reg = reg; |
142 | gate->bit_idx = bit_idx; | 144 | gate->bit_idx = bit_idx; |
145 | gate->cgr_val = cgr_val; | ||
143 | gate->flags = clk_gate2_flags; | 146 | gate->flags = clk_gate2_flags; |
144 | gate->lock = lock; | 147 | gate->lock = lock; |
145 | gate->share_count = share_count; | 148 | gate->share_count = share_count; |
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index d942f5748d08..508d0fad84cf 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h | |||
@@ -41,7 +41,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, | |||
41 | 41 | ||
42 | struct clk *clk_register_gate2(struct device *dev, const char *name, | 42 | struct clk *clk_register_gate2(struct device *dev, const char *name, |
43 | const char *parent_name, unsigned long flags, | 43 | const char *parent_name, unsigned long flags, |
44 | void __iomem *reg, u8 bit_idx, | 44 | void __iomem *reg, u8 bit_idx, u8 cgr_val, |
45 | u8 clk_gate_flags, spinlock_t *lock, | 45 | u8 clk_gate_flags, spinlock_t *lock, |
46 | unsigned int *share_count); | 46 | unsigned int *share_count); |
47 | 47 | ||
@@ -55,7 +55,7 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent, | |||
55 | void __iomem *reg, u8 shift) | 55 | void __iomem *reg, u8 shift) |
56 | { | 56 | { |
57 | return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, | 57 | return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, |
58 | shift, 0, &imx_ccm_lock, NULL); | 58 | shift, 0x3, 0, &imx_ccm_lock, NULL); |
59 | } | 59 | } |
60 | 60 | ||
61 | static inline struct clk *imx_clk_gate2_shared(const char *name, | 61 | static inline struct clk *imx_clk_gate2_shared(const char *name, |
@@ -63,7 +63,14 @@ static inline struct clk *imx_clk_gate2_shared(const char *name, | |||
63 | unsigned int *share_count) | 63 | unsigned int *share_count) |
64 | { | 64 | { |
65 | return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, | 65 | return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, |
66 | shift, 0, &imx_ccm_lock, share_count); | 66 | shift, 0x3, 0, &imx_ccm_lock, share_count); |
67 | } | ||
68 | |||
69 | static inline struct clk *imx_clk_gate2_cgr(const char *name, const char *parent, | ||
70 | void __iomem *reg, u8 shift, u8 cgr_val) | ||
71 | { | ||
72 | return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, | ||
73 | shift, cgr_val, 0, &imx_ccm_lock, NULL); | ||
67 | } | 74 | } |
68 | 75 | ||
69 | struct clk *imx_clk_pfd(const char *name, const char *parent_name, | 76 | struct clk *imx_clk_pfd(const char *name, const char *parent_name, |