2 * PRCMU clock implementation for ux500 platform.
4 * Copyright (C) 2012 ST-Ericsson SA
5 * Author: Ulf Hansson <ulf.hansson@linaro.org>
7 * License terms: GNU General Public License (GPL) version 2
10 #include <linux/clk-provider.h>
11 #include <linux/clk-private.h>
12 #include <linux/mfd/dbx500-prcmu.h>
13 #include <linux/slab.h>
15 #include <linux/err.h>
18 #define to_clk_prcmu(_hw) container_of(_hw, struct clk_prcmu, hw)
26 /* PRCMU clock operations. */
28 static int clk_prcmu_prepare(struct clk_hw *hw)
30 struct clk_prcmu *clk = to_clk_prcmu(hw);
31 return prcmu_request_clock(clk->cg_sel, true);
34 static void clk_prcmu_unprepare(struct clk_hw *hw)
36 struct clk_prcmu *clk = to_clk_prcmu(hw);
37 if (prcmu_request_clock(clk->cg_sel, false))
38 pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
42 static int clk_prcmu_enable(struct clk_hw *hw)
44 struct clk_prcmu *clk = to_clk_prcmu(hw);
49 static void clk_prcmu_disable(struct clk_hw *hw)
51 struct clk_prcmu *clk = to_clk_prcmu(hw);
55 static int clk_prcmu_is_enabled(struct clk_hw *hw)
57 struct clk_prcmu *clk = to_clk_prcmu(hw);
58 return clk->is_enabled;
61 static unsigned long clk_prcmu_recalc_rate(struct clk_hw *hw,
62 unsigned long parent_rate)
64 struct clk_prcmu *clk = to_clk_prcmu(hw);
65 return prcmu_clock_rate(clk->cg_sel);
68 static long clk_prcmu_round_rate(struct clk_hw *hw, unsigned long rate,
69 unsigned long *parent_rate)
71 struct clk_prcmu *clk = to_clk_prcmu(hw);
72 return prcmu_round_clock_rate(clk->cg_sel, rate);
75 static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate,
76 unsigned long parent_rate)
78 struct clk_prcmu *clk = to_clk_prcmu(hw);
79 return prcmu_set_clock_rate(clk->cg_sel, rate);
82 static int request_ape_opp100(bool enable)
89 err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
96 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
102 static int clk_prcmu_opp_prepare(struct clk_hw *hw)
105 struct clk_prcmu *clk = to_clk_prcmu(hw);
107 err = request_ape_opp100(true);
109 pr_err("clk_prcmu: %s failed to request APE OPP100 for %s.\n",
110 __func__, hw->init->name);
114 err = prcmu_request_clock(clk->cg_sel, true);
116 request_ape_opp100(false);
121 static void clk_prcmu_opp_unprepare(struct clk_hw *hw)
123 struct clk_prcmu *clk = to_clk_prcmu(hw);
125 if (prcmu_request_clock(clk->cg_sel, false))
127 if (request_ape_opp100(false))
132 pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
136 static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
139 struct clk_prcmu *clk = to_clk_prcmu(hw);
141 err = prcmu_request_ape_opp_100_voltage(true);
143 pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n",
144 __func__, hw->init->name);
148 err = prcmu_request_clock(clk->cg_sel, true);
150 prcmu_request_ape_opp_100_voltage(false);
155 static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
157 struct clk_prcmu *clk = to_clk_prcmu(hw);
159 if (prcmu_request_clock(clk->cg_sel, false))
161 if (prcmu_request_ape_opp_100_voltage(false))
166 pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
170 static struct clk_ops clk_prcmu_scalable_ops = {
171 .prepare = clk_prcmu_prepare,
172 .unprepare = clk_prcmu_unprepare,
173 .enable = clk_prcmu_enable,
174 .disable = clk_prcmu_disable,
175 .is_enabled = clk_prcmu_is_enabled,
176 .recalc_rate = clk_prcmu_recalc_rate,
177 .round_rate = clk_prcmu_round_rate,
178 .set_rate = clk_prcmu_set_rate,
181 static struct clk_ops clk_prcmu_gate_ops = {
182 .prepare = clk_prcmu_prepare,
183 .unprepare = clk_prcmu_unprepare,
184 .enable = clk_prcmu_enable,
185 .disable = clk_prcmu_disable,
186 .is_enabled = clk_prcmu_is_enabled,
187 .recalc_rate = clk_prcmu_recalc_rate,
190 static struct clk_ops clk_prcmu_scalable_rate_ops = {
191 .is_enabled = clk_prcmu_is_enabled,
192 .recalc_rate = clk_prcmu_recalc_rate,
193 .round_rate = clk_prcmu_round_rate,
194 .set_rate = clk_prcmu_set_rate,
197 static struct clk_ops clk_prcmu_rate_ops = {
198 .is_enabled = clk_prcmu_is_enabled,
199 .recalc_rate = clk_prcmu_recalc_rate,
202 static struct clk_ops clk_prcmu_opp_gate_ops = {
203 .prepare = clk_prcmu_opp_prepare,
204 .unprepare = clk_prcmu_opp_unprepare,
205 .enable = clk_prcmu_enable,
206 .disable = clk_prcmu_disable,
207 .is_enabled = clk_prcmu_is_enabled,
208 .recalc_rate = clk_prcmu_recalc_rate,
211 static struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
212 .prepare = clk_prcmu_opp_volt_prepare,
213 .unprepare = clk_prcmu_opp_volt_unprepare,
214 .enable = clk_prcmu_enable,
215 .disable = clk_prcmu_disable,
216 .is_enabled = clk_prcmu_is_enabled,
217 .recalc_rate = clk_prcmu_recalc_rate,
218 .round_rate = clk_prcmu_round_rate,
219 .set_rate = clk_prcmu_set_rate,
222 static struct clk *clk_reg_prcmu(const char *name,
223 const char *parent_name,
227 struct clk_ops *clk_prcmu_ops)
229 struct clk_prcmu *clk;
230 struct clk_init_data clk_prcmu_init;
234 pr_err("clk_prcmu: %s invalid arguments passed\n", __func__);
235 return ERR_PTR(-EINVAL);
238 clk = kzalloc(sizeof(struct clk_prcmu), GFP_KERNEL);
240 pr_err("clk_prcmu: %s could not allocate clk\n", __func__);
241 return ERR_PTR(-ENOMEM);
244 clk->cg_sel = cg_sel;
246 /* "rate" can be used for changing the initial frequency */
248 prcmu_set_clock_rate(cg_sel, rate);
250 clk_prcmu_init.name = name;
251 clk_prcmu_init.ops = clk_prcmu_ops;
252 clk_prcmu_init.flags = flags;
253 clk_prcmu_init.parent_names = (parent_name ? &parent_name : NULL);
254 clk_prcmu_init.num_parents = (parent_name ? 1 : 0);
255 clk->hw.init = &clk_prcmu_init;
257 clk_reg = clk_register(NULL, &clk->hw);
258 if (IS_ERR_OR_NULL(clk_reg))
265 pr_err("clk_prcmu: %s failed to register clk\n", __func__);
266 return ERR_PTR(-ENOMEM);
269 struct clk *clk_reg_prcmu_scalable(const char *name,
270 const char *parent_name,
275 return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
276 &clk_prcmu_scalable_ops);
279 struct clk *clk_reg_prcmu_gate(const char *name,
280 const char *parent_name,
284 return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
285 &clk_prcmu_gate_ops);
288 struct clk *clk_reg_prcmu_scalable_rate(const char *name,
289 const char *parent_name,
294 return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
295 &clk_prcmu_scalable_rate_ops);
298 struct clk *clk_reg_prcmu_rate(const char *name,
299 const char *parent_name,
303 return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
304 &clk_prcmu_rate_ops);
307 struct clk *clk_reg_prcmu_opp_gate(const char *name,
308 const char *parent_name,
312 return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
313 &clk_prcmu_opp_gate_ops);
316 struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name,
317 const char *parent_name,
322 return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
323 &clk_prcmu_opp_volt_scalable_ops);