aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Agner <stefan@agner.ch>2016-03-09 21:16:47 -0500
committerShawn Guo <shawnguo@kernel.org>2016-03-31 05:01:55 -0400
commit456829228f96702ca281b65e11d11e8c09ca9da0 (patch)
tree65784e1d35f7199f9daf3cc363269a7982b48dfb
parent0b55257ebc66d333e86415b0fdf46450ca807059 (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.c7
-rw-r--r--drivers/clk/imx/clk.h13
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
56out: 58out:
@@ -125,7 +127,7 @@ static struct clk_ops clk_gate2_ops = {
125 127
126struct clk *clk_register_gate2(struct device *dev, const char *name, 128struct 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
42struct clk *clk_register_gate2(struct device *dev, const char *name, 42struct 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
61static inline struct clk *imx_clk_gate2_shared(const char *name, 61static 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
69static 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
69struct clk *imx_clk_pfd(const char *name, const char *parent_name, 76struct clk *imx_clk_pfd(const char *name, const char *parent_name,