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