1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128#undef DEBUG
129
130#include <linux/kernel.h>
131#include <linux/errno.h>
132#include <linux/io.h>
133#include <linux/clk.h>
134#include <linux/clk-provider.h>
135#include <linux/delay.h>
136#include <linux/err.h>
137#include <linux/list.h>
138#include <linux/mutex.h>
139#include <linux/spinlock.h>
140#include <linux/slab.h>
141#include <linux/cpu.h>
142#include <linux/of.h>
143#include <linux/of_address.h>
144#include <linux/memblock.h>
145
146#include <linux/platform_data/ti-sysc.h>
147
148#include <dt-bindings/bus/ti-sysc.h>
149
150#include <asm/system_misc.h>
151
152#include "clock.h"
153#include "omap_hwmod.h"
154
155#include "soc.h"
156#include "common.h"
157#include "clockdomain.h"
158#include "powerdomain.h"
159#include "cm2xxx.h"
160#include "cm3xxx.h"
161#include "cm33xx.h"
162#include "prm.h"
163#include "prm3xxx.h"
164#include "prm44xx.h"
165#include "prm33xx.h"
166#include "prminst44xx.h"
167#include "pm.h"
168
169
170#define MPU_INITIATOR_NAME "mpu"
171
172
173
174
175
176#define LINKS_PER_OCP_IF 2
177
178
179
180
181
182#define OMAP4_RST_CTRL_ST_OFFSET 4
183
184
185
186
187#define MOD_CLK_MAX_NAME_LEN 32
188
189
190
191
192
193
194
195
196
197struct clkctrl_provider {
198 int num_addrs;
199 u32 *addr;
200 u32 *size;
201 struct device_node *node;
202 struct list_head link;
203};
204
205static LIST_HEAD(clkctrl_providers);
206
207
208
209
210
211
212
213
214
215
216struct omap_hwmod_soc_ops {
217 void (*enable_module)(struct omap_hwmod *oh);
218 int (*disable_module)(struct omap_hwmod *oh);
219 int (*wait_target_ready)(struct omap_hwmod *oh);
220 int (*assert_hardreset)(struct omap_hwmod *oh,
221 struct omap_hwmod_rst_info *ohri);
222 int (*deassert_hardreset)(struct omap_hwmod *oh,
223 struct omap_hwmod_rst_info *ohri);
224 int (*is_hardreset_asserted)(struct omap_hwmod *oh,
225 struct omap_hwmod_rst_info *ohri);
226 int (*init_clkdm)(struct omap_hwmod *oh);
227 void (*update_context_lost)(struct omap_hwmod *oh);
228 int (*get_context_lost)(struct omap_hwmod *oh);
229 int (*disable_direct_prcm)(struct omap_hwmod *oh);
230 u32 (*xlate_clkctrl)(struct omap_hwmod *oh);
231};
232
233
234static struct omap_hwmod_soc_ops soc_ops;
235
236
237static LIST_HEAD(omap_hwmod_list);
238
239
240static struct omap_hwmod *mpu_oh;
241
242
243static bool inited;
244
245
246
247
248
249
250
251
252
253
254
255static int _update_sysc_cache(struct omap_hwmod *oh)
256{
257 if (!oh->class->sysc) {
258 WARN(1, "omap_hwmod: %s: cannot read OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
259 return -EINVAL;
260 }
261
262
263
264 oh->_sysc_cache = omap_hwmod_read(oh, oh->class->sysc->sysc_offs);
265
266 if (!(oh->class->sysc->sysc_flags & SYSC_NO_CACHE))
267 oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
268
269 return 0;
270}
271
272
273
274
275
276
277
278
279
280static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
281{
282 if (!oh->class->sysc) {
283 WARN(1, "omap_hwmod: %s: cannot write OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
284 return;
285 }
286
287
288
289
290 oh->_sysc_cache = v;
291
292
293
294
295
296
297
298 if (oh->class->unlock)
299 oh->class->unlock(oh);
300
301 omap_hwmod_write(v, oh, oh->class->sysc->sysc_offs);
302
303 if (oh->class->lock)
304 oh->class->lock(oh);
305}
306
307
308
309
310
311
312
313
314
315
316
317static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
318 u32 *v)
319{
320 u32 mstandby_mask;
321 u8 mstandby_shift;
322
323 if (!oh->class->sysc ||
324 !(oh->class->sysc->sysc_flags & SYSC_HAS_MIDLEMODE))
325 return -EINVAL;
326
327 if (!oh->class->sysc->sysc_fields) {
328 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
329 return -EINVAL;
330 }
331
332 mstandby_shift = oh->class->sysc->sysc_fields->midle_shift;
333 mstandby_mask = (0x3 << mstandby_shift);
334
335 *v &= ~mstandby_mask;
336 *v |= __ffs(standbymode) << mstandby_shift;
337
338 return 0;
339}
340
341
342
343
344
345
346
347
348
349
350
351static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
352{
353 u32 sidle_mask;
354 u8 sidle_shift;
355
356 if (!oh->class->sysc ||
357 !(oh->class->sysc->sysc_flags & SYSC_HAS_SIDLEMODE))
358 return -EINVAL;
359
360 if (!oh->class->sysc->sysc_fields) {
361 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
362 return -EINVAL;
363 }
364
365 sidle_shift = oh->class->sysc->sysc_fields->sidle_shift;
366 sidle_mask = (0x3 << sidle_shift);
367
368 *v &= ~sidle_mask;
369 *v |= __ffs(idlemode) << sidle_shift;
370
371 return 0;
372}
373
374
375
376
377
378
379
380
381
382
383
384
385static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
386{
387 u32 clkact_mask;
388 u8 clkact_shift;
389
390 if (!oh->class->sysc ||
391 !(oh->class->sysc->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
392 return -EINVAL;
393
394 if (!oh->class->sysc->sysc_fields) {
395 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
396 return -EINVAL;
397 }
398
399 clkact_shift = oh->class->sysc->sysc_fields->clkact_shift;
400 clkact_mask = (0x3 << clkact_shift);
401
402 *v &= ~clkact_mask;
403 *v |= clockact << clkact_shift;
404
405 return 0;
406}
407
408
409
410
411
412
413
414
415
416static int _set_softreset(struct omap_hwmod *oh, u32 *v)
417{
418 u32 softrst_mask;
419
420 if (!oh->class->sysc ||
421 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
422 return -EINVAL;
423
424 if (!oh->class->sysc->sysc_fields) {
425 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
426 return -EINVAL;
427 }
428
429 softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
430
431 *v |= softrst_mask;
432
433 return 0;
434}
435
436
437
438
439
440
441
442
443
444static int _clear_softreset(struct omap_hwmod *oh, u32 *v)
445{
446 u32 softrst_mask;
447
448 if (!oh->class->sysc ||
449 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
450 return -EINVAL;
451
452 if (!oh->class->sysc->sysc_fields) {
453 WARN(1,
454 "omap_hwmod: %s: sysc_fields absent for sysconfig class\n",
455 oh->name);
456 return -EINVAL;
457 }
458
459 softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
460
461 *v &= ~softrst_mask;
462
463 return 0;
464}
465
466
467
468
469
470
471
472
473
474
475
476static int _wait_softreset_complete(struct omap_hwmod *oh)
477{
478 struct omap_hwmod_class_sysconfig *sysc;
479 u32 softrst_mask;
480 int c = 0;
481
482 sysc = oh->class->sysc;
483
484 if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS && sysc->syss_offs > 0)
485 omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
486 & SYSS_RESETDONE_MASK),
487 MAX_MODULE_SOFTRESET_WAIT, c);
488 else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
489 softrst_mask = (0x1 << sysc->sysc_fields->srst_shift);
490 omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs)
491 & softrst_mask),
492 MAX_MODULE_SOFTRESET_WAIT, c);
493 }
494
495 return c;
496}
497
498
499
500
501
502
503
504
505
506
507
508
509
510static int _set_dmadisable(struct omap_hwmod *oh)
511{
512 u32 v;
513 u32 dmadisable_mask;
514
515 if (!oh->class->sysc ||
516 !(oh->class->sysc->sysc_flags & SYSC_HAS_DMADISABLE))
517 return -EINVAL;
518
519 if (!oh->class->sysc->sysc_fields) {
520 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
521 return -EINVAL;
522 }
523
524
525 if (oh->_state != _HWMOD_STATE_ENABLED) {
526 pr_warn("omap_hwmod: %s: dma can be disabled only from enabled state\n", oh->name);
527 return -EINVAL;
528 }
529
530 pr_debug("omap_hwmod: %s: setting DMADISABLE\n", oh->name);
531
532 v = oh->_sysc_cache;
533 dmadisable_mask =
534 (0x1 << oh->class->sysc->sysc_fields->dmadisable_shift);
535 v |= dmadisable_mask;
536 _write_sysconfig(v, oh);
537
538 return 0;
539}
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
555 u32 *v)
556{
557 u32 autoidle_mask;
558 u8 autoidle_shift;
559
560 if (!oh->class->sysc ||
561 !(oh->class->sysc->sysc_flags & SYSC_HAS_AUTOIDLE))
562 return -EINVAL;
563
564 if (!oh->class->sysc->sysc_fields) {
565 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
566 return -EINVAL;
567 }
568
569 autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift;
570 autoidle_mask = (0x1 << autoidle_shift);
571
572 *v &= ~autoidle_mask;
573 *v |= autoidle << autoidle_shift;
574
575 return 0;
576}
577
578
579
580
581
582
583
584
585static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
586{
587 if (!oh->class->sysc ||
588 !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
589 (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
590 (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))
591 return -EINVAL;
592
593 if (!oh->class->sysc->sysc_fields) {
594 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
595 return -EINVAL;
596 }
597
598 if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
599 *v |= 0x1 << oh->class->sysc->sysc_fields->enwkup_shift;
600
601 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
602 _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
603 if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
604 _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
605
606
607
608 return 0;
609}
610
611
612
613
614
615
616
617
618static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
619{
620 if (!oh->class->sysc ||
621 !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
622 (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
623 (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))
624 return -EINVAL;
625
626 if (!oh->class->sysc->sysc_fields) {
627 WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
628 return -EINVAL;
629 }
630
631 if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
632 *v &= ~(0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
633
634 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
635 _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
636 if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
637 _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART, v);
638
639
640
641 return 0;
642}
643
644static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
645{
646 struct clk_hw_omap *clk;
647
648 if (oh->clkdm) {
649 return oh->clkdm;
650 } else if (oh->_clk) {
651 if (__clk_get_flags(oh->_clk) & CLK_IS_BASIC)
652 return NULL;
653 clk = to_clk_hw_omap(__clk_get_hw(oh->_clk));
654 return clk->clkdm;
655 }
656 return NULL;
657}
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
673{
674 struct clockdomain *clkdm, *init_clkdm;
675
676 clkdm = _get_clkdm(oh);
677 init_clkdm = _get_clkdm(init_oh);
678
679 if (!clkdm || !init_clkdm)
680 return -EINVAL;
681
682 if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS)
683 return 0;
684
685 return clkdm_add_sleepdep(clkdm, init_clkdm);
686}
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
702{
703 struct clockdomain *clkdm, *init_clkdm;
704
705 clkdm = _get_clkdm(oh);
706 init_clkdm = _get_clkdm(init_oh);
707
708 if (!clkdm || !init_clkdm)
709 return -EINVAL;
710
711 if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS)
712 return 0;
713
714 return clkdm_del_sleepdep(clkdm, init_clkdm);
715}
716
717static const struct of_device_id ti_clkctrl_match_table[] __initconst = {
718 { .compatible = "ti,clkctrl" },
719 { }
720};
721
722static int __init _setup_clkctrl_provider(struct device_node *np)
723{
724 const __be32 *addrp;
725 struct clkctrl_provider *provider;
726 u64 size;
727 int i;
728
729 provider = memblock_alloc(sizeof(*provider), SMP_CACHE_BYTES);
730 if (!provider)
731 return -ENOMEM;
732
733 provider->node = np;
734
735 provider->num_addrs =
736 of_property_count_elems_of_size(np, "reg", sizeof(u32)) / 2;
737
738 provider->addr =
739 memblock_alloc(sizeof(void *) * provider->num_addrs,
740 SMP_CACHE_BYTES);
741 if (!provider->addr)
742 return -ENOMEM;
743
744 provider->size =
745 memblock_alloc(sizeof(u32) * provider->num_addrs,
746 SMP_CACHE_BYTES);
747 if (!provider->size)
748 return -ENOMEM;
749
750 for (i = 0; i < provider->num_addrs; i++) {
751 addrp = of_get_address(np, i, &size, NULL);
752 provider->addr[i] = (u32)of_translate_address(np, addrp);
753 provider->size[i] = size;
754 pr_debug("%s: %pOF: %x...%x\n", __func__, np, provider->addr[i],
755 provider->addr[i] + provider->size[i]);
756 }
757
758 list_add(&provider->link, &clkctrl_providers);
759
760 return 0;
761}
762
763static int __init _init_clkctrl_providers(void)
764{
765 struct device_node *np;
766 int ret = 0;
767
768 for_each_matching_node(np, ti_clkctrl_match_table) {
769 ret = _setup_clkctrl_provider(np);
770 if (ret)
771 break;
772 }
773
774 return ret;
775}
776
777static u32 _omap4_xlate_clkctrl(struct omap_hwmod *oh)
778{
779 if (!oh->prcm.omap4.modulemode)
780 return 0;
781
782 return omap_cm_xlate_clkctrl(oh->clkdm->prcm_partition,
783 oh->clkdm->cm_inst,
784 oh->prcm.omap4.clkctrl_offs);
785}
786
787static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh)
788{
789 struct clkctrl_provider *provider;
790 struct clk *clk;
791 u32 addr;
792
793 if (!soc_ops.xlate_clkctrl)
794 return NULL;
795
796 addr = soc_ops.xlate_clkctrl(oh);
797 if (!addr)
798 return NULL;
799
800 pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr);
801
802 list_for_each_entry(provider, &clkctrl_providers, link) {
803 int i;
804
805 for (i = 0; i < provider->num_addrs; i++) {
806 if (provider->addr[i] <= addr &&
807 provider->addr[i] + provider->size[i] > addr) {
808 struct of_phandle_args clkspec;
809
810 clkspec.np = provider->node;
811 clkspec.args_count = 2;
812 clkspec.args[0] = addr - provider->addr[0];
813 clkspec.args[1] = 0;
814
815 clk = of_clk_get_from_provider(&clkspec);
816
817 pr_debug("%s: %s got %p (offset=%x, provider=%pOF)\n",
818 __func__, oh->name, clk,
819 clkspec.args[0], provider->node);
820
821 return clk;
822 }
823 }
824 }
825
826 return NULL;
827}
828
829
830
831
832
833
834
835
836
837static int _init_main_clk(struct omap_hwmod *oh)
838{
839 int ret = 0;
840 struct clk *clk = NULL;
841
842 clk = _lookup_clkctrl_clk(oh);
843
844 if (!IS_ERR_OR_NULL(clk)) {
845 pr_debug("%s: mapped main_clk %s for %s\n", __func__,
846 __clk_get_name(clk), oh->name);
847 oh->main_clk = __clk_get_name(clk);
848 oh->_clk = clk;
849 soc_ops.disable_direct_prcm(oh);
850 } else {
851 if (!oh->main_clk)
852 return 0;
853
854 oh->_clk = clk_get(NULL, oh->main_clk);
855 }
856
857 if (IS_ERR(oh->_clk)) {
858 pr_warn("omap_hwmod: %s: cannot clk_get main_clk %s\n",
859 oh->name, oh->main_clk);
860 return -EINVAL;
861 }
862
863
864
865
866
867
868
869
870 clk_prepare(oh->_clk);
871
872 if (!_get_clkdm(oh))
873 pr_debug("omap_hwmod: %s: missing clockdomain for %s.\n",
874 oh->name, oh->main_clk);
875
876 return ret;
877}
878
879
880
881
882
883
884
885
886static int _init_interface_clks(struct omap_hwmod *oh)
887{
888 struct omap_hwmod_ocp_if *os;
889 struct clk *c;
890 int ret = 0;
891
892 list_for_each_entry(os, &oh->slave_ports, node) {
893 if (!os->clk)
894 continue;
895
896 c = clk_get(NULL, os->clk);
897 if (IS_ERR(c)) {
898 pr_warn("omap_hwmod: %s: cannot clk_get interface_clk %s\n",
899 oh->name, os->clk);
900 ret = -EINVAL;
901 continue;
902 }
903 os->_clk = c;
904
905
906
907
908
909
910
911
912 clk_prepare(os->_clk);
913 }
914
915 return ret;
916}
917
918
919
920
921
922
923
924
925static int _init_opt_clks(struct omap_hwmod *oh)
926{
927 struct omap_hwmod_opt_clk *oc;
928 struct clk *c;
929 int i;
930 int ret = 0;
931
932 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
933 c = clk_get(NULL, oc->clk);
934 if (IS_ERR(c)) {
935 pr_warn("omap_hwmod: %s: cannot clk_get opt_clk %s\n",
936 oh->name, oc->clk);
937 ret = -EINVAL;
938 continue;
939 }
940 oc->_clk = c;
941
942
943
944
945
946
947
948
949 clk_prepare(oc->_clk);
950 }
951
952 return ret;
953}
954
955static void _enable_optional_clocks(struct omap_hwmod *oh)
956{
957 struct omap_hwmod_opt_clk *oc;
958 int i;
959
960 pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name);
961
962 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
963 if (oc->_clk) {
964 pr_debug("omap_hwmod: enable %s:%s\n", oc->role,
965 __clk_get_name(oc->_clk));
966 clk_enable(oc->_clk);
967 }
968}
969
970static void _disable_optional_clocks(struct omap_hwmod *oh)
971{
972 struct omap_hwmod_opt_clk *oc;
973 int i;
974
975 pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name);
976
977 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
978 if (oc->_clk) {
979 pr_debug("omap_hwmod: disable %s:%s\n", oc->role,
980 __clk_get_name(oc->_clk));
981 clk_disable(oc->_clk);
982 }
983}
984
985
986
987
988
989
990
991
992static int _enable_clocks(struct omap_hwmod *oh)
993{
994 struct omap_hwmod_ocp_if *os;
995
996 pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);
997
998 if (oh->flags & HWMOD_OPT_CLKS_NEEDED)
999 _enable_optional_clocks(oh);
1000
1001 if (oh->_clk)
1002 clk_enable(oh->_clk);
1003
1004 list_for_each_entry(os, &oh->slave_ports, node) {
1005 if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) {
1006 omap2_clk_deny_idle(os->_clk);
1007 clk_enable(os->_clk);
1008 }
1009 }
1010
1011
1012
1013 return 0;
1014}
1015
1016
1017
1018
1019
1020static bool _omap4_clkctrl_managed_by_clkfwk(struct omap_hwmod *oh)
1021{
1022 if (oh->prcm.omap4.flags & HWMOD_OMAP4_CLKFWK_CLKCTR_CLOCK)
1023 return true;
1024
1025 return false;
1026}
1027
1028
1029
1030
1031
1032static bool _omap4_has_clkctrl_clock(struct omap_hwmod *oh)
1033{
1034 if (oh->prcm.omap4.clkctrl_offs)
1035 return true;
1036
1037 if (!oh->prcm.omap4.clkctrl_offs &&
1038 oh->prcm.omap4.flags & HWMOD_OMAP4_ZERO_CLKCTRL_OFFSET)
1039 return true;
1040
1041 return false;
1042}
1043
1044
1045
1046
1047
1048
1049
1050static int _disable_clocks(struct omap_hwmod *oh)
1051{
1052 struct omap_hwmod_ocp_if *os;
1053
1054 pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name);
1055
1056 if (oh->_clk)
1057 clk_disable(oh->_clk);
1058
1059 list_for_each_entry(os, &oh->slave_ports, node) {
1060 if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) {
1061 clk_disable(os->_clk);
1062 omap2_clk_allow_idle(os->_clk);
1063 }
1064 }
1065
1066 if (oh->flags & HWMOD_OPT_CLKS_NEEDED)
1067 _disable_optional_clocks(oh);
1068
1069
1070
1071 return 0;
1072}
1073
1074
1075
1076
1077
1078
1079
1080
1081static void _omap4_enable_module(struct omap_hwmod *oh)
1082{
1083 if (!oh->clkdm || !oh->prcm.omap4.modulemode ||
1084 _omap4_clkctrl_managed_by_clkfwk(oh))
1085 return;
1086
1087 pr_debug("omap_hwmod: %s: %s: %d\n",
1088 oh->name, __func__, oh->prcm.omap4.modulemode);
1089
1090 omap_cm_module_enable(oh->prcm.omap4.modulemode,
1091 oh->clkdm->prcm_partition,
1092 oh->clkdm->cm_inst, oh->prcm.omap4.clkctrl_offs);
1093}
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104static int _omap4_wait_target_disable(struct omap_hwmod *oh)
1105{
1106 if (!oh)
1107 return -EINVAL;
1108
1109 if (oh->_int_flags & _HWMOD_NO_MPU_PORT || !oh->clkdm)
1110 return 0;
1111
1112 if (oh->flags & HWMOD_NO_IDLEST)
1113 return 0;
1114
1115 if (_omap4_clkctrl_managed_by_clkfwk(oh))
1116 return 0;
1117
1118 if (!_omap4_has_clkctrl_clock(oh))
1119 return 0;
1120
1121 return omap_cm_wait_module_idle(oh->clkdm->prcm_partition,
1122 oh->clkdm->cm_inst,
1123 oh->prcm.omap4.clkctrl_offs, 0);
1124}
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135static void __init _save_mpu_port_index(struct omap_hwmod *oh)
1136{
1137 struct omap_hwmod_ocp_if *os = NULL;
1138
1139 if (!oh)
1140 return;
1141
1142 oh->_int_flags |= _HWMOD_NO_MPU_PORT;
1143
1144 list_for_each_entry(os, &oh->slave_ports, node) {
1145 if (os->user & OCP_USER_MPU) {
1146 oh->_mpu_port = os;
1147 oh->_int_flags &= ~_HWMOD_NO_MPU_PORT;
1148 break;
1149 }
1150 }
1151
1152 return;
1153}
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168static struct omap_hwmod_ocp_if *_find_mpu_rt_port(struct omap_hwmod *oh)
1169{
1170 if (!oh || oh->_int_flags & _HWMOD_NO_MPU_PORT || oh->slaves_cnt == 0)
1171 return NULL;
1172
1173 return oh->_mpu_port;
1174};
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187static void _enable_sysc(struct omap_hwmod *oh)
1188{
1189 u8 idlemode, sf;
1190 u32 v;
1191 bool clkdm_act;
1192 struct clockdomain *clkdm;
1193
1194 if (!oh->class->sysc)
1195 return;
1196
1197
1198
1199
1200
1201
1202
1203 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1204 _enable_optional_clocks(oh);
1205 _wait_softreset_complete(oh);
1206 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1207 _disable_optional_clocks(oh);
1208
1209 v = oh->_sysc_cache;
1210 sf = oh->class->sysc->sysc_flags;
1211
1212 clkdm = _get_clkdm(oh);
1213 if (sf & SYSC_HAS_SIDLEMODE) {
1214 if (oh->flags & HWMOD_SWSUP_SIDLE ||
1215 oh->flags & HWMOD_SWSUP_SIDLE_ACT) {
1216 idlemode = HWMOD_IDLEMODE_NO;
1217 } else {
1218 if (sf & SYSC_HAS_ENAWAKEUP)
1219 _enable_wakeup(oh, &v);
1220 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
1221 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1222 else
1223 idlemode = HWMOD_IDLEMODE_SMART;
1224 }
1225
1226
1227
1228
1229
1230 clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);
1231 if (clkdm_act && !(oh->class->sysc->idlemodes &
1232 (SIDLE_SMART | SIDLE_SMART_WKUP)))
1233 idlemode = HWMOD_IDLEMODE_FORCE;
1234
1235 _set_slave_idlemode(oh, idlemode, &v);
1236 }
1237
1238 if (sf & SYSC_HAS_MIDLEMODE) {
1239 if (oh->flags & HWMOD_FORCE_MSTANDBY) {
1240 idlemode = HWMOD_IDLEMODE_FORCE;
1241 } else if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
1242 idlemode = HWMOD_IDLEMODE_NO;
1243 } else {
1244 if (sf & SYSC_HAS_ENAWAKEUP)
1245 _enable_wakeup(oh, &v);
1246 if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
1247 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1248 else
1249 idlemode = HWMOD_IDLEMODE_SMART;
1250 }
1251 _set_master_standbymode(oh, idlemode, &v);
1252 }
1253
1254
1255
1256
1257
1258
1259 if ((oh->flags & HWMOD_SET_DEFAULT_CLOCKACT) &&
1260 (sf & SYSC_HAS_CLOCKACTIVITY))
1261 _set_clockactivity(oh, CLOCKACT_TEST_ICLK, &v);
1262
1263 _write_sysconfig(v, oh);
1264
1265
1266
1267
1268
1269 if (sf & SYSC_HAS_AUTOIDLE) {
1270 idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
1271 0 : 1;
1272 _set_module_autoidle(oh, idlemode, &v);
1273 _write_sysconfig(v, oh);
1274 }
1275}
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286static void _idle_sysc(struct omap_hwmod *oh)
1287{
1288 u8 idlemode, sf;
1289 u32 v;
1290
1291 if (!oh->class->sysc)
1292 return;
1293
1294 v = oh->_sysc_cache;
1295 sf = oh->class->sysc->sysc_flags;
1296
1297 if (sf & SYSC_HAS_SIDLEMODE) {
1298 if (oh->flags & HWMOD_SWSUP_SIDLE) {
1299 idlemode = HWMOD_IDLEMODE_FORCE;
1300 } else {
1301 if (sf & SYSC_HAS_ENAWAKEUP)
1302 _enable_wakeup(oh, &v);
1303 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
1304 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1305 else
1306 idlemode = HWMOD_IDLEMODE_SMART;
1307 }
1308 _set_slave_idlemode(oh, idlemode, &v);
1309 }
1310
1311 if (sf & SYSC_HAS_MIDLEMODE) {
1312 if ((oh->flags & HWMOD_SWSUP_MSTANDBY) ||
1313 (oh->flags & HWMOD_FORCE_MSTANDBY)) {
1314 idlemode = HWMOD_IDLEMODE_FORCE;
1315 } else {
1316 if (sf & SYSC_HAS_ENAWAKEUP)
1317 _enable_wakeup(oh, &v);
1318 if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
1319 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1320 else
1321 idlemode = HWMOD_IDLEMODE_SMART;
1322 }
1323 _set_master_standbymode(oh, idlemode, &v);
1324 }
1325
1326
1327 if (oh->_sysc_cache != v)
1328 _write_sysconfig(v, oh);
1329}
1330
1331
1332
1333
1334
1335
1336
1337
1338static void _shutdown_sysc(struct omap_hwmod *oh)
1339{
1340 u32 v;
1341 u8 sf;
1342
1343 if (!oh->class->sysc)
1344 return;
1345
1346 v = oh->_sysc_cache;
1347 sf = oh->class->sysc->sysc_flags;
1348
1349 if (sf & SYSC_HAS_SIDLEMODE)
1350 _set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v);
1351
1352 if (sf & SYSC_HAS_MIDLEMODE)
1353 _set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
1354
1355 if (sf & SYSC_HAS_AUTOIDLE)
1356 _set_module_autoidle(oh, 1, &v);
1357
1358 _write_sysconfig(v, oh);
1359}
1360
1361
1362
1363
1364
1365
1366
1367static struct omap_hwmod *_lookup(const char *name)
1368{
1369 struct omap_hwmod *oh, *temp_oh;
1370
1371 oh = NULL;
1372
1373 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
1374 if (!strcmp(name, temp_oh->name)) {
1375 oh = temp_oh;
1376 break;
1377 }
1378 }
1379
1380 return oh;
1381}
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391static int _init_clkdm(struct omap_hwmod *oh)
1392{
1393 if (!oh->clkdm_name) {
1394 pr_debug("omap_hwmod: %s: missing clockdomain\n", oh->name);
1395 return 0;
1396 }
1397
1398 oh->clkdm = clkdm_lookup(oh->clkdm_name);
1399 if (!oh->clkdm) {
1400 pr_warn("omap_hwmod: %s: could not associate to clkdm %s\n",
1401 oh->name, oh->clkdm_name);
1402 return 0;
1403 }
1404
1405 pr_debug("omap_hwmod: %s: associated to clkdm %s\n",
1406 oh->name, oh->clkdm_name);
1407
1408 return 0;
1409}
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421static int _init_clocks(struct omap_hwmod *oh, struct device_node *np)
1422{
1423 int ret = 0;
1424
1425 if (oh->_state != _HWMOD_STATE_REGISTERED)
1426 return 0;
1427
1428 pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name);
1429
1430 if (soc_ops.init_clkdm)
1431 ret |= soc_ops.init_clkdm(oh);
1432
1433 ret |= _init_main_clk(oh);
1434 ret |= _init_interface_clks(oh);
1435 ret |= _init_opt_clks(oh);
1436
1437 if (!ret)
1438 oh->_state = _HWMOD_STATE_CLKS_INITED;
1439 else
1440 pr_warn("omap_hwmod: %s: cannot _init_clocks\n", oh->name);
1441
1442 return ret;
1443}
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454static int _lookup_hardreset(struct omap_hwmod *oh, const char *name,
1455 struct omap_hwmod_rst_info *ohri)
1456{
1457 int i;
1458
1459 for (i = 0; i < oh->rst_lines_cnt; i++) {
1460 const char *rst_line = oh->rst_lines[i].name;
1461 if (!strcmp(rst_line, name)) {
1462 ohri->rst_shift = oh->rst_lines[i].rst_shift;
1463 ohri->st_shift = oh->rst_lines[i].st_shift;
1464 pr_debug("omap_hwmod: %s: %s: %s: rst %d st %d\n",
1465 oh->name, __func__, rst_line, ohri->rst_shift,
1466 ohri->st_shift);
1467
1468 return 0;
1469 }
1470 }
1471
1472 return -ENOENT;
1473}
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
1489{
1490 struct omap_hwmod_rst_info ohri;
1491 int ret = -EINVAL;
1492
1493 if (!oh)
1494 return -EINVAL;
1495
1496 if (!soc_ops.assert_hardreset)
1497 return -ENOSYS;
1498
1499 ret = _lookup_hardreset(oh, name, &ohri);
1500 if (ret < 0)
1501 return ret;
1502
1503 ret = soc_ops.assert_hardreset(oh, &ohri);
1504
1505 return ret;
1506}
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
1522{
1523 struct omap_hwmod_rst_info ohri;
1524 int ret = -EINVAL;
1525
1526 if (!oh)
1527 return -EINVAL;
1528
1529 if (!soc_ops.deassert_hardreset)
1530 return -ENOSYS;
1531
1532 ret = _lookup_hardreset(oh, name, &ohri);
1533 if (ret < 0)
1534 return ret;
1535
1536 if (oh->clkdm) {
1537
1538
1539
1540
1541
1542 clkdm_deny_idle(oh->clkdm);
1543 ret = clkdm_hwmod_enable(oh->clkdm, oh);
1544 if (ret) {
1545 WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
1546 oh->name, oh->clkdm->name, ret);
1547 return ret;
1548 }
1549 }
1550
1551 _enable_clocks(oh);
1552 if (soc_ops.enable_module)
1553 soc_ops.enable_module(oh);
1554
1555 ret = soc_ops.deassert_hardreset(oh, &ohri);
1556
1557 if (soc_ops.disable_module)
1558 soc_ops.disable_module(oh);
1559 _disable_clocks(oh);
1560
1561 if (ret == -EBUSY)
1562 pr_warn("omap_hwmod: %s: failed to hardreset\n", oh->name);
1563
1564 if (oh->clkdm) {
1565
1566
1567
1568
1569 clkdm_allow_idle(oh->clkdm);
1570
1571 clkdm_hwmod_disable(oh->clkdm, oh);
1572 }
1573
1574 return ret;
1575}
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589static int _read_hardreset(struct omap_hwmod *oh, const char *name)
1590{
1591 struct omap_hwmod_rst_info ohri;
1592 int ret = -EINVAL;
1593
1594 if (!oh)
1595 return -EINVAL;
1596
1597 if (!soc_ops.is_hardreset_asserted)
1598 return -ENOSYS;
1599
1600 ret = _lookup_hardreset(oh, name, &ohri);
1601 if (ret < 0)
1602 return ret;
1603
1604 return soc_ops.is_hardreset_asserted(oh, &ohri);
1605}
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617static bool _are_all_hardreset_lines_asserted(struct omap_hwmod *oh)
1618{
1619 int i, rst_cnt = 0;
1620
1621 if (oh->rst_lines_cnt == 0)
1622 return false;
1623
1624 for (i = 0; i < oh->rst_lines_cnt; i++)
1625 if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
1626 rst_cnt++;
1627
1628 if (oh->rst_lines_cnt == rst_cnt)
1629 return true;
1630
1631 return false;
1632}
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)
1646{
1647 int rst_cnt = 0;
1648 int i;
1649
1650 for (i = 0; i < oh->rst_lines_cnt && rst_cnt == 0; i++)
1651 if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
1652 rst_cnt++;
1653
1654 return (rst_cnt) ? true : false;
1655}
1656
1657
1658
1659
1660
1661
1662
1663
1664static int _omap4_disable_module(struct omap_hwmod *oh)
1665{
1666 int v;
1667
1668 if (!oh->clkdm || !oh->prcm.omap4.modulemode ||
1669 _omap4_clkctrl_managed_by_clkfwk(oh))
1670 return -EINVAL;
1671
1672
1673
1674
1675
1676 if (_are_any_hardreset_lines_asserted(oh))
1677 return 0;
1678
1679 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
1680
1681 omap_cm_module_disable(oh->clkdm->prcm_partition, oh->clkdm->cm_inst,
1682 oh->prcm.omap4.clkctrl_offs);
1683
1684 v = _omap4_wait_target_disable(oh);
1685 if (v)
1686 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
1687 oh->name);
1688
1689 return 0;
1690}
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708static int _ocp_softreset(struct omap_hwmod *oh)
1709{
1710 u32 v;
1711 int c = 0;
1712 int ret = 0;
1713
1714 if (!oh->class->sysc ||
1715 !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
1716 return -ENOENT;
1717
1718
1719 if (oh->_state != _HWMOD_STATE_ENABLED) {
1720 pr_warn("omap_hwmod: %s: reset can only be entered from enabled state\n",
1721 oh->name);
1722 return -EINVAL;
1723 }
1724
1725
1726 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1727 _enable_optional_clocks(oh);
1728
1729 pr_debug("omap_hwmod: %s: resetting via OCP SOFTRESET\n", oh->name);
1730
1731 v = oh->_sysc_cache;
1732 ret = _set_softreset(oh, &v);
1733 if (ret)
1734 goto dis_opt_clks;
1735
1736 _write_sysconfig(v, oh);
1737
1738 if (oh->class->sysc->srst_udelay)
1739 udelay(oh->class->sysc->srst_udelay);
1740
1741 c = _wait_softreset_complete(oh);
1742 if (c == MAX_MODULE_SOFTRESET_WAIT) {
1743 pr_warn("omap_hwmod: %s: softreset failed (waited %d usec)\n",
1744 oh->name, MAX_MODULE_SOFTRESET_WAIT);
1745 ret = -ETIMEDOUT;
1746 goto dis_opt_clks;
1747 } else {
1748 pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c);
1749 }
1750
1751 ret = _clear_softreset(oh, &v);
1752 if (ret)
1753 goto dis_opt_clks;
1754
1755 _write_sysconfig(v, oh);
1756
1757
1758
1759
1760
1761
1762dis_opt_clks:
1763 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1764 _disable_optional_clocks(oh);
1765
1766 return ret;
1767}
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802static int _reset(struct omap_hwmod *oh)
1803{
1804 int i, r;
1805
1806 pr_debug("omap_hwmod: %s: resetting\n", oh->name);
1807
1808 if (oh->class->reset) {
1809 r = oh->class->reset(oh);
1810 } else {
1811 if (oh->rst_lines_cnt > 0) {
1812 for (i = 0; i < oh->rst_lines_cnt; i++)
1813 _assert_hardreset(oh, oh->rst_lines[i].name);
1814 return 0;
1815 } else {
1816 r = _ocp_softreset(oh);
1817 if (r == -ENOENT)
1818 r = 0;
1819 }
1820 }
1821
1822 _set_dmadisable(oh);
1823
1824
1825
1826
1827
1828
1829 if (oh->class->sysc) {
1830 _update_sysc_cache(oh);
1831 _enable_sysc(oh);
1832 }
1833
1834 return r;
1835}
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846static void _omap4_update_context_lost(struct omap_hwmod *oh)
1847{
1848 if (oh->prcm.omap4.flags & HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT)
1849 return;
1850
1851 if (!prm_was_any_context_lost_old(oh->clkdm->pwrdm.ptr->prcm_partition,
1852 oh->clkdm->pwrdm.ptr->prcm_offs,
1853 oh->prcm.omap4.context_offs))
1854 return;
1855
1856 oh->prcm.omap4.context_lost_counter++;
1857 prm_clear_context_loss_flags_old(oh->clkdm->pwrdm.ptr->prcm_partition,
1858 oh->clkdm->pwrdm.ptr->prcm_offs,
1859 oh->prcm.omap4.context_offs);
1860}
1861
1862
1863
1864
1865
1866
1867
1868static int _omap4_get_context_lost(struct omap_hwmod *oh)
1869{
1870 return oh->prcm.omap4.context_lost_counter;
1871}
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882static int _enable_preprogram(struct omap_hwmod *oh)
1883{
1884 if (!oh->class->enable_preprogram)
1885 return 0;
1886
1887 return oh->class->enable_preprogram(oh);
1888}
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898static int _enable(struct omap_hwmod *oh)
1899{
1900 int r;
1901
1902 pr_debug("omap_hwmod: %s: enabling\n", oh->name);
1903
1904
1905
1906
1907
1908 if (oh->_int_flags & _HWMOD_SKIP_ENABLE) {
1909 oh->_int_flags &= ~_HWMOD_SKIP_ENABLE;
1910 return 0;
1911 }
1912
1913 if (oh->_state != _HWMOD_STATE_INITIALIZED &&
1914 oh->_state != _HWMOD_STATE_IDLE &&
1915 oh->_state != _HWMOD_STATE_DISABLED) {
1916 WARN(1, "omap_hwmod: %s: enabled state can only be entered from initialized, idle, or disabled state\n",
1917 oh->name);
1918 return -EINVAL;
1919 }
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930 if (_are_all_hardreset_lines_asserted(oh))
1931 return 0;
1932
1933 _add_initiator_dep(oh, mpu_oh);
1934
1935 if (oh->clkdm) {
1936
1937
1938
1939
1940
1941 clkdm_deny_idle(oh->clkdm);
1942 r = clkdm_hwmod_enable(oh->clkdm, oh);
1943 if (r) {
1944 WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
1945 oh->name, oh->clkdm->name, r);
1946 return r;
1947 }
1948 }
1949
1950 _enable_clocks(oh);
1951 if (soc_ops.enable_module)
1952 soc_ops.enable_module(oh);
1953 if (oh->flags & HWMOD_BLOCK_WFI)
1954 cpu_idle_poll_ctrl(true);
1955
1956 if (soc_ops.update_context_lost)
1957 soc_ops.update_context_lost(oh);
1958
1959 r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
1960 -EINVAL;
1961 if (oh->clkdm && !(oh->flags & HWMOD_CLKDM_NOAUTO))
1962 clkdm_allow_idle(oh->clkdm);
1963
1964 if (!r) {
1965 oh->_state = _HWMOD_STATE_ENABLED;
1966
1967
1968 if (oh->class->sysc) {
1969 if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
1970 _update_sysc_cache(oh);
1971 _enable_sysc(oh);
1972 }
1973 r = _enable_preprogram(oh);
1974 } else {
1975 if (soc_ops.disable_module)
1976 soc_ops.disable_module(oh);
1977 _disable_clocks(oh);
1978 pr_err("omap_hwmod: %s: _wait_target_ready failed: %d\n",
1979 oh->name, r);
1980
1981 if (oh->clkdm)
1982 clkdm_hwmod_disable(oh->clkdm, oh);
1983 }
1984
1985 return r;
1986}
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996static int _idle(struct omap_hwmod *oh)
1997{
1998 if (oh->flags & HWMOD_NO_IDLE) {
1999 oh->_int_flags |= _HWMOD_SKIP_ENABLE;
2000 return 0;
2001 }
2002
2003 pr_debug("omap_hwmod: %s: idling\n", oh->name);
2004
2005 if (_are_all_hardreset_lines_asserted(oh))
2006 return 0;
2007
2008 if (oh->_state != _HWMOD_STATE_ENABLED) {
2009 WARN(1, "omap_hwmod: %s: idle state can only be entered from enabled state\n",
2010 oh->name);
2011 return -EINVAL;
2012 }
2013
2014 if (oh->class->sysc)
2015 _idle_sysc(oh);
2016 _del_initiator_dep(oh, mpu_oh);
2017
2018
2019
2020
2021
2022
2023 if (oh->clkdm && !(oh->flags & HWMOD_CLKDM_NOAUTO))
2024 clkdm_deny_idle(oh->clkdm);
2025
2026 if (oh->flags & HWMOD_BLOCK_WFI)
2027 cpu_idle_poll_ctrl(false);
2028 if (soc_ops.disable_module)
2029 soc_ops.disable_module(oh);
2030
2031
2032
2033
2034
2035
2036
2037 _disable_clocks(oh);
2038 if (oh->clkdm) {
2039 clkdm_allow_idle(oh->clkdm);
2040 clkdm_hwmod_disable(oh->clkdm, oh);
2041 }
2042
2043 oh->_state = _HWMOD_STATE_IDLE;
2044
2045 return 0;
2046}
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057static int _shutdown(struct omap_hwmod *oh)
2058{
2059 int ret, i;
2060 u8 prev_state;
2061
2062 if (_are_all_hardreset_lines_asserted(oh))
2063 return 0;
2064
2065 if (oh->_state != _HWMOD_STATE_IDLE &&
2066 oh->_state != _HWMOD_STATE_ENABLED) {
2067 WARN(1, "omap_hwmod: %s: disabled state can only be entered from idle, or enabled state\n",
2068 oh->name);
2069 return -EINVAL;
2070 }
2071
2072 pr_debug("omap_hwmod: %s: disabling\n", oh->name);
2073
2074 if (oh->class->pre_shutdown) {
2075 prev_state = oh->_state;
2076 if (oh->_state == _HWMOD_STATE_IDLE)
2077 _enable(oh);
2078 ret = oh->class->pre_shutdown(oh);
2079 if (ret) {
2080 if (prev_state == _HWMOD_STATE_IDLE)
2081 _idle(oh);
2082 return ret;
2083 }
2084 }
2085
2086 if (oh->class->sysc) {
2087 if (oh->_state == _HWMOD_STATE_IDLE)
2088 _enable(oh);
2089 _shutdown_sysc(oh);
2090 }
2091
2092
2093 if (oh->_state == _HWMOD_STATE_ENABLED) {
2094 _del_initiator_dep(oh, mpu_oh);
2095
2096 if (oh->flags & HWMOD_BLOCK_WFI)
2097 cpu_idle_poll_ctrl(false);
2098 if (soc_ops.disable_module)
2099 soc_ops.disable_module(oh);
2100 _disable_clocks(oh);
2101 if (oh->clkdm)
2102 clkdm_hwmod_disable(oh->clkdm, oh);
2103 }
2104
2105
2106 for (i = 0; i < oh->rst_lines_cnt; i++)
2107 _assert_hardreset(oh, oh->rst_lines[i].name);
2108
2109 oh->_state = _HWMOD_STATE_DISABLED;
2110
2111 return 0;
2112}
2113
2114static int of_dev_find_hwmod(struct device_node *np,
2115 struct omap_hwmod *oh)
2116{
2117 int count, i, res;
2118 const char *p;
2119
2120 count = of_property_count_strings(np, "ti,hwmods");
2121 if (count < 1)
2122 return -ENODEV;
2123
2124 for (i = 0; i < count; i++) {
2125 res = of_property_read_string_index(np, "ti,hwmods",
2126 i, &p);
2127 if (res)
2128 continue;
2129 if (!strcmp(p, oh->name)) {
2130 pr_debug("omap_hwmod: dt %pOFn[%i] uses hwmod %s\n",
2131 np, i, oh->name);
2132 return i;
2133 }
2134 }
2135
2136 return -ENODEV;
2137}
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150static int of_dev_hwmod_lookup(struct device_node *np,
2151 struct omap_hwmod *oh,
2152 int *index,
2153 struct device_node **found)
2154{
2155 struct device_node *np0 = NULL;
2156 int res;
2157
2158 res = of_dev_find_hwmod(np, oh);
2159 if (res >= 0) {
2160 *found = np;
2161 *index = res;
2162 return 0;
2163 }
2164
2165 for_each_child_of_node(np, np0) {
2166 struct device_node *fc;
2167 int i;
2168
2169 res = of_dev_hwmod_lookup(np0, oh, &i, &fc);
2170 if (res == 0) {
2171 *found = fc;
2172 *index = i;
2173 return 0;
2174 }
2175 }
2176
2177 *found = NULL;
2178 *index = 0;
2179
2180 return -ENODEV;
2181}
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197static void omap_hwmod_fix_mpu_rt_idx(struct omap_hwmod *oh,
2198 struct device_node *np,
2199 struct resource *res)
2200{
2201 struct device_node *child = NULL;
2202 int error;
2203
2204 child = of_get_next_child(np, child);
2205 if (!child)
2206 return;
2207
2208 error = of_address_to_resource(child, oh->mpu_rt_idx, res);
2209 if (error)
2210 pr_err("%s: error mapping mpu_rt_idx: %i\n",
2211 __func__, error);
2212}
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225int omap_hwmod_parse_module_range(struct omap_hwmod *oh,
2226 struct device_node *np,
2227 struct resource *res)
2228{
2229 struct property *prop;
2230 const __be32 *ranges;
2231 const char *name;
2232 u32 nr_addr, nr_size;
2233 u64 base, size;
2234 int len, error;
2235
2236 if (!res)
2237 return -EINVAL;
2238
2239 ranges = of_get_property(np, "ranges", &len);
2240 if (!ranges)
2241 return -ENOENT;
2242
2243 len /= sizeof(*ranges);
2244
2245 if (len < 3)
2246 return -EINVAL;
2247
2248 of_property_for_each_string(np, "compatible", prop, name)
2249 if (!strncmp("ti,sysc-", name, 8))
2250 break;
2251
2252 if (!name)
2253 return -ENOENT;
2254
2255 error = of_property_read_u32(np, "#address-cells", &nr_addr);
2256 if (error)
2257 return -ENOENT;
2258
2259 error = of_property_read_u32(np, "#size-cells", &nr_size);
2260 if (error)
2261 return -ENOENT;
2262
2263 if (nr_addr != 1 || nr_size != 1) {
2264 pr_err("%s: invalid range for %s->%pOFn\n", __func__,
2265 oh->name, np);
2266 return -EINVAL;
2267 }
2268
2269 ranges++;
2270 base = of_translate_address(np, ranges++);
2271 size = be32_to_cpup(ranges);
2272
2273 pr_debug("omap_hwmod: %s %pOFn at 0x%llx size 0x%llx\n",
2274 oh->name, np, base, size);
2275
2276 if (oh && oh->mpu_rt_idx) {
2277 omap_hwmod_fix_mpu_rt_idx(oh, np, res);
2278
2279 return 0;
2280 }
2281
2282 res->start = base;
2283 res->end = base + size - 1;
2284 res->flags = IORESOURCE_MEM;
2285
2286 return 0;
2287}
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
2307 int index, struct device_node *np)
2308{
2309 void __iomem *va_start = NULL;
2310 struct resource res;
2311 int error;
2312
2313 if (!oh)
2314 return -EINVAL;
2315
2316 _save_mpu_port_index(oh);
2317
2318
2319 if (!oh->class->sysc)
2320 return 0;
2321
2322
2323 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
2324 return -ENXIO;
2325
2326 if (!np) {
2327 pr_err("omap_hwmod: %s: no dt node\n", oh->name);
2328 return -ENXIO;
2329 }
2330
2331
2332 error = omap_hwmod_parse_module_range(oh, np, &res);
2333 if (!error)
2334 va_start = ioremap(res.start, resource_size(&res));
2335
2336
2337 if (!va_start)
2338 va_start = of_iomap(np, index + oh->mpu_rt_idx);
2339 if (!va_start) {
2340 pr_err("omap_hwmod: %s: Missing dt reg%i for %pOF\n",
2341 oh->name, index, np);
2342 return -ENXIO;
2343 }
2344
2345 pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
2346 oh->name, va_start);
2347
2348 oh->_mpu_rt_va = va_start;
2349 return 0;
2350}
2351
2352static void __init parse_module_flags(struct omap_hwmod *oh,
2353 struct device_node *np)
2354{
2355 if (of_find_property(np, "ti,no-reset-on-init", NULL))
2356 oh->flags |= HWMOD_INIT_NO_RESET;
2357 if (of_find_property(np, "ti,no-idle-on-init", NULL))
2358 oh->flags |= HWMOD_INIT_NO_IDLE;
2359 if (of_find_property(np, "ti,no-idle", NULL))
2360 oh->flags |= HWMOD_NO_IDLE;
2361}
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376static int __init _init(struct omap_hwmod *oh, void *data)
2377{
2378 int r, index;
2379 struct device_node *np = NULL;
2380 struct device_node *bus;
2381
2382 if (oh->_state != _HWMOD_STATE_REGISTERED)
2383 return 0;
2384
2385 bus = of_find_node_by_name(NULL, "ocp");
2386 if (!bus)
2387 return -ENODEV;
2388
2389 r = of_dev_hwmod_lookup(bus, oh, &index, &np);
2390 if (r)
2391 pr_debug("omap_hwmod: %s missing dt data\n", oh->name);
2392 else if (np && index)
2393 pr_warn("omap_hwmod: %s using broken dt data from %pOFn\n",
2394 oh->name, np);
2395
2396 r = _init_mpu_rt_base(oh, NULL, index, np);
2397 if (r < 0) {
2398 WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
2399 oh->name);
2400 return 0;
2401 }
2402
2403 r = _init_clocks(oh, np);
2404 if (r < 0) {
2405 WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name);
2406 return -EINVAL;
2407 }
2408
2409 if (np) {
2410 struct device_node *child;
2411
2412 parse_module_flags(oh, np);
2413 child = of_get_next_child(np, NULL);
2414 if (child)
2415 parse_module_flags(oh, child);
2416 }
2417
2418 oh->_state = _HWMOD_STATE_INITIALIZED;
2419
2420 return 0;
2421}
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431static void _setup_iclk_autoidle(struct omap_hwmod *oh)
2432{
2433 struct omap_hwmod_ocp_if *os;
2434
2435 if (oh->_state != _HWMOD_STATE_INITIALIZED)
2436 return;
2437
2438 list_for_each_entry(os, &oh->slave_ports, node) {
2439 if (!os->_clk)
2440 continue;
2441
2442 if (os->flags & OCPIF_SWSUP_IDLE) {
2443
2444
2445
2446
2447
2448 } else {
2449
2450 clk_enable(os->_clk);
2451 }
2452 }
2453
2454 return;
2455}
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466static int _setup_reset(struct omap_hwmod *oh)
2467{
2468 int r;
2469
2470 if (oh->_state != _HWMOD_STATE_INITIALIZED)
2471 return -EINVAL;
2472
2473 if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK)
2474 return -EPERM;
2475
2476 if (oh->rst_lines_cnt == 0) {
2477 r = _enable(oh);
2478 if (r) {
2479 pr_warn("omap_hwmod: %s: cannot be enabled for reset (%d)\n",
2480 oh->name, oh->_state);
2481 return -EINVAL;
2482 }
2483 }
2484
2485 if (!(oh->flags & HWMOD_INIT_NO_RESET))
2486 r = _reset(oh);
2487
2488 return r;
2489}
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527static void _setup_postsetup(struct omap_hwmod *oh)
2528{
2529 u8 postsetup_state;
2530
2531 if (oh->rst_lines_cnt > 0)
2532 return;
2533
2534 postsetup_state = oh->_postsetup_state;
2535 if (postsetup_state == _HWMOD_STATE_UNKNOWN)
2536 postsetup_state = _HWMOD_STATE_ENABLED;
2537
2538
2539
2540
2541
2542 if ((oh->flags & (HWMOD_INIT_NO_IDLE | HWMOD_NO_IDLE)) &&
2543 (postsetup_state == _HWMOD_STATE_IDLE)) {
2544 oh->_int_flags |= _HWMOD_SKIP_ENABLE;
2545 postsetup_state = _HWMOD_STATE_ENABLED;
2546 }
2547
2548 if (postsetup_state == _HWMOD_STATE_IDLE)
2549 _idle(oh);
2550 else if (postsetup_state == _HWMOD_STATE_DISABLED)
2551 _shutdown(oh);
2552 else if (postsetup_state != _HWMOD_STATE_ENABLED)
2553 WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
2554 oh->name, postsetup_state);
2555
2556 return;
2557}
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575static int _setup(struct omap_hwmod *oh, void *data)
2576{
2577 if (oh->_state != _HWMOD_STATE_INITIALIZED)
2578 return 0;
2579
2580 if (oh->parent_hwmod) {
2581 int r;
2582
2583 r = _enable(oh->parent_hwmod);
2584 WARN(r, "hwmod: %s: setup: failed to enable parent hwmod %s\n",
2585 oh->name, oh->parent_hwmod->name);
2586 }
2587
2588 _setup_iclk_autoidle(oh);
2589
2590 if (!_setup_reset(oh))
2591 _setup_postsetup(oh);
2592
2593 if (oh->parent_hwmod) {
2594 u8 postsetup_state;
2595
2596 postsetup_state = oh->parent_hwmod->_postsetup_state;
2597
2598 if (postsetup_state == _HWMOD_STATE_IDLE)
2599 _idle(oh->parent_hwmod);
2600 else if (postsetup_state == _HWMOD_STATE_DISABLED)
2601 _shutdown(oh->parent_hwmod);
2602 else if (postsetup_state != _HWMOD_STATE_ENABLED)
2603 WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
2604 oh->parent_hwmod->name, postsetup_state);
2605 }
2606
2607 return 0;
2608}
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627static int __init _register(struct omap_hwmod *oh)
2628{
2629 if (!oh || !oh->name || !oh->class || !oh->class->name ||
2630 (oh->_state != _HWMOD_STATE_UNKNOWN))
2631 return -EINVAL;
2632
2633 pr_debug("omap_hwmod: %s: registering\n", oh->name);
2634
2635 if (_lookup(oh->name))
2636 return -EEXIST;
2637
2638 list_add_tail(&oh->node, &omap_hwmod_list);
2639
2640 INIT_LIST_HEAD(&oh->slave_ports);
2641 spin_lock_init(&oh->_lock);
2642 lockdep_set_class(&oh->_lock, &oh->hwmod_key);
2643
2644 oh->_state = _HWMOD_STATE_REGISTERED;
2645
2646
2647
2648
2649
2650 if (!strcmp(oh->name, MPU_INITIATOR_NAME))
2651 mpu_oh = oh;
2652
2653 return 0;
2654}
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666static int __init _add_link(struct omap_hwmod_ocp_if *oi)
2667{
2668 pr_debug("omap_hwmod: %s -> %s: adding link\n", oi->master->name,
2669 oi->slave->name);
2670
2671 list_add(&oi->node, &oi->slave->slave_ports);
2672 oi->slave->slaves_cnt++;
2673
2674 return 0;
2675}
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690static int __init _register_link(struct omap_hwmod_ocp_if *oi)
2691{
2692 if (!oi || !oi->master || !oi->slave || !oi->user)
2693 return -EINVAL;
2694
2695 if (oi->_int_flags & _OCPIF_INT_FLAGS_REGISTERED)
2696 return -EEXIST;
2697
2698 pr_debug("omap_hwmod: registering link from %s to %s\n",
2699 oi->master->name, oi->slave->name);
2700
2701
2702
2703
2704
2705 if (oi->master->_state != _HWMOD_STATE_REGISTERED)
2706 _register(oi->master);
2707
2708 if (oi->slave->_state != _HWMOD_STATE_REGISTERED)
2709 _register(oi->slave);
2710
2711 _add_link(oi);
2712
2713 oi->_int_flags |= _OCPIF_INT_FLAGS_REGISTERED;
2714
2715 return 0;
2716}
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729static int _omap2xxx_3xxx_wait_target_ready(struct omap_hwmod *oh)
2730{
2731 if (!oh)
2732 return -EINVAL;
2733
2734 if (oh->flags & HWMOD_NO_IDLEST)
2735 return 0;
2736
2737 if (!_find_mpu_rt_port(oh))
2738 return 0;
2739
2740
2741
2742 return omap_cm_wait_module_ready(0, oh->prcm.omap2.module_offs,
2743 oh->prcm.omap2.idlest_reg_id,
2744 oh->prcm.omap2.idlest_idle_bit);
2745}
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756static int _omap4_wait_target_ready(struct omap_hwmod *oh)
2757{
2758 if (!oh)
2759 return -EINVAL;
2760
2761 if (oh->flags & HWMOD_NO_IDLEST || !oh->clkdm)
2762 return 0;
2763
2764 if (!_find_mpu_rt_port(oh))
2765 return 0;
2766
2767 if (_omap4_clkctrl_managed_by_clkfwk(oh))
2768 return 0;
2769
2770 if (!_omap4_has_clkctrl_clock(oh))
2771 return 0;
2772
2773
2774
2775 return omap_cm_wait_module_ready(oh->clkdm->prcm_partition,
2776 oh->clkdm->cm_inst,
2777 oh->prcm.omap4.clkctrl_offs, 0);
2778}
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791static int _omap2_assert_hardreset(struct omap_hwmod *oh,
2792 struct omap_hwmod_rst_info *ohri)
2793{
2794 return omap_prm_assert_hardreset(ohri->rst_shift, 0,
2795 oh->prcm.omap2.module_offs, 0);
2796}
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809static int _omap2_deassert_hardreset(struct omap_hwmod *oh,
2810 struct omap_hwmod_rst_info *ohri)
2811{
2812 return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0,
2813 oh->prcm.omap2.module_offs, 0, 0);
2814}
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh,
2829 struct omap_hwmod_rst_info *ohri)
2830{
2831 return omap_prm_is_hardreset_asserted(ohri->st_shift, 0,
2832 oh->prcm.omap2.module_offs, 0);
2833}
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847static int _omap4_assert_hardreset(struct omap_hwmod *oh,
2848 struct omap_hwmod_rst_info *ohri)
2849{
2850 if (!oh->clkdm)
2851 return -EINVAL;
2852
2853 return omap_prm_assert_hardreset(ohri->rst_shift,
2854 oh->clkdm->pwrdm.ptr->prcm_partition,
2855 oh->clkdm->pwrdm.ptr->prcm_offs,
2856 oh->prcm.omap4.rstctrl_offs);
2857}
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871static int _omap4_deassert_hardreset(struct omap_hwmod *oh,
2872 struct omap_hwmod_rst_info *ohri)
2873{
2874 if (!oh->clkdm)
2875 return -EINVAL;
2876
2877 if (ohri->st_shift)
2878 pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
2879 oh->name, ohri->name);
2880 return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->rst_shift,
2881 oh->clkdm->pwrdm.ptr->prcm_partition,
2882 oh->clkdm->pwrdm.ptr->prcm_offs,
2883 oh->prcm.omap4.rstctrl_offs,
2884 oh->prcm.omap4.rstctrl_offs +
2885 OMAP4_RST_CTRL_ST_OFFSET);
2886}
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
2901 struct omap_hwmod_rst_info *ohri)
2902{
2903 if (!oh->clkdm)
2904 return -EINVAL;
2905
2906 return omap_prm_is_hardreset_asserted(ohri->rst_shift,
2907 oh->clkdm->pwrdm.ptr->
2908 prcm_partition,
2909 oh->clkdm->pwrdm.ptr->prcm_offs,
2910 oh->prcm.omap4.rstctrl_offs);
2911}
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921static int _omap4_disable_direct_prcm(struct omap_hwmod *oh)
2922{
2923 if (!oh)
2924 return -EINVAL;
2925
2926 oh->prcm.omap4.flags |= HWMOD_OMAP4_CLKFWK_CLKCTR_CLOCK;
2927
2928 return 0;
2929}
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
2944 struct omap_hwmod_rst_info *ohri)
2945{
2946 return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift,
2947 oh->clkdm->pwrdm.ptr->prcm_partition,
2948 oh->clkdm->pwrdm.ptr->prcm_offs,
2949 oh->prcm.omap4.rstctrl_offs,
2950 oh->prcm.omap4.rstst_offs);
2951}
2952
2953
2954
2955u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
2956{
2957 if (oh->flags & HWMOD_16BIT_REG)
2958 return readw_relaxed(oh->_mpu_rt_va + reg_offs);
2959 else
2960 return readl_relaxed(oh->_mpu_rt_va + reg_offs);
2961}
2962
2963void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs)
2964{
2965 if (oh->flags & HWMOD_16BIT_REG)
2966 writew_relaxed(v, oh->_mpu_rt_va + reg_offs);
2967 else
2968 writel_relaxed(v, oh->_mpu_rt_va + reg_offs);
2969}
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980int omap_hwmod_softreset(struct omap_hwmod *oh)
2981{
2982 u32 v;
2983 int ret;
2984
2985 if (!oh || !(oh->_sysc_cache))
2986 return -EINVAL;
2987
2988 v = oh->_sysc_cache;
2989 ret = _set_softreset(oh, &v);
2990 if (ret)
2991 goto error;
2992 _write_sysconfig(v, oh);
2993
2994 ret = _clear_softreset(oh, &v);
2995 if (ret)
2996 goto error;
2997 _write_sysconfig(v, oh);
2998
2999error:
3000 return ret;
3001}
3002
3003
3004
3005
3006
3007
3008
3009
3010struct omap_hwmod *omap_hwmod_lookup(const char *name)
3011{
3012 struct omap_hwmod *oh;
3013
3014 if (!name)
3015 return NULL;
3016
3017 oh = _lookup(name);
3018
3019 return oh;
3020}
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
3035 void *data)
3036{
3037 struct omap_hwmod *temp_oh;
3038 int ret = 0;
3039
3040 if (!fn)
3041 return -EINVAL;
3042
3043 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
3044 ret = (*fn)(temp_oh, data);
3045 if (ret)
3046 break;
3047 }
3048
3049 return ret;
3050}
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois)
3064{
3065 int r, i;
3066
3067 if (!inited)
3068 return -EINVAL;
3069
3070 if (!ois)
3071 return 0;
3072
3073 if (ois[0] == NULL)
3074 return 0;
3075
3076 i = 0;
3077 do {
3078 r = _register_link(ois[i]);
3079 WARN(r && r != -EEXIST,
3080 "omap_hwmod: _register_link(%s -> %s) returned %d\n",
3081 ois[i]->master->name, ois[i]->slave->name, r);
3082 } while (ois[++i]);
3083
3084 return 0;
3085}
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097static void __init _ensure_mpu_hwmod_is_setup(struct omap_hwmod *oh)
3098{
3099 if (!mpu_oh || mpu_oh->_state == _HWMOD_STATE_UNKNOWN)
3100 pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n",
3101 __func__, MPU_INITIATOR_NAME);
3102 else if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh)
3103 omap_hwmod_setup_one(MPU_INITIATOR_NAME);
3104}
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117int __init omap_hwmod_setup_one(const char *oh_name)
3118{
3119 struct omap_hwmod *oh;
3120
3121 pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__);
3122
3123 oh = _lookup(oh_name);
3124 if (!oh) {
3125 WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name);
3126 return -EINVAL;
3127 }
3128
3129 _ensure_mpu_hwmod_is_setup(oh);
3130
3131 _init(oh, NULL);
3132 _setup(oh, NULL);
3133
3134 return 0;
3135}
3136
3137static void omap_hwmod_check_one(struct device *dev,
3138 const char *name, s8 v1, u8 v2)
3139{
3140 if (v1 < 0)
3141 return;
3142
3143 if (v1 != v2)
3144 dev_warn(dev, "%s %d != %d\n", name, v1, v2);
3145}
3146
3147
3148
3149
3150
3151
3152
3153static int omap_hwmod_check_sysc(struct device *dev,
3154 const struct ti_sysc_module_data *data,
3155 struct sysc_regbits *sysc_fields)
3156{
3157 const struct sysc_regbits *regbits = data->cap->regbits;
3158
3159 omap_hwmod_check_one(dev, "dmadisable_shift",
3160 regbits->dmadisable_shift,
3161 sysc_fields->dmadisable_shift);
3162 omap_hwmod_check_one(dev, "midle_shift",
3163 regbits->midle_shift,
3164 sysc_fields->midle_shift);
3165 omap_hwmod_check_one(dev, "sidle_shift",
3166 regbits->sidle_shift,
3167 sysc_fields->sidle_shift);
3168 omap_hwmod_check_one(dev, "clkact_shift",
3169 regbits->clkact_shift,
3170 sysc_fields->clkact_shift);
3171 omap_hwmod_check_one(dev, "enwkup_shift",
3172 regbits->enwkup_shift,
3173 sysc_fields->enwkup_shift);
3174 omap_hwmod_check_one(dev, "srst_shift",
3175 regbits->srst_shift,
3176 sysc_fields->srst_shift);
3177 omap_hwmod_check_one(dev, "autoidle_shift",
3178 regbits->autoidle_shift,
3179 sysc_fields->autoidle_shift);
3180
3181 return 0;
3182}
3183
3184
3185
3186
3187
3188
3189
3190static int omap_hwmod_init_regbits(struct device *dev,
3191 const struct ti_sysc_module_data *data,
3192 struct sysc_regbits **sysc_fields)
3193{
3194 *sysc_fields = NULL;
3195
3196 switch (data->cap->type) {
3197 case TI_SYSC_OMAP2:
3198 case TI_SYSC_OMAP2_TIMER:
3199 *sysc_fields = &omap_hwmod_sysc_type1;
3200 break;
3201 case TI_SYSC_OMAP3_SHAM:
3202 *sysc_fields = &omap3_sham_sysc_fields;
3203 break;
3204 case TI_SYSC_OMAP3_AES:
3205 *sysc_fields = &omap3xxx_aes_sysc_fields;
3206 break;
3207 case TI_SYSC_OMAP4:
3208 case TI_SYSC_OMAP4_TIMER:
3209 *sysc_fields = &omap_hwmod_sysc_type2;
3210 break;
3211 case TI_SYSC_OMAP4_SIMPLE:
3212 *sysc_fields = &omap_hwmod_sysc_type3;
3213 break;
3214 case TI_SYSC_OMAP34XX_SR:
3215 *sysc_fields = &omap34xx_sr_sysc_fields;
3216 break;
3217 case TI_SYSC_OMAP36XX_SR:
3218 *sysc_fields = &omap36xx_sr_sysc_fields;
3219 break;
3220 case TI_SYSC_OMAP4_SR:
3221 *sysc_fields = &omap36xx_sr_sysc_fields;
3222 break;
3223 case TI_SYSC_OMAP4_MCASP:
3224 *sysc_fields = &omap_hwmod_sysc_type_mcasp;
3225 break;
3226 case TI_SYSC_OMAP4_USB_HOST_FS:
3227 *sysc_fields = &omap_hwmod_sysc_type_usb_host_fs;
3228 break;
3229 default:
3230 return -EINVAL;
3231 }
3232
3233 return omap_hwmod_check_sysc(dev, data, *sysc_fields);
3234}
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244int omap_hwmod_init_reg_offs(struct device *dev,
3245 const struct ti_sysc_module_data *data,
3246 s32 *rev_offs, s32 *sysc_offs, s32 *syss_offs)
3247{
3248 *rev_offs = -ENODEV;
3249 *sysc_offs = 0;
3250 *syss_offs = 0;
3251
3252 if (data->offsets[SYSC_REVISION] >= 0)
3253 *rev_offs = data->offsets[SYSC_REVISION];
3254
3255 if (data->offsets[SYSC_SYSCONFIG] >= 0)
3256 *sysc_offs = data->offsets[SYSC_SYSCONFIG];
3257
3258 if (data->offsets[SYSC_SYSSTATUS] >= 0)
3259 *syss_offs = data->offsets[SYSC_SYSSTATUS];
3260
3261 return 0;
3262}
3263
3264
3265
3266
3267
3268
3269
3270int omap_hwmod_init_sysc_flags(struct device *dev,
3271 const struct ti_sysc_module_data *data,
3272 u32 *sysc_flags)
3273{
3274 *sysc_flags = 0;
3275
3276 switch (data->cap->type) {
3277 case TI_SYSC_OMAP2:
3278 case TI_SYSC_OMAP2_TIMER:
3279
3280 if (data->cfg->sysc_val & SYSC_OMAP2_CLOCKACTIVITY)
3281 *sysc_flags |= SYSC_HAS_CLOCKACTIVITY;
3282 if (data->cfg->sysc_val & SYSC_OMAP2_EMUFREE)
3283 *sysc_flags |= SYSC_HAS_EMUFREE;
3284 if (data->cfg->sysc_val & SYSC_OMAP2_ENAWAKEUP)
3285 *sysc_flags |= SYSC_HAS_ENAWAKEUP;
3286 if (data->cfg->sysc_val & SYSC_OMAP2_SOFTRESET)
3287 *sysc_flags |= SYSC_HAS_SOFTRESET;
3288 if (data->cfg->sysc_val & SYSC_OMAP2_AUTOIDLE)
3289 *sysc_flags |= SYSC_HAS_AUTOIDLE;
3290 break;
3291 case TI_SYSC_OMAP4:
3292 case TI_SYSC_OMAP4_TIMER:
3293
3294 if (data->cfg->sysc_val & SYSC_OMAP4_DMADISABLE)
3295 *sysc_flags |= SYSC_HAS_DMADISABLE;
3296 if (data->cfg->sysc_val & SYSC_OMAP4_FREEEMU)
3297 *sysc_flags |= SYSC_HAS_EMUFREE;
3298 if (data->cfg->sysc_val & SYSC_OMAP4_SOFTRESET)
3299 *sysc_flags |= SYSC_HAS_SOFTRESET;
3300 break;
3301 case TI_SYSC_OMAP34XX_SR:
3302 case TI_SYSC_OMAP36XX_SR:
3303
3304 if (data->cfg->sysc_val & SYSC_OMAP3_SR_ENAWAKEUP)
3305 *sysc_flags |= SYSC_HAS_ENAWAKEUP;
3306 break;
3307 default:
3308 if (data->cap->regbits->emufree_shift >= 0)
3309 *sysc_flags |= SYSC_HAS_EMUFREE;
3310 if (data->cap->regbits->enwkup_shift >= 0)
3311 *sysc_flags |= SYSC_HAS_ENAWAKEUP;
3312 if (data->cap->regbits->srst_shift >= 0)
3313 *sysc_flags |= SYSC_HAS_SOFTRESET;
3314 if (data->cap->regbits->autoidle_shift >= 0)
3315 *sysc_flags |= SYSC_HAS_AUTOIDLE;
3316 break;
3317 }
3318
3319 if (data->cap->regbits->midle_shift >= 0 &&
3320 data->cfg->midlemodes)
3321 *sysc_flags |= SYSC_HAS_MIDLEMODE;
3322
3323 if (data->cap->regbits->sidle_shift >= 0 &&
3324 data->cfg->sidlemodes)
3325 *sysc_flags |= SYSC_HAS_SIDLEMODE;
3326
3327 if (data->cfg->quirks & SYSC_QUIRK_UNCACHED)
3328 *sysc_flags |= SYSC_NO_CACHE;
3329 if (data->cfg->quirks & SYSC_QUIRK_RESET_STATUS)
3330 *sysc_flags |= SYSC_HAS_RESET_STATUS;
3331
3332 if (data->cfg->syss_mask & 1)
3333 *sysc_flags |= SYSS_HAS_RESET_STATUS;
3334
3335 return 0;
3336}
3337
3338
3339
3340
3341
3342
3343
3344int omap_hwmod_init_idlemodes(struct device *dev,
3345 const struct ti_sysc_module_data *data,
3346 u32 *idlemodes)
3347{
3348 *idlemodes = 0;
3349
3350 if (data->cfg->midlemodes & BIT(SYSC_IDLE_FORCE))
3351 *idlemodes |= MSTANDBY_FORCE;
3352 if (data->cfg->midlemodes & BIT(SYSC_IDLE_NO))
3353 *idlemodes |= MSTANDBY_NO;
3354 if (data->cfg->midlemodes & BIT(SYSC_IDLE_SMART))
3355 *idlemodes |= MSTANDBY_SMART;
3356 if (data->cfg->midlemodes & BIT(SYSC_IDLE_SMART_WKUP))
3357 *idlemodes |= MSTANDBY_SMART_WKUP;
3358
3359 if (data->cfg->sidlemodes & BIT(SYSC_IDLE_FORCE))
3360 *idlemodes |= SIDLE_FORCE;
3361 if (data->cfg->sidlemodes & BIT(SYSC_IDLE_NO))
3362 *idlemodes |= SIDLE_NO;
3363 if (data->cfg->sidlemodes & BIT(SYSC_IDLE_SMART))
3364 *idlemodes |= SIDLE_SMART;
3365 if (data->cfg->sidlemodes & BIT(SYSC_IDLE_SMART_WKUP))
3366 *idlemodes |= SIDLE_SMART_WKUP;
3367
3368 return 0;
3369}
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383static int omap_hwmod_check_module(struct device *dev,
3384 struct omap_hwmod *oh,
3385 const struct ti_sysc_module_data *data,
3386 struct sysc_regbits *sysc_fields,
3387 s32 rev_offs, s32 sysc_offs,
3388 s32 syss_offs, u32 sysc_flags,
3389 u32 idlemodes)
3390{
3391 if (!oh->class->sysc)
3392 return -ENODEV;
3393
3394 if (sysc_fields != oh->class->sysc->sysc_fields)
3395 dev_warn(dev, "sysc_fields %p != %p\n", sysc_fields,
3396 oh->class->sysc->sysc_fields);
3397
3398 if (rev_offs != oh->class->sysc->rev_offs)
3399 dev_warn(dev, "rev_offs %08x != %08x\n", rev_offs,
3400 oh->class->sysc->rev_offs);
3401 if (sysc_offs != oh->class->sysc->sysc_offs)
3402 dev_warn(dev, "sysc_offs %08x != %08x\n", sysc_offs,
3403 oh->class->sysc->sysc_offs);
3404 if (syss_offs != oh->class->sysc->syss_offs)
3405 dev_warn(dev, "syss_offs %08x != %08x\n", syss_offs,
3406 oh->class->sysc->syss_offs);
3407
3408 if (sysc_flags != oh->class->sysc->sysc_flags)
3409 dev_warn(dev, "sysc_flags %08x != %08x\n", sysc_flags,
3410 oh->class->sysc->sysc_flags);
3411
3412 if (idlemodes != oh->class->sysc->idlemodes)
3413 dev_warn(dev, "idlemodes %08x != %08x\n", idlemodes,
3414 oh->class->sysc->idlemodes);
3415
3416 if (data->cfg->srst_udelay != oh->class->sysc->srst_udelay)
3417 dev_warn(dev, "srst_udelay %i != %i\n",
3418 data->cfg->srst_udelay,
3419 oh->class->sysc->srst_udelay);
3420
3421 return 0;
3422}
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
3438 const struct ti_sysc_module_data *data,
3439 struct sysc_regbits *sysc_fields,
3440 s32 rev_offs, s32 sysc_offs, s32 syss_offs,
3441 u32 sysc_flags, u32 idlemodes)
3442{
3443 struct omap_hwmod_class_sysconfig *sysc;
3444 struct omap_hwmod_class *class;
3445 void __iomem *regs = NULL;
3446 unsigned long flags;
3447
3448 sysc = kzalloc(sizeof(*sysc), GFP_KERNEL);
3449 if (!sysc)
3450 return -ENOMEM;
3451
3452 sysc->sysc_fields = sysc_fields;
3453 sysc->rev_offs = rev_offs;
3454 sysc->sysc_offs = sysc_offs;
3455 sysc->syss_offs = syss_offs;
3456 sysc->sysc_flags = sysc_flags;
3457 sysc->idlemodes = idlemodes;
3458 sysc->srst_udelay = data->cfg->srst_udelay;
3459
3460 if (!oh->_mpu_rt_va) {
3461 regs = ioremap(data->module_pa,
3462 data->module_size);
3463 if (!regs)
3464 return -ENOMEM;
3465 }
3466
3467
3468
3469
3470
3471 class = kmemdup(oh->class, sizeof(*oh->class), GFP_KERNEL);
3472 if (!class)
3473 return -ENOMEM;
3474
3475 class->sysc = sysc;
3476
3477 spin_lock_irqsave(&oh->_lock, flags);
3478 if (regs)
3479 oh->_mpu_rt_va = regs;
3480 oh->class = class;
3481 oh->_state = _HWMOD_STATE_INITIALIZED;
3482 _setup(oh, NULL);
3483 spin_unlock_irqrestore(&oh->_lock, flags);
3484
3485 return 0;
3486}
3487
3488
3489
3490
3491
3492
3493
3494int omap_hwmod_init_module(struct device *dev,
3495 const struct ti_sysc_module_data *data,
3496 struct ti_sysc_cookie *cookie)
3497{
3498 struct omap_hwmod *oh;
3499 struct sysc_regbits *sysc_fields;
3500 s32 rev_offs, sysc_offs, syss_offs;
3501 u32 sysc_flags, idlemodes;
3502 int error;
3503
3504 if (!dev || !data)
3505 return -EINVAL;
3506
3507 oh = _lookup(data->name);
3508 if (!oh)
3509 return -ENODEV;
3510
3511 cookie->data = oh;
3512
3513 error = omap_hwmod_init_regbits(dev, data, &sysc_fields);
3514 if (error)
3515 return error;
3516
3517 error = omap_hwmod_init_reg_offs(dev, data, &rev_offs,
3518 &sysc_offs, &syss_offs);
3519 if (error)
3520 return error;
3521
3522 error = omap_hwmod_init_sysc_flags(dev, data, &sysc_flags);
3523 if (error)
3524 return error;
3525
3526 error = omap_hwmod_init_idlemodes(dev, data, &idlemodes);
3527 if (error)
3528 return error;
3529
3530 if (data->cfg->quirks & SYSC_QUIRK_NO_IDLE_ON_INIT)
3531 oh->flags |= HWMOD_INIT_NO_IDLE;
3532 if (data->cfg->quirks & SYSC_QUIRK_NO_RESET_ON_INIT)
3533 oh->flags |= HWMOD_INIT_NO_RESET;
3534
3535 error = omap_hwmod_check_module(dev, oh, data, sysc_fields,
3536 rev_offs, sysc_offs, syss_offs,
3537 sysc_flags, idlemodes);
3538 if (!error)
3539 return error;
3540
3541 return omap_hwmod_allocate_module(dev, oh, data, sysc_fields,
3542 rev_offs, sysc_offs, syss_offs,
3543 sysc_flags, idlemodes);
3544}
3545
3546
3547
3548
3549
3550
3551
3552
3553#ifdef CONFIG_SERIAL_EARLYCON
3554static void __init omap_hwmod_setup_earlycon_flags(void)
3555{
3556 struct device_node *np;
3557 struct omap_hwmod *oh;
3558 const char *uart;
3559
3560 np = of_find_node_by_path("/chosen");
3561 if (np) {
3562 uart = of_get_property(np, "stdout-path", NULL);
3563 if (uart) {
3564 np = of_find_node_by_path(uart);
3565 if (np) {
3566 uart = of_get_property(np, "ti,hwmods", NULL);
3567 oh = omap_hwmod_lookup(uart);
3568 if (!oh) {
3569 uart = of_get_property(np->parent,
3570 "ti,hwmods",
3571 NULL);
3572 oh = omap_hwmod_lookup(uart);
3573 }
3574 if (oh)
3575 oh->flags |= DEBUG_OMAPUART_FLAGS;
3576 }
3577 }
3578 }
3579}
3580#endif
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590static int __init omap_hwmod_setup_all(void)
3591{
3592 _ensure_mpu_hwmod_is_setup(NULL);
3593
3594 omap_hwmod_for_each(_init, NULL);
3595#ifdef CONFIG_SERIAL_EARLYCON
3596 omap_hwmod_setup_earlycon_flags();
3597#endif
3598 omap_hwmod_for_each(_setup, NULL);
3599
3600 return 0;
3601}
3602omap_postcore_initcall(omap_hwmod_setup_all);
3603
3604
3605
3606
3607
3608
3609
3610
3611int omap_hwmod_enable(struct omap_hwmod *oh)
3612{
3613 int r;
3614 unsigned long flags;
3615
3616 if (!oh)
3617 return -EINVAL;
3618
3619 spin_lock_irqsave(&oh->_lock, flags);
3620 r = _enable(oh);
3621 spin_unlock_irqrestore(&oh->_lock, flags);
3622
3623 return r;
3624}
3625
3626
3627
3628
3629
3630
3631
3632
3633int omap_hwmod_idle(struct omap_hwmod *oh)
3634{
3635 int r;
3636 unsigned long flags;
3637
3638 if (!oh)
3639 return -EINVAL;
3640
3641 spin_lock_irqsave(&oh->_lock, flags);
3642 r = _idle(oh);
3643 spin_unlock_irqrestore(&oh->_lock, flags);
3644
3645 return r;
3646}
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656int omap_hwmod_shutdown(struct omap_hwmod *oh)
3657{
3658 int r;
3659 unsigned long flags;
3660
3661 if (!oh)
3662 return -EINVAL;
3663
3664 spin_lock_irqsave(&oh->_lock, flags);
3665 r = _shutdown(oh);
3666 spin_unlock_irqrestore(&oh->_lock, flags);
3667
3668 return r;
3669}
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
3687{
3688 struct clk *c;
3689 struct omap_hwmod_ocp_if *oi;
3690 struct clockdomain *clkdm;
3691 struct clk_hw_omap *clk;
3692
3693 if (!oh)
3694 return NULL;
3695
3696 if (oh->clkdm)
3697 return oh->clkdm->pwrdm.ptr;
3698
3699 if (oh->_clk) {
3700 c = oh->_clk;
3701 } else {
3702 oi = _find_mpu_rt_port(oh);
3703 if (!oi)
3704 return NULL;
3705 c = oi->_clk;
3706 }
3707
3708 clk = to_clk_hw_omap(__clk_get_hw(c));
3709 clkdm = clk->clkdm;
3710 if (!clkdm)
3711 return NULL;
3712
3713 return clkdm->pwrdm.ptr;
3714}
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
3726{
3727 if (!oh)
3728 return NULL;
3729
3730 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
3731 return NULL;
3732
3733 if (oh->_state == _HWMOD_STATE_UNKNOWN)
3734 return NULL;
3735
3736 return oh->_mpu_rt_va;
3737}
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
3758{
3759 unsigned long flags;
3760 u32 v;
3761
3762 spin_lock_irqsave(&oh->_lock, flags);
3763
3764 if (oh->class->sysc &&
3765 (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
3766 v = oh->_sysc_cache;
3767 _enable_wakeup(oh, &v);
3768 _write_sysconfig(v, oh);
3769 }
3770
3771 spin_unlock_irqrestore(&oh->_lock, flags);
3772
3773 return 0;
3774}
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
3790{
3791 unsigned long flags;
3792 u32 v;
3793
3794 spin_lock_irqsave(&oh->_lock, flags);
3795
3796 if (oh->class->sysc &&
3797 (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
3798 v = oh->_sysc_cache;
3799 _disable_wakeup(oh, &v);
3800 _write_sysconfig(v, oh);
3801 }
3802
3803 spin_unlock_irqrestore(&oh->_lock, flags);
3804
3805 return 0;
3806}
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name)
3821{
3822 int ret;
3823 unsigned long flags;
3824
3825 if (!oh)
3826 return -EINVAL;
3827
3828 spin_lock_irqsave(&oh->_lock, flags);
3829 ret = _assert_hardreset(oh, name);
3830 spin_unlock_irqrestore(&oh->_lock, flags);
3831
3832 return ret;
3833}
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name)
3848{
3849 int ret;
3850 unsigned long flags;
3851
3852 if (!oh)
3853 return -EINVAL;
3854
3855 spin_lock_irqsave(&oh->_lock, flags);
3856 ret = _deassert_hardreset(oh, name);
3857 spin_unlock_irqrestore(&oh->_lock, flags);
3858
3859 return ret;
3860}
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874int omap_hwmod_for_each_by_class(const char *classname,
3875 int (*fn)(struct omap_hwmod *oh,
3876 void *user),
3877 void *user)
3878{
3879 struct omap_hwmod *temp_oh;
3880 int ret = 0;
3881
3882 if (!classname || !fn)
3883 return -EINVAL;
3884
3885 pr_debug("omap_hwmod: %s: looking for modules of class %s\n",
3886 __func__, classname);
3887
3888 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
3889 if (!strcmp(temp_oh->class->name, classname)) {
3890 pr_debug("omap_hwmod: %s: %s: calling callback fn\n",
3891 __func__, temp_oh->name);
3892 ret = (*fn)(temp_oh, user);
3893 if (ret)
3894 break;
3895 }
3896 }
3897
3898 if (ret)
3899 pr_debug("omap_hwmod: %s: iterator terminated early: %d\n",
3900 __func__, ret);
3901
3902 return ret;
3903}
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state)
3917{
3918 int ret;
3919 unsigned long flags;
3920
3921 if (!oh)
3922 return -EINVAL;
3923
3924 if (state != _HWMOD_STATE_DISABLED &&
3925 state != _HWMOD_STATE_ENABLED &&
3926 state != _HWMOD_STATE_IDLE)
3927 return -EINVAL;
3928
3929 spin_lock_irqsave(&oh->_lock, flags);
3930
3931 if (oh->_state != _HWMOD_STATE_REGISTERED) {
3932 ret = -EINVAL;
3933 goto ohsps_unlock;
3934 }
3935
3936 oh->_postsetup_state = state;
3937 ret = 0;
3938
3939ohsps_unlock:
3940 spin_unlock_irqrestore(&oh->_lock, flags);
3941
3942 return ret;
3943}
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
3957{
3958 struct powerdomain *pwrdm;
3959 int ret = 0;
3960
3961 if (soc_ops.get_context_lost)
3962 return soc_ops.get_context_lost(oh);
3963
3964 pwrdm = omap_hwmod_get_pwrdm(oh);
3965 if (pwrdm)
3966 ret = pwrdm_get_context_loss_count(pwrdm);
3967
3968 return ret;
3969}
3970
3971
3972
3973
3974
3975
3976
3977
3978void __init omap_hwmod_init(void)
3979{
3980 if (cpu_is_omap24xx()) {
3981 soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready;
3982 soc_ops.assert_hardreset = _omap2_assert_hardreset;
3983 soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
3984 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
3985 } else if (cpu_is_omap34xx()) {
3986 soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready;
3987 soc_ops.assert_hardreset = _omap2_assert_hardreset;
3988 soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
3989 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
3990 soc_ops.init_clkdm = _init_clkdm;
3991 } else if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) {
3992 soc_ops.enable_module = _omap4_enable_module;
3993 soc_ops.disable_module = _omap4_disable_module;
3994 soc_ops.wait_target_ready = _omap4_wait_target_ready;
3995 soc_ops.assert_hardreset = _omap4_assert_hardreset;
3996 soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
3997 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
3998 soc_ops.init_clkdm = _init_clkdm;
3999 soc_ops.update_context_lost = _omap4_update_context_lost;
4000 soc_ops.get_context_lost = _omap4_get_context_lost;
4001 soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm;
4002 soc_ops.xlate_clkctrl = _omap4_xlate_clkctrl;
4003 } else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() ||
4004 soc_is_am43xx()) {
4005 soc_ops.enable_module = _omap4_enable_module;
4006 soc_ops.disable_module = _omap4_disable_module;
4007 soc_ops.wait_target_ready = _omap4_wait_target_ready;
4008 soc_ops.assert_hardreset = _omap4_assert_hardreset;
4009 soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
4010 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
4011 soc_ops.init_clkdm = _init_clkdm;
4012 soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm;
4013 soc_ops.xlate_clkctrl = _omap4_xlate_clkctrl;
4014 } else {
4015 WARN(1, "omap_hwmod: unknown SoC type\n");
4016 }
4017
4018 _init_clkctrl_providers();
4019
4020 inited = true;
4021}
4022
4023
4024
4025
4026
4027
4028
4029
4030const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh)
4031{
4032 if (!oh)
4033 return NULL;
4034
4035 return oh->main_clk;
4036}
4037