aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/bcm/clk-kona-setup.c
diff options
context:
space:
mode:
authorAlex Elder <elder@linaro.org>2014-04-21 17:11:42 -0400
committerMike Turquette <mturquette@linaro.org>2014-04-30 14:51:36 -0400
commita597faccc7eedd406313e880ed05ff75bc522910 (patch)
tree4e463bcfde259380a3ea5b50534272357f007dc8 /drivers/clk/bcm/clk-kona-setup.c
parent03548ec06ad3ec75d5b212fa832e4e617334ea09 (diff)
clk: bcm281xx: add clock policy support
Add support for CCU policy engine control, and also for setting the mask bits for bus clocks that require a policy change to get activated. This includes adding validity checking framework for CCUs, to validate the policy fields if defined. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk/bcm/clk-kona-setup.c')
-rw-r--r--drivers/clk/bcm/clk-kona-setup.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c
index 825a2f2ab052..773ad7c7dd59 100644
--- a/drivers/clk/bcm/clk-kona-setup.c
+++ b/drivers/clk/bcm/clk-kona-setup.c
@@ -25,6 +25,31 @@ LIST_HEAD(ccu_list); /* The list of set up CCUs */
25 25
26/* Validity checking */ 26/* Validity checking */
27 27
28static bool ccu_data_offsets_valid(struct ccu_data *ccu)
29{
30 struct ccu_policy *ccu_policy = &ccu->policy;
31 u32 limit;
32
33 limit = ccu->range - sizeof(u32);
34 limit = round_down(limit, sizeof(u32));
35 if (ccu_policy_exists(ccu_policy)) {
36 if (ccu_policy->enable.offset > limit) {
37 pr_err("%s: bad policy enable offset for %s "
38 "(%u > %u)\n", __func__,
39 ccu->name, ccu_policy->enable.offset, limit);
40 return false;
41 }
42 if (ccu_policy->control.offset > limit) {
43 pr_err("%s: bad policy control offset for %s "
44 "(%u > %u)\n", __func__,
45 ccu->name, ccu_policy->control.offset, limit);
46 return false;
47 }
48 }
49
50 return true;
51}
52
28static bool clk_requires_trigger(struct kona_clk *bcm_clk) 53static bool clk_requires_trigger(struct kona_clk *bcm_clk)
29{ 54{
30 struct peri_clk_data *peri = bcm_clk->u.peri; 55 struct peri_clk_data *peri = bcm_clk->u.peri;
@@ -54,6 +79,7 @@ static bool clk_requires_trigger(struct kona_clk *bcm_clk)
54static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk) 79static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk)
55{ 80{
56 struct peri_clk_data *peri; 81 struct peri_clk_data *peri;
82 struct bcm_clk_policy *policy;
57 struct bcm_clk_gate *gate; 83 struct bcm_clk_gate *gate;
58 struct bcm_clk_div *div; 84 struct bcm_clk_div *div;
59 struct bcm_clk_sel *sel; 85 struct bcm_clk_sel *sel;
@@ -70,6 +96,15 @@ static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk)
70 limit = range - sizeof(u32); 96 limit = range - sizeof(u32);
71 limit = round_down(limit, sizeof(u32)); 97 limit = round_down(limit, sizeof(u32));
72 98
99 policy = &peri->policy;
100 if (policy_exists(policy)) {
101 if (policy->offset > limit) {
102 pr_err("%s: bad policy offset for %s (%u > %u)\n",
103 __func__, name, policy->offset, limit);
104 return false;
105 }
106 }
107
73 gate = &peri->gate; 108 gate = &peri->gate;
74 if (gate_exists(gate)) { 109 if (gate_exists(gate)) {
75 if (gate->offset > limit) { 110 if (gate->offset > limit) {
@@ -167,6 +202,36 @@ static bool bitfield_valid(u32 shift, u32 width, const char *field_name,
167 return true; 202 return true;
168} 203}
169 204
205static bool
206ccu_policy_valid(struct ccu_policy *ccu_policy, const char *ccu_name)
207{
208 struct bcm_lvm_en *enable = &ccu_policy->enable;
209 struct bcm_policy_ctl *control;
210
211 if (!bit_posn_valid(enable->bit, "policy enable", ccu_name))
212 return false;
213
214 control = &ccu_policy->control;
215 if (!bit_posn_valid(control->go_bit, "policy control GO", ccu_name))
216 return false;
217
218 if (!bit_posn_valid(control->atl_bit, "policy control ATL", ccu_name))
219 return false;
220
221 if (!bit_posn_valid(control->ac_bit, "policy control AC", ccu_name))
222 return false;
223
224 return true;
225}
226
227static bool policy_valid(struct bcm_clk_policy *policy, const char *clock_name)
228{
229 if (!bit_posn_valid(policy->bit, "policy", clock_name))
230 return false;
231
232 return true;
233}
234
170/* 235/*
171 * All gates, if defined, have a status bit, and for hardware-only 236 * All gates, if defined, have a status bit, and for hardware-only
172 * gates, that's it. Gates that can be software controlled also 237 * gates, that's it. Gates that can be software controlled also
@@ -312,6 +377,7 @@ static bool
312peri_clk_data_valid(struct kona_clk *bcm_clk) 377peri_clk_data_valid(struct kona_clk *bcm_clk)
313{ 378{
314 struct peri_clk_data *peri; 379 struct peri_clk_data *peri;
380 struct bcm_clk_policy *policy;
315 struct bcm_clk_gate *gate; 381 struct bcm_clk_gate *gate;
316 struct bcm_clk_sel *sel; 382 struct bcm_clk_sel *sel;
317 struct bcm_clk_div *div; 383 struct bcm_clk_div *div;
@@ -331,6 +397,11 @@ peri_clk_data_valid(struct kona_clk *bcm_clk)
331 397
332 peri = bcm_clk->u.peri; 398 peri = bcm_clk->u.peri;
333 name = bcm_clk->init_data.name; 399 name = bcm_clk->init_data.name;
400
401 policy = &peri->policy;
402 if (policy_exists(policy) && !policy_valid(policy, name))
403 return false;
404
334 gate = &peri->gate; 405 gate = &peri->gate;
335 if (gate_exists(gate) && !gate_valid(gate, "gate", name)) 406 if (gate_exists(gate) && !gate_valid(gate, "gate", name))
336 return false; 407 return false;
@@ -679,6 +750,21 @@ static void kona_ccu_teardown(struct ccu_data *ccu)
679 ccu->base = NULL; 750 ccu->base = NULL;
680} 751}
681 752
753static bool ccu_data_valid(struct ccu_data *ccu)
754{
755 struct ccu_policy *ccu_policy;
756
757 if (!ccu_data_offsets_valid(ccu))
758 return false;
759
760 ccu_policy = &ccu->policy;
761 if (ccu_policy_exists(ccu_policy))
762 if (!ccu_policy_valid(ccu_policy, ccu->name))
763 return false;
764
765 return true;
766}
767
682/* 768/*
683 * Set up a CCU. Call the provided ccu_clks_setup callback to 769 * Set up a CCU. Call the provided ccu_clks_setup callback to
684 * initialize the array of clocks provided by the CCU. 770 * initialize the array of clocks provided by the CCU.
@@ -718,6 +804,12 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu,
718 } 804 }
719 805
720 ccu->range = (u32)range; 806 ccu->range = (u32)range;
807
808 if (!ccu_data_valid(ccu)) {
809 pr_err("%s: ccu data not valid for %s\n", __func__, node->name);
810 goto out_err;
811 }
812
721 ccu->base = ioremap(res.start, ccu->range); 813 ccu->base = ioremap(res.start, ccu->range);
722 if (!ccu->base) { 814 if (!ccu->base) {
723 pr_err("%s: unable to map CCU registers for %s\n", __func__, 815 pr_err("%s: unable to map CCU registers for %s\n", __func__,