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