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