kernel: update 3.14 to 3.14.18
[openwrt.git] / target / linux / ipq806x / patches / 0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch
1 From 856324d2daa3246ac62d7920d6a274e1fa35bcf5 Mon Sep 17 00:00:00 2001
2 From: Stephen Boyd <sboyd@codeaurora.org>
3 Date: Mon, 28 Apr 2014 15:59:16 -0700
4 Subject: [PATCH 128/182] clk: qcom: Add support for banked MD RCGs
5
6 The banked MD RCGs in global clock control have a different
7 register layout than the ones implemented in multimedia clock
8 control. Add support for these types of clocks so we can change
9 the rates of the UBI32 clocks.
10
11 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
12 ---
13  drivers/clk/qcom/clk-rcg.c      |   99 ++++++++++++++++++++-------------------
14  drivers/clk/qcom/clk-rcg.h      |    5 +-
15  drivers/clk/qcom/mmcc-msm8960.c |   24 +++++++---
16  3 files changed, 73 insertions(+), 55 deletions(-)
17
18 --- a/drivers/clk/qcom/clk-rcg.c
19 +++ b/drivers/clk/qcom/clk-rcg.c
20 @@ -67,16 +67,16 @@ static u8 clk_dyn_rcg_get_parent(struct
21  {
22         struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
23         int num_parents = __clk_get_num_parents(hw->clk);
24 -       u32 ns, ctl;
25 +       u32 ns, reg;
26         int bank;
27         int i;
28         struct src_sel *s;
29  
30 -       regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
31 -       bank = reg_to_bank(rcg, ctl);
32 +       regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
33 +       bank = reg_to_bank(rcg, reg);
34         s = &rcg->s[bank];
35  
36 -       regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
37 +       regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
38         ns = ns_to_src(s, ns);
39  
40         for (i = 0; i < num_parents; i++)
41 @@ -192,90 +192,93 @@ static u32 mn_to_reg(struct mn *mn, u32
42  
43  static void configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
44  {
45 -       u32 ns, md, ctl, *regp;
46 +       u32 ns, md, reg;
47         int bank, new_bank;
48         struct mn *mn;
49         struct pre_div *p;
50         struct src_sel *s;
51         bool enabled;
52 -       u32 md_reg;
53 -       u32 bank_reg;
54 +       u32 md_reg, ns_reg;
55         bool banked_mn = !!rcg->mn[1].width;
56 +       bool banked_p = !!rcg->p[1].pre_div_width;
57         struct clk_hw *hw = &rcg->clkr.hw;
58  
59         enabled = __clk_is_enabled(hw->clk);
60  
61 -       regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
62 -       regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
63 -
64 -       if (banked_mn) {
65 -               regp = &ctl;
66 -               bank_reg = rcg->clkr.enable_reg;
67 -       } else {
68 -               regp = &ns;
69 -               bank_reg = rcg->ns_reg;
70 -       }
71 -
72 -       bank = reg_to_bank(rcg, *regp);
73 +       regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
74 +       bank = reg_to_bank(rcg, reg);
75         new_bank = enabled ? !bank : bank;
76  
77 +       ns_reg = rcg->ns_reg[new_bank];
78 +       regmap_read(rcg->clkr.regmap, ns_reg, &ns);
79 +
80         if (banked_mn) {
81                 mn = &rcg->mn[new_bank];
82                 md_reg = rcg->md_reg[new_bank];
83  
84                 ns |= BIT(mn->mnctr_reset_bit);
85 -               regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
86 +               regmap_write(rcg->clkr.regmap, ns_reg, ns);
87  
88                 regmap_read(rcg->clkr.regmap, md_reg, &md);
89                 md = mn_to_md(mn, f->m, f->n, md);
90                 regmap_write(rcg->clkr.regmap, md_reg, md);
91  
92                 ns = mn_to_ns(mn, f->m, f->n, ns);
93 -               regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
94 +               regmap_write(rcg->clkr.regmap, ns_reg, ns);
95  
96 -               ctl = mn_to_reg(mn, f->m, f->n, ctl);
97 -               regmap_write(rcg->clkr.regmap, rcg->clkr.enable_reg, ctl);
98 +               /* Two NS registers means mode control is in NS register */
99 +               if (rcg->ns_reg[0] != rcg->ns_reg[1]) {
100 +                       ns = mn_to_reg(mn, f->m, f->n, ns);
101 +                       regmap_write(rcg->clkr.regmap, ns_reg, ns);
102 +               } else {
103 +                       reg = mn_to_reg(mn, f->m, f->n, reg);
104 +                       regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
105 +               }
106  
107                 ns &= ~BIT(mn->mnctr_reset_bit);
108 -               regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
109 -       } else {
110 +               regmap_write(rcg->clkr.regmap, ns_reg, ns);
111 +       }
112 +
113 +       if (banked_p) {
114                 p = &rcg->p[new_bank];
115                 ns = pre_div_to_ns(p, f->pre_div - 1, ns);
116         }
117  
118         s = &rcg->s[new_bank];
119         ns = src_to_ns(s, s->parent_map[f->src], ns);
120 -       regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
121 +       regmap_write(rcg->clkr.regmap, ns_reg, ns);
122  
123         if (enabled) {
124 -               *regp ^= BIT(rcg->mux_sel_bit);
125 -               regmap_write(rcg->clkr.regmap, bank_reg, *regp);
126 +               regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
127 +               reg ^= BIT(rcg->mux_sel_bit);
128 +               regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
129         }
130  }
131  
132  static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index)
133  {
134         struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
135 -       u32 ns, ctl, md, reg;
136 +       u32 ns, md, reg;
137         int bank;
138         struct freq_tbl f = { 0 };
139         bool banked_mn = !!rcg->mn[1].width;
140 +       bool banked_p = !!rcg->p[1].pre_div_width;
141  
142 -       regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
143 -       regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
144 -       reg = banked_mn ? ctl : ns;
145 -
146 +       regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
147         bank = reg_to_bank(rcg, reg);
148  
149 +       regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
150 +
151         if (banked_mn) {
152                 regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
153                 f.m = md_to_m(&rcg->mn[bank], md);
154                 f.n = ns_m_to_n(&rcg->mn[bank], ns, f.m);
155 -       } else {
156 -               f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
157         }
158 -       f.src = index;
159  
160 +       if (banked_p)
161 +               f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
162 +
163 +       f.src = index;
164         configure_bank(rcg, &f);
165  
166         return 0;
167 @@ -336,28 +339,30 @@ clk_dyn_rcg_recalc_rate(struct clk_hw *h
168         u32 m, n, pre_div, ns, md, mode, reg;
169         int bank;
170         struct mn *mn;
171 +       bool banked_p = !!rcg->p[1].pre_div_width;
172         bool banked_mn = !!rcg->mn[1].width;
173  
174 -       regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
175 -
176 -       if (banked_mn)
177 -               regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &reg);
178 -       else
179 -               reg = ns;
180 -
181 +       regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
182         bank = reg_to_bank(rcg, reg);
183  
184 +       regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
185 +       m = n = pre_div = mode = 0;
186 +
187         if (banked_mn) {
188                 mn = &rcg->mn[bank];
189                 regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
190                 m = md_to_m(mn, md);
191                 n = ns_m_to_n(mn, ns, m);
192 +               /* Two NS registers means mode control is in NS register */
193 +               if (rcg->ns_reg[0] != rcg->ns_reg[1])
194 +                       reg = ns;
195                 mode = reg_to_mnctr_mode(mn, reg);
196 -               return calc_rate(parent_rate, m, n, mode, 0);
197 -       } else {
198 -               pre_div = ns_to_pre_div(&rcg->p[bank], ns);
199 -               return calc_rate(parent_rate, 0, 0, 0, pre_div);
200         }
201 +
202 +       if (banked_p)
203 +               pre_div = ns_to_pre_div(&rcg->p[bank], ns);
204 +
205 +       return calc_rate(parent_rate, m, n, mode, pre_div);
206  }
207  
208  static const
209 --- a/drivers/clk/qcom/clk-rcg.h
210 +++ b/drivers/clk/qcom/clk-rcg.h
211 @@ -102,7 +102,7 @@ extern const struct clk_ops clk_rcg_ops;
212   * struct clk_dyn_rcg - root clock generator with glitch free mux
213   *
214   * @mux_sel_bit: bit to switch glitch free mux
215 - * @ns_reg: NS register
216 + * @ns_reg: NS0 and NS1 register
217   * @md_reg: MD0 and MD1 register
218   * @mn: mn counter (banked)
219   * @s: source selector (banked)
220 @@ -112,8 +112,9 @@ extern const struct clk_ops clk_rcg_ops;
221   *
222   */
223  struct clk_dyn_rcg {
224 -       u32     ns_reg;
225 +       u32     ns_reg[2];
226         u32     md_reg[2];
227 +       u32     bank_reg;
228  
229         u8      mux_sel_bit;
230  
231 --- a/drivers/clk/qcom/mmcc-msm8960.c
232 +++ b/drivers/clk/qcom/mmcc-msm8960.c
233 @@ -726,9 +726,11 @@ static struct freq_tbl clk_tbl_gfx2d[] =
234  };
235  
236  static struct clk_dyn_rcg gfx2d0_src = {
237 -       .ns_reg = 0x0070,
238 +       .ns_reg[0] = 0x0070,
239 +       .ns_reg[1] = 0x0070,
240         .md_reg[0] = 0x0064,
241         .md_reg[1] = 0x0068,
242 +       .bank_reg = 0x0060,
243         .mn[0] = {
244                 .mnctr_en_bit = 8,
245                 .mnctr_reset_bit = 25,
246 @@ -784,9 +786,11 @@ static struct clk_branch gfx2d0_clk = {
247  };
248  
249  static struct clk_dyn_rcg gfx2d1_src = {
250 -       .ns_reg = 0x007c,
251 +       .ns_reg[0] = 0x007c,
252 +       .ns_reg[1] = 0x007c,
253         .md_reg[0] = 0x0078,
254         .md_reg[1] = 0x006c,
255 +       .bank_reg = 0x0074,
256         .mn[0] = {
257                 .mnctr_en_bit = 8,
258                 .mnctr_reset_bit = 25,
259 @@ -862,9 +866,11 @@ static struct freq_tbl clk_tbl_gfx3d[] =
260  };
261  
262  static struct clk_dyn_rcg gfx3d_src = {
263 -       .ns_reg = 0x008c,
264 +       .ns_reg[0] = 0x008c,
265 +       .ns_reg[1] = 0x008c,
266         .md_reg[0] = 0x0084,
267         .md_reg[1] = 0x0088,
268 +       .bank_reg = 0x0080,
269         .mn[0] = {
270                 .mnctr_en_bit = 8,
271                 .mnctr_reset_bit = 25,
272 @@ -1051,9 +1057,11 @@ static struct freq_tbl clk_tbl_mdp[] = {
273  };
274  
275  static struct clk_dyn_rcg mdp_src = {
276 -       .ns_reg = 0x00d0,
277 +       .ns_reg[0] = 0x00d0,
278 +       .ns_reg[1] = 0x00d0,
279         .md_reg[0] = 0x00c4,
280         .md_reg[1] = 0x00c8,
281 +       .bank_reg = 0x00c0,
282         .mn[0] = {
283                 .mnctr_en_bit = 8,
284                 .mnctr_reset_bit = 31,
285 @@ -1158,7 +1166,9 @@ static struct freq_tbl clk_tbl_rot[] = {
286  };
287  
288  static struct clk_dyn_rcg rot_src = {
289 -       .ns_reg = 0x00e8,
290 +       .ns_reg[0] = 0x00e8,
291 +       .ns_reg[1] = 0x00e8,
292 +       .bank_reg = 0x00e8,
293         .p[0] = {
294                 .pre_div_shift = 22,
295                 .pre_div_width = 4,
296 @@ -1355,9 +1365,11 @@ static struct freq_tbl clk_tbl_vcodec[]
297  };
298  
299  static struct clk_dyn_rcg vcodec_src = {
300 -       .ns_reg = 0x0100,
301 +       .ns_reg[0] = 0x0100,
302 +       .ns_reg[1] = 0x0100,
303         .md_reg[0] = 0x00fc,
304         .md_reg[1] = 0x0128,
305 +       .bank_reg = 0x00f8,
306         .mn[0] = {
307                 .mnctr_en_bit = 5,
308                 .mnctr_reset_bit = 31,