27
27
#include <linux/bitops.h>
29
#include "prm2xxx_3xxx.h"
30
#include "prm-regbits-24xx.h"
31
#include "cm2xxx_3xxx.h"
32
#include "cm-regbits-24xx.h"
33
#include "cminst44xx.h"
36
29
#include <plat/clock.h>
37
#include "powerdomain.h"
38
30
#include "clockdomain.h"
39
#include <plat/prcm.h>
41
32
/* clkdm_list contains all registered struct clockdomains */
42
33
static LIST_HEAD(clkdm_list);
177
169
* XXX autodeps are deprecated and should be removed at the earliest
180
static void _clkdm_add_autodeps(struct clockdomain *clkdm)
172
void _clkdm_add_autodeps(struct clockdomain *clkdm)
182
174
struct clkdm_autodep *autodep;
176
if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS)
187
179
for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
211
203
* XXX autodeps are deprecated and should be removed at the earliest
214
static void _clkdm_del_autodeps(struct clockdomain *clkdm)
206
void _clkdm_del_autodeps(struct clockdomain *clkdm)
216
208
struct clkdm_autodep *autodep;
210
if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS)
221
213
for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
238
* _enable_hwsup - place a clockdomain into hardware-supervised idle
239
* @clkdm: struct clockdomain *
241
* Place the clockdomain into hardware-supervised idle mode. No return
244
* XXX Should this return an error if the clockdomain does not support
245
* hardware-supervised idle mode?
247
static void _enable_hwsup(struct clockdomain *clkdm)
249
if (cpu_is_omap24xx())
250
omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
251
clkdm->clktrctrl_mask);
252
else if (cpu_is_omap34xx())
253
omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
254
clkdm->clktrctrl_mask);
255
else if (cpu_is_omap44xx())
256
return omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
264
* _disable_hwsup - place a clockdomain into software-supervised idle
265
* @clkdm: struct clockdomain *
267
* Place the clockdomain @clkdm into software-supervised idle mode.
230
* _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms
231
* @clkdm: clockdomain that we are resolving dependencies for
232
* @clkdm_deps: ptr to array of struct clkdm_deps to resolve
234
* Iterates through @clkdm_deps, looking up the struct clockdomain named by
235
* clkdm_name and storing the clockdomain pointer in the struct clkdm_dep.
268
236
* No return value.
270
* XXX Should this return an error if the clockdomain does not support
271
* software-supervised idle mode?
273
static void _disable_hwsup(struct clockdomain *clkdm)
238
static void _resolve_clkdm_deps(struct clockdomain *clkdm,
239
struct clkdm_dep *clkdm_deps)
275
if (cpu_is_omap24xx())
276
omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
277
clkdm->clktrctrl_mask);
278
else if (cpu_is_omap34xx())
279
omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
280
clkdm->clktrctrl_mask);
281
else if (cpu_is_omap44xx())
282
return omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
241
struct clkdm_dep *cd;
243
for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) {
244
if (!omap_chip_is(cd->omap_chip))
248
cd->clkdm = _clkdm_lookup(cd->clkdm_name);
250
WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen",
251
clkdm->name, cd->clkdm_name);
289
255
/* Public functions */
292
258
* clkdm_init - set up the clockdomain layer
293
259
* @clkdms: optional pointer to an array of clockdomains to register
294
260
* @init_autodeps: optional pointer to an array of autodeps to register
261
* @custom_funcs: func pointers for arch specific implementations
296
263
* Set up internal state. If a pointer to an array of clockdomains
297
264
* @clkdms was supplied, loop through the list of clockdomains,
300
267
* @init_autodeps was provided, register those. No return value.
302
269
void clkdm_init(struct clockdomain **clkdms,
303
struct clkdm_autodep *init_autodeps)
270
struct clkdm_autodep *init_autodeps,
271
struct clkdm_ops *custom_funcs)
305
273
struct clockdomain **c = NULL;
306
274
struct clockdomain *clkdm;
307
275
struct clkdm_autodep *autodep = NULL;
278
WARN(1, "No custom clkdm functions registered\n");
280
arch_clkdm = custom_funcs;
310
283
for (c = clkdms; *c; c++)
311
284
_clkdm_register(*c);
322
295
list_for_each_entry(clkdm, &clkdm_list, node) {
323
296
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
324
omap2_clkdm_wakeup(clkdm);
325
298
else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
326
omap2_clkdm_deny_idle(clkdm);
299
clkdm_deny_idle(clkdm);
301
_resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs);
328
302
clkdm_clear_all_wkdeps(clkdm);
304
_resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs);
329
305
clkdm_clear_all_sleepdeps(clkdm);
422
398
int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
424
400
struct clkdm_dep *cd;
426
if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
427
pr_err("clockdomain: %s/%s: %s: not yet implemented\n",
428
clkdm1->name, clkdm2->name, __func__);
432
403
if (!clkdm1 || !clkdm2)
435
406
cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
410
if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep)
437
414
pr_debug("clockdomain: hardware cannot set/clear wake up of "
438
415
"%s when %s wakes up\n", clkdm1->name, clkdm2->name);
442
419
if (atomic_inc_return(&cd->wkdep_usecount) == 1) {
443
420
pr_debug("clockdomain: hardware will wake up %s when %s wakes "
444
421
"up\n", clkdm1->name, clkdm2->name);
446
omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
447
clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
423
ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
463
439
int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
465
441
struct clkdm_dep *cd;
467
if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
468
pr_err("clockdomain: %s/%s: %s: not yet implemented\n",
469
clkdm1->name, clkdm2->name, __func__);
473
444
if (!clkdm1 || !clkdm2)
476
447
cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
451
if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep)
478
455
pr_debug("clockdomain: hardware cannot set/clear wake up of "
479
456
"%s when %s wakes up\n", clkdm1->name, clkdm2->name);
483
460
if (atomic_dec_return(&cd->wkdep_usecount) == 0) {
484
461
pr_debug("clockdomain: hardware will no longer wake up %s "
485
462
"after %s wakes up\n", clkdm1->name, clkdm2->name);
487
omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
488
clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
464
ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2);
508
484
int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
510
486
struct clkdm_dep *cd;
512
489
if (!clkdm1 || !clkdm2)
515
if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
516
pr_err("clockdomain: %s/%s: %s: not yet implemented\n",
517
clkdm1->name, clkdm2->name, __func__);
521
492
cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
496
if (!arch_clkdm || !arch_clkdm->clkdm_read_wkdep)
523
500
pr_debug("clockdomain: hardware cannot set/clear wake up of "
524
501
"%s when %s wakes up\n", clkdm1->name, clkdm2->name);
528
505
/* XXX It's faster to return the atomic wkdep_usecount */
529
return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP,
530
(1 << clkdm2->dep_bit));
506
return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2);
543
519
int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
545
struct clkdm_dep *cd;
548
if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
549
pr_err("clockdomain: %s: %s: not yet implemented\n",
550
clkdm->name, __func__);
557
for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
558
if (!omap_chip_is(cd->omap_chip))
561
if (!cd->clkdm && cd->clkdm_name)
562
cd->clkdm = _clkdm_lookup(cd->clkdm_name);
564
/* PRM accesses are slow, so minimize them */
565
mask |= 1 << cd->clkdm->dep_bit;
566
atomic_set(&cd->wkdep_usecount, 0);
569
omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, PM_WKDEP);
524
if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_wkdeps)
527
return arch_clkdm->clkdm_clear_all_wkdeps(clkdm);
586
542
int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
588
544
struct clkdm_dep *cd;
590
if (!cpu_is_omap34xx())
593
547
if (!clkdm1 || !clkdm2)
596
550
cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
554
if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep)
598
558
pr_debug("clockdomain: hardware cannot set/clear sleep "
599
559
"dependency affecting %s from %s\n", clkdm1->name,
604
564
if (atomic_inc_return(&cd->sleepdep_usecount) == 1) {
605
565
pr_debug("clockdomain: will prevent %s from sleeping if %s "
606
566
"is active\n", clkdm1->name, clkdm2->name);
608
omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
609
clkdm1->pwrdm.ptr->prcm_offs,
610
OMAP3430_CM_SLEEPDEP);
568
ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2);
628
586
int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
630
588
struct clkdm_dep *cd;
632
if (!cpu_is_omap34xx())
635
591
if (!clkdm1 || !clkdm2)
638
594
cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
598
if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep)
640
602
pr_debug("clockdomain: hardware cannot set/clear sleep "
641
603
"dependency affecting %s from %s\n", clkdm1->name,
646
608
if (atomic_dec_return(&cd->sleepdep_usecount) == 0) {
648
610
"sleeping if %s is active\n", clkdm1->name,
651
omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
652
clkdm1->pwrdm.ptr->prcm_offs,
653
OMAP3430_CM_SLEEPDEP);
613
ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2);
675
635
int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
677
637
struct clkdm_dep *cd;
679
if (!cpu_is_omap34xx())
682
640
if (!clkdm1 || !clkdm2)
685
643
cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
647
if (!arch_clkdm || !arch_clkdm->clkdm_read_sleepdep)
687
651
pr_debug("clockdomain: hardware cannot set/clear sleep "
688
652
"dependency affecting %s from %s\n", clkdm1->name,
693
657
/* XXX It's faster to return the atomic sleepdep_usecount */
694
return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
695
OMAP3430_CM_SLEEPDEP,
696
(1 << clkdm2->dep_bit));
658
return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2);
709
671
int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
711
struct clkdm_dep *cd;
714
if (!cpu_is_omap34xx())
720
for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
721
if (!omap_chip_is(cd->omap_chip))
724
if (!cd->clkdm && cd->clkdm_name)
725
cd->clkdm = _clkdm_lookup(cd->clkdm_name);
727
/* PRM accesses are slow, so minimize them */
728
mask |= 1 << cd->clkdm->dep_bit;
729
atomic_set(&cd->sleepdep_usecount, 0);
732
omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
733
OMAP3430_CM_SLEEPDEP);
676
if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_sleepdeps)
679
return arch_clkdm->clkdm_clear_all_sleepdeps(clkdm);
739
* omap2_clkdm_sleep - force clockdomain sleep transition
683
* clkdm_sleep - force clockdomain sleep transition
740
684
* @clkdm: struct clockdomain *
742
686
* Instruct the CM to force a sleep transition on the specified
702
if (!arch_clkdm || !arch_clkdm->clkdm_sleep)
758
705
pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);
760
if (cpu_is_omap24xx()) {
762
omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
763
clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
765
} else if (cpu_is_omap34xx()) {
767
omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
768
clkdm->clktrctrl_mask);
770
} else if (cpu_is_omap44xx()) {
772
omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
707
return arch_clkdm->clkdm_sleep(clkdm);
784
* omap2_clkdm_wakeup - force clockdomain wakeup transition
711
* clkdm_wakeup - force clockdomain wakeup transition
785
712
* @clkdm: struct clockdomain *
787
714
* Instruct the CM to force a wakeup transition on the specified
730
if (!arch_clkdm || !arch_clkdm->clkdm_wakeup)
803
733
pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name);
805
if (cpu_is_omap24xx()) {
807
omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
808
clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
810
} else if (cpu_is_omap34xx()) {
812
omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
813
clkdm->clktrctrl_mask);
815
} else if (cpu_is_omap44xx()) {
817
omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
735
return arch_clkdm->clkdm_wakeup(clkdm);
829
* omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm
739
* clkdm_allow_idle - enable hwsup idle transitions for clkdm
830
740
* @clkdm: struct clockdomain *
832
742
* Allow the hardware to automatically switch the clockdomain @clkdm into
759
if (!arch_clkdm || !arch_clkdm->clkdm_allow_idle)
849
762
pr_debug("clockdomain: enabling automatic idle transitions for %s\n",
853
* XXX This should be removed once TI adds wakeup/sleep
854
* dependency code and data for OMAP4.
856
if (cpu_is_omap44xx()) {
857
pr_err("clockdomain: %s: OMAP4 wakeup/sleep dependency support: not yet implemented\n", clkdm->name);
859
if (atomic_read(&clkdm->usecount) > 0)
860
_clkdm_add_autodeps(clkdm);
863
_enable_hwsup(clkdm);
765
arch_clkdm->clkdm_allow_idle(clkdm);
865
766
pwrdm_clkdm_state_switch(clkdm);
869
* omap2_clkdm_deny_idle - disable hwsup idle transitions for clkdm
770
* clkdm_deny_idle - disable hwsup idle transitions for clkdm
870
771
* @clkdm: struct clockdomain *
872
773
* Prevent the hardware from automatically switching the clockdomain
789
if (!arch_clkdm || !arch_clkdm->clkdm_deny_idle)
888
792
pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
891
_disable_hwsup(clkdm);
894
* XXX This should be removed once TI adds wakeup/sleep
895
* dependency code and data for OMAP4.
897
if (cpu_is_omap44xx()) {
898
pr_err("clockdomain: %s: OMAP4 wakeup/sleep dependency support: not yet implemented\n", clkdm->name);
900
if (atomic_read(&clkdm->usecount) > 0)
901
_clkdm_del_autodeps(clkdm);
795
arch_clkdm->clkdm_deny_idle(clkdm);
906
799
/* Clockdomain-to-clock framework interface code */
909
* omap2_clkdm_clk_enable - add an enabled downstream clock to this clkdm
802
* clkdm_clk_enable - add an enabled downstream clock to this clkdm
910
803
* @clkdm: struct clockdomain *
911
804
* @clk: struct clk * of the enabled downstream clock
919
812
* by on-chip processors. Returns -EINVAL if passed null pointers;
920
813
* returns 0 upon success or if the clockdomain is in hwsup idle mode.
922
int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
815
int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
927
818
* XXX Rewrite this code to maintain a list of enabled
928
819
* downstream clocks for debugging purposes?
939
833
pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name,
942
if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
944
if (!clkdm->clktrctrl_mask)
947
hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
948
clkdm->clktrctrl_mask);
950
} else if (cpu_is_omap44xx()) {
952
hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
959
/* Disable HW transitions when we are changing deps */
960
_disable_hwsup(clkdm);
961
_clkdm_add_autodeps(clkdm);
962
_enable_hwsup(clkdm);
964
omap2_clkdm_wakeup(clkdm);
836
arch_clkdm->clkdm_clk_enable(clkdm);
967
837
pwrdm_wait_transition(clkdm->pwrdm.ptr);
968
838
pwrdm_clkdm_state_switch(clkdm);
984
854
* is enabled; or returns 0 upon success or if the clockdomain is in
985
855
* hwsup idle mode.
987
int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
857
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
992
860
* XXX Rewrite this code to maintain a list of enabled
993
861
* downstream clocks for debugging purposes?
1011
882
pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name,
1014
if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1016
if (!clkdm->clktrctrl_mask)
1019
hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
1020
clkdm->clktrctrl_mask);
1022
} else if (cpu_is_omap44xx()) {
1024
hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
1031
/* Disable HW transitions when we are changing deps */
1032
_disable_hwsup(clkdm);
1033
_clkdm_del_autodeps(clkdm);
1034
_enable_hwsup(clkdm);
1036
omap2_clkdm_sleep(clkdm);
885
arch_clkdm->clkdm_clk_disable(clkdm);
1039
886
pwrdm_clkdm_state_switch(clkdm);