These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / clk / ux500 / clk-prcmu.c
1 /*
2  * PRCMU clock implementation for ux500 platform.
3  *
4  * Copyright (C) 2012 ST-Ericsson SA
5  * Author: Ulf Hansson <ulf.hansson@linaro.org>
6  *
7  * License terms: GNU General Public License (GPL) version 2
8  */
9
10 #include <linux/clk-provider.h>
11 #include <linux/mfd/dbx500-prcmu.h>
12 #include <linux/slab.h>
13 #include <linux/io.h>
14 #include <linux/err.h>
15 #include "clk.h"
16
17 #define to_clk_prcmu(_hw) container_of(_hw, struct clk_prcmu, hw)
18
19 struct clk_prcmu {
20         struct clk_hw hw;
21         u8 cg_sel;
22         int is_prepared;
23         int is_enabled;
24         int opp_requested;
25 };
26
27 /* PRCMU clock operations. */
28
29 static int clk_prcmu_prepare(struct clk_hw *hw)
30 {
31         int ret;
32         struct clk_prcmu *clk = to_clk_prcmu(hw);
33
34         ret = prcmu_request_clock(clk->cg_sel, true);
35         if (!ret)
36                 clk->is_prepared = 1;
37
38         return ret;
39 }
40
41 static void clk_prcmu_unprepare(struct clk_hw *hw)
42 {
43         struct clk_prcmu *clk = to_clk_prcmu(hw);
44         if (prcmu_request_clock(clk->cg_sel, false))
45                 pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
46                         clk_hw_get_name(hw));
47         else
48                 clk->is_prepared = 0;
49 }
50
51 static int clk_prcmu_is_prepared(struct clk_hw *hw)
52 {
53         struct clk_prcmu *clk = to_clk_prcmu(hw);
54         return clk->is_prepared;
55 }
56
57 static int clk_prcmu_enable(struct clk_hw *hw)
58 {
59         struct clk_prcmu *clk = to_clk_prcmu(hw);
60         clk->is_enabled = 1;
61         return 0;
62 }
63
64 static void clk_prcmu_disable(struct clk_hw *hw)
65 {
66         struct clk_prcmu *clk = to_clk_prcmu(hw);
67         clk->is_enabled = 0;
68 }
69
70 static int clk_prcmu_is_enabled(struct clk_hw *hw)
71 {
72         struct clk_prcmu *clk = to_clk_prcmu(hw);
73         return clk->is_enabled;
74 }
75
76 static unsigned long clk_prcmu_recalc_rate(struct clk_hw *hw,
77                                            unsigned long parent_rate)
78 {
79         struct clk_prcmu *clk = to_clk_prcmu(hw);
80         return prcmu_clock_rate(clk->cg_sel);
81 }
82
83 static long clk_prcmu_round_rate(struct clk_hw *hw, unsigned long rate,
84                                  unsigned long *parent_rate)
85 {
86         struct clk_prcmu *clk = to_clk_prcmu(hw);
87         return prcmu_round_clock_rate(clk->cg_sel, rate);
88 }
89
90 static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate,
91                               unsigned long parent_rate)
92 {
93         struct clk_prcmu *clk = to_clk_prcmu(hw);
94         return prcmu_set_clock_rate(clk->cg_sel, rate);
95 }
96
97 static int clk_prcmu_opp_prepare(struct clk_hw *hw)
98 {
99         int err;
100         struct clk_prcmu *clk = to_clk_prcmu(hw);
101
102         if (!clk->opp_requested) {
103                 err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
104                                                 (char *)clk_hw_get_name(hw),
105                                                 100);
106                 if (err) {
107                         pr_err("clk_prcmu: %s fail req APE OPP for %s.\n",
108                                 __func__, clk_hw_get_name(hw));
109                         return err;
110                 }
111                 clk->opp_requested = 1;
112         }
113
114         err = prcmu_request_clock(clk->cg_sel, true);
115         if (err) {
116                 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
117                                         (char *)clk_hw_get_name(hw));
118                 clk->opp_requested = 0;
119                 return err;
120         }
121
122         clk->is_prepared = 1;
123         return 0;
124 }
125
126 static void clk_prcmu_opp_unprepare(struct clk_hw *hw)
127 {
128         struct clk_prcmu *clk = to_clk_prcmu(hw);
129
130         if (prcmu_request_clock(clk->cg_sel, false)) {
131                 pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
132                         clk_hw_get_name(hw));
133                 return;
134         }
135
136         if (clk->opp_requested) {
137                 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
138                                         (char *)clk_hw_get_name(hw));
139                 clk->opp_requested = 0;
140         }
141
142         clk->is_prepared = 0;
143 }
144
145 static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
146 {
147         int err;
148         struct clk_prcmu *clk = to_clk_prcmu(hw);
149
150         if (!clk->opp_requested) {
151                 err = prcmu_request_ape_opp_100_voltage(true);
152                 if (err) {
153                         pr_err("clk_prcmu: %s fail req APE OPP VOLT for %s.\n",
154                                 __func__, clk_hw_get_name(hw));
155                         return err;
156                 }
157                 clk->opp_requested = 1;
158         }
159
160         err = prcmu_request_clock(clk->cg_sel, true);
161         if (err) {
162                 prcmu_request_ape_opp_100_voltage(false);
163                 clk->opp_requested = 0;
164                 return err;
165         }
166
167         clk->is_prepared = 1;
168         return 0;
169 }
170
171 static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
172 {
173         struct clk_prcmu *clk = to_clk_prcmu(hw);
174
175         if (prcmu_request_clock(clk->cg_sel, false)) {
176                 pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
177                         clk_hw_get_name(hw));
178                 return;
179         }
180
181         if (clk->opp_requested) {
182                 prcmu_request_ape_opp_100_voltage(false);
183                 clk->opp_requested = 0;
184         }
185
186         clk->is_prepared = 0;
187 }
188
189 static struct clk_ops clk_prcmu_scalable_ops = {
190         .prepare = clk_prcmu_prepare,
191         .unprepare = clk_prcmu_unprepare,
192         .is_prepared = clk_prcmu_is_prepared,
193         .enable = clk_prcmu_enable,
194         .disable = clk_prcmu_disable,
195         .is_enabled = clk_prcmu_is_enabled,
196         .recalc_rate = clk_prcmu_recalc_rate,
197         .round_rate = clk_prcmu_round_rate,
198         .set_rate = clk_prcmu_set_rate,
199 };
200
201 static struct clk_ops clk_prcmu_gate_ops = {
202         .prepare = clk_prcmu_prepare,
203         .unprepare = clk_prcmu_unprepare,
204         .is_prepared = clk_prcmu_is_prepared,
205         .enable = clk_prcmu_enable,
206         .disable = clk_prcmu_disable,
207         .is_enabled = clk_prcmu_is_enabled,
208         .recalc_rate = clk_prcmu_recalc_rate,
209 };
210
211 static struct clk_ops clk_prcmu_scalable_rate_ops = {
212         .is_enabled = clk_prcmu_is_enabled,
213         .recalc_rate = clk_prcmu_recalc_rate,
214         .round_rate = clk_prcmu_round_rate,
215         .set_rate = clk_prcmu_set_rate,
216 };
217
218 static struct clk_ops clk_prcmu_rate_ops = {
219         .is_enabled = clk_prcmu_is_enabled,
220         .recalc_rate = clk_prcmu_recalc_rate,
221 };
222
223 static struct clk_ops clk_prcmu_opp_gate_ops = {
224         .prepare = clk_prcmu_opp_prepare,
225         .unprepare = clk_prcmu_opp_unprepare,
226         .is_prepared = clk_prcmu_is_prepared,
227         .enable = clk_prcmu_enable,
228         .disable = clk_prcmu_disable,
229         .is_enabled = clk_prcmu_is_enabled,
230         .recalc_rate = clk_prcmu_recalc_rate,
231 };
232
233 static struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
234         .prepare = clk_prcmu_opp_volt_prepare,
235         .unprepare = clk_prcmu_opp_volt_unprepare,
236         .is_prepared = clk_prcmu_is_prepared,
237         .enable = clk_prcmu_enable,
238         .disable = clk_prcmu_disable,
239         .is_enabled = clk_prcmu_is_enabled,
240         .recalc_rate = clk_prcmu_recalc_rate,
241         .round_rate = clk_prcmu_round_rate,
242         .set_rate = clk_prcmu_set_rate,
243 };
244
245 static struct clk *clk_reg_prcmu(const char *name,
246                                  const char *parent_name,
247                                  u8 cg_sel,
248                                  unsigned long rate,
249                                  unsigned long flags,
250                                  struct clk_ops *clk_prcmu_ops)
251 {
252         struct clk_prcmu *clk;
253         struct clk_init_data clk_prcmu_init;
254         struct clk *clk_reg;
255
256         if (!name) {
257                 pr_err("clk_prcmu: %s invalid arguments passed\n", __func__);
258                 return ERR_PTR(-EINVAL);
259         }
260
261         clk = kzalloc(sizeof(struct clk_prcmu), GFP_KERNEL);
262         if (!clk) {
263                 pr_err("clk_prcmu: %s could not allocate clk\n", __func__);
264                 return ERR_PTR(-ENOMEM);
265         }
266
267         clk->cg_sel = cg_sel;
268         clk->is_prepared = 1;
269         clk->is_enabled = 1;
270         clk->opp_requested = 0;
271         /* "rate" can be used for changing the initial frequency */
272         if (rate)
273                 prcmu_set_clock_rate(cg_sel, rate);
274
275         clk_prcmu_init.name = name;
276         clk_prcmu_init.ops = clk_prcmu_ops;
277         clk_prcmu_init.flags = flags;
278         clk_prcmu_init.parent_names = (parent_name ? &parent_name : NULL);
279         clk_prcmu_init.num_parents = (parent_name ? 1 : 0);
280         clk->hw.init = &clk_prcmu_init;
281
282         clk_reg = clk_register(NULL, &clk->hw);
283         if (IS_ERR_OR_NULL(clk_reg))
284                 goto free_clk;
285
286         return clk_reg;
287
288 free_clk:
289         kfree(clk);
290         pr_err("clk_prcmu: %s failed to register clk\n", __func__);
291         return ERR_PTR(-ENOMEM);
292 }
293
294 struct clk *clk_reg_prcmu_scalable(const char *name,
295                                    const char *parent_name,
296                                    u8 cg_sel,
297                                    unsigned long rate,
298                                    unsigned long flags)
299 {
300         return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
301                         &clk_prcmu_scalable_ops);
302 }
303
304 struct clk *clk_reg_prcmu_gate(const char *name,
305                                const char *parent_name,
306                                u8 cg_sel,
307                                unsigned long flags)
308 {
309         return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
310                         &clk_prcmu_gate_ops);
311 }
312
313 struct clk *clk_reg_prcmu_scalable_rate(const char *name,
314                                         const char *parent_name,
315                                         u8 cg_sel,
316                                         unsigned long rate,
317                                         unsigned long flags)
318 {
319         return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
320                         &clk_prcmu_scalable_rate_ops);
321 }
322
323 struct clk *clk_reg_prcmu_rate(const char *name,
324                                const char *parent_name,
325                                u8 cg_sel,
326                                unsigned long flags)
327 {
328         return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
329                         &clk_prcmu_rate_ops);
330 }
331
332 struct clk *clk_reg_prcmu_opp_gate(const char *name,
333                                    const char *parent_name,
334                                    u8 cg_sel,
335                                    unsigned long flags)
336 {
337         return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
338                         &clk_prcmu_opp_gate_ops);
339 }
340
341 struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name,
342                                             const char *parent_name,
343                                             u8 cg_sel,
344                                             unsigned long rate,
345                                             unsigned long flags)
346 {
347         return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
348                         &clk_prcmu_opp_volt_scalable_ops);
349 }