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
1420 if (oh->_sysc_cache != v)
1421 _write_sysconfig(v, oh);
1422
1423
1424
1425
1426
1427 if (sf & SYSC_HAS_AUTOIDLE) {
1428 idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
1429 0 : 1;
1430 _set_module_autoidle(oh, idlemode, &v);
1431 _write_sysconfig(v, oh);
1432 }
1433}
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444static void _idle_sysc(struct omap_hwmod *oh)
1445{
1446 u8 idlemode, sf;
1447 u32 v;
1448
1449 if (!oh->class->sysc)
1450 return;
1451
1452 v = oh->_sysc_cache;
1453 sf = oh->class->sysc->sysc_flags;
1454
1455 if (sf & SYSC_HAS_SIDLEMODE) {
1456 if (oh->flags & HWMOD_SWSUP_SIDLE) {
1457 idlemode = HWMOD_IDLEMODE_FORCE;
1458 } else {
1459 if (sf & SYSC_HAS_ENAWAKEUP)
1460 _enable_wakeup(oh, &v);
1461 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
1462 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1463 else
1464 idlemode = HWMOD_IDLEMODE_SMART;
1465 }
1466 _set_slave_idlemode(oh, idlemode, &v);
1467 }
1468
1469 if (sf & SYSC_HAS_MIDLEMODE) {
1470 if ((oh->flags & HWMOD_SWSUP_MSTANDBY) ||
1471 (oh->flags & HWMOD_FORCE_MSTANDBY)) {
1472 idlemode = HWMOD_IDLEMODE_FORCE;
1473 } else {
1474 if (sf & SYSC_HAS_ENAWAKEUP)
1475 _enable_wakeup(oh, &v);
1476 if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
1477 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1478 else
1479 idlemode = HWMOD_IDLEMODE_SMART;
1480 }
1481 _set_master_standbymode(oh, idlemode, &v);
1482 }
1483
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 pr_debug("omap_hwmod: %s: idling\n", oh->name);
2204
2205 if (oh->_state != _HWMOD_STATE_ENABLED) {
2206 WARN(1, "omap_hwmod: %s: idle state can only be entered from enabled state\n",
2207 oh->name);
2208 return -EINVAL;
2209 }
2210
2211 if (_are_all_hardreset_lines_asserted(oh))
2212 return 0;
2213
2214 if (oh->class->sysc)
2215 _idle_sysc(oh);
2216 _del_initiator_dep(oh, mpu_oh);
2217
2218 if (oh->flags & HWMOD_BLOCK_WFI)
2219 cpu_idle_poll_ctrl(false);
2220 if (soc_ops.disable_module)
2221 soc_ops.disable_module(oh);
2222
2223
2224
2225
2226
2227
2228
2229 _disable_clocks(oh);
2230 if (oh->clkdm)
2231 clkdm_hwmod_disable(oh->clkdm, oh);
2232
2233
2234 if (oh->mux && oh->mux->pads_dynamic) {
2235 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
2236 _reconfigure_io_chain();
2237 } else if (oh->flags & HWMOD_RECONFIG_IO_CHAIN) {
2238 _reconfigure_io_chain();
2239 }
2240
2241 oh->_state = _HWMOD_STATE_IDLE;
2242
2243 return 0;
2244}
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255static int _shutdown(struct omap_hwmod *oh)
2256{
2257 int ret, i;
2258 u8 prev_state;
2259
2260 if (oh->_state != _HWMOD_STATE_IDLE &&
2261 oh->_state != _HWMOD_STATE_ENABLED) {
2262 WARN(1, "omap_hwmod: %s: disabled state can only be entered from idle, or enabled state\n",
2263 oh->name);
2264 return -EINVAL;
2265 }
2266
2267 if (_are_all_hardreset_lines_asserted(oh))
2268 return 0;
2269
2270 pr_debug("omap_hwmod: %s: disabling\n", oh->name);
2271
2272 if (oh->class->pre_shutdown) {
2273 prev_state = oh->_state;
2274 if (oh->_state == _HWMOD_STATE_IDLE)
2275 _enable(oh);
2276 ret = oh->class->pre_shutdown(oh);
2277 if (ret) {
2278 if (prev_state == _HWMOD_STATE_IDLE)
2279 _idle(oh);
2280 return ret;
2281 }
2282 }
2283
2284 if (oh->class->sysc) {
2285 if (oh->_state == _HWMOD_STATE_IDLE)
2286 _enable(oh);
2287 _shutdown_sysc(oh);
2288 }
2289
2290
2291 if (oh->_state == _HWMOD_STATE_ENABLED) {
2292 _del_initiator_dep(oh, mpu_oh);
2293
2294 if (oh->flags & HWMOD_BLOCK_WFI)
2295 cpu_idle_poll_ctrl(false);
2296 if (soc_ops.disable_module)
2297 soc_ops.disable_module(oh);
2298 _disable_clocks(oh);
2299 if (oh->clkdm)
2300 clkdm_hwmod_disable(oh->clkdm, oh);
2301 }
2302
2303
2304 for (i = 0; i < oh->rst_lines_cnt; i++)
2305 _assert_hardreset(oh, oh->rst_lines[i].name);
2306
2307
2308 if (oh->mux)
2309 omap_hwmod_mux(oh->mux, _HWMOD_STATE_DISABLED);
2310
2311 oh->_state = _HWMOD_STATE_DISABLED;
2312
2313 return 0;
2314}
2315
2316static int of_dev_find_hwmod(struct device_node *np,
2317 struct omap_hwmod *oh)
2318{
2319 int count, i, res;
2320 const char *p;
2321
2322 count = of_property_count_strings(np, "ti,hwmods");
2323 if (count < 1)
2324 return -ENODEV;
2325
2326 for (i = 0; i < count; i++) {
2327 res = of_property_read_string_index(np, "ti,hwmods",
2328 i, &p);
2329 if (res)
2330 continue;
2331 if (!strcmp(p, oh->name)) {
2332 pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n",
2333 np->name, i, oh->name);
2334 return i;
2335 }
2336 }
2337
2338 return -ENODEV;
2339}
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352static int of_dev_hwmod_lookup(struct device_node *np,
2353 struct omap_hwmod *oh,
2354 int *index,
2355 struct device_node **found)
2356{
2357 struct device_node *np0 = NULL;
2358 int res;
2359
2360 res = of_dev_find_hwmod(np, oh);
2361 if (res >= 0) {
2362 *found = np;
2363 *index = res;
2364 return 0;
2365 }
2366
2367 for_each_child_of_node(np, np0) {
2368 struct device_node *fc;
2369 int i;
2370
2371 res = of_dev_hwmod_lookup(np0, oh, &i, &fc);
2372 if (res == 0) {
2373 *found = fc;
2374 *index = i;
2375 return 0;
2376 }
2377 }
2378
2379 *found = NULL;
2380 *index = 0;
2381
2382 return -ENODEV;
2383}
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
2403 int index, struct device_node *np)
2404{
2405 struct omap_hwmod_addr_space *mem;
2406 void __iomem *va_start = NULL;
2407
2408 if (!oh)
2409 return -EINVAL;
2410
2411 _save_mpu_port_index(oh);
2412
2413
2414 if (!oh->class->sysc)
2415 return 0;
2416
2417
2418 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
2419 return -ENXIO;
2420
2421 mem = _find_mpu_rt_addr_space(oh);
2422 if (!mem) {
2423 pr_debug("omap_hwmod: %s: no MPU register target found\n",
2424 oh->name);
2425
2426
2427 if (!np) {
2428 pr_err("omap_hwmod: %s: no dt node\n", oh->name);
2429 return -ENXIO;
2430 }
2431
2432 va_start = of_iomap(np, index + oh->mpu_rt_idx);
2433 } else {
2434 va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
2435 }
2436
2437 if (!va_start) {
2438 if (mem)
2439 pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
2440 else
2441 pr_err("omap_hwmod: %s: Missing dt reg%i for %s\n",
2442 oh->name, index, np->full_name);
2443 return -ENXIO;
2444 }
2445
2446 pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
2447 oh->name, va_start);
2448
2449 oh->_mpu_rt_va = va_start;
2450 return 0;
2451}
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466static int __init _init(struct omap_hwmod *oh, void *data)
2467{
2468 int r, index;
2469 struct device_node *np = NULL;
2470
2471 if (oh->_state != _HWMOD_STATE_REGISTERED)
2472 return 0;
2473
2474 if (of_have_populated_dt()) {
2475 struct device_node *bus;
2476
2477 bus = of_find_node_by_name(NULL, "ocp");
2478 if (!bus)
2479 return -ENODEV;
2480
2481 r = of_dev_hwmod_lookup(bus, oh, &index, &np);
2482 if (r)
2483 pr_debug("omap_hwmod: %s missing dt data\n", oh->name);
2484 else if (np && index)
2485 pr_warn("omap_hwmod: %s using broken dt data from %s\n",
2486 oh->name, np->name);
2487 }
2488
2489 r = _init_mpu_rt_base(oh, NULL, index, np);
2490 if (r < 0) {
2491 WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
2492 oh->name);
2493 return 0;
2494 }
2495
2496 r = _init_clocks(oh, NULL);
2497 if (r < 0) {
2498 WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name);
2499 return -EINVAL;
2500 }
2501
2502 if (np) {
2503 if (of_find_property(np, "ti,no-reset-on-init", NULL))
2504 oh->flags |= HWMOD_INIT_NO_RESET;
2505 if (of_find_property(np, "ti,no-idle-on-init", NULL))
2506 oh->flags |= HWMOD_INIT_NO_IDLE;
2507 }
2508
2509 oh->_state = _HWMOD_STATE_INITIALIZED;
2510
2511 return 0;
2512}
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522static void __init _setup_iclk_autoidle(struct omap_hwmod *oh)
2523{
2524 struct omap_hwmod_ocp_if *os;
2525 struct list_head *p;
2526 int i = 0;
2527 if (oh->_state != _HWMOD_STATE_INITIALIZED)
2528 return;
2529
2530 p = oh->slave_ports.next;
2531
2532 while (i < oh->slaves_cnt) {
2533 os = _fetch_next_ocp_if(&p, &i);
2534 if (!os->_clk)
2535 continue;
2536
2537 if (os->flags & OCPIF_SWSUP_IDLE) {
2538
2539 } else {
2540
2541 clk_enable(os->_clk);
2542 }
2543 }
2544
2545 return;
2546}
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557static int __init _setup_reset(struct omap_hwmod *oh)
2558{
2559 int r;
2560
2561 if (oh->_state != _HWMOD_STATE_INITIALIZED)
2562 return -EINVAL;
2563
2564 if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK)
2565 return -EPERM;
2566
2567 if (oh->rst_lines_cnt == 0) {
2568 r = _enable(oh);
2569 if (r) {
2570 pr_warn("omap_hwmod: %s: cannot be enabled for reset (%d)\n",
2571 oh->name, oh->_state);
2572 return -EINVAL;
2573 }
2574 }
2575
2576 if (!(oh->flags & HWMOD_INIT_NO_RESET))
2577 r = _reset(oh);
2578
2579 return r;
2580}
2581
2582
2583
2584
2585
2586
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
2618static void __init _setup_postsetup(struct omap_hwmod *oh)
2619{
2620 u8 postsetup_state;
2621
2622 if (oh->rst_lines_cnt > 0)
2623 return;
2624
2625 postsetup_state = oh->_postsetup_state;
2626 if (postsetup_state == _HWMOD_STATE_UNKNOWN)
2627 postsetup_state = _HWMOD_STATE_ENABLED;
2628
2629
2630
2631
2632
2633 if ((oh->flags & HWMOD_INIT_NO_IDLE) &&
2634 (postsetup_state == _HWMOD_STATE_IDLE)) {
2635 oh->_int_flags |= _HWMOD_SKIP_ENABLE;
2636 postsetup_state = _HWMOD_STATE_ENABLED;
2637 }
2638
2639 if (postsetup_state == _HWMOD_STATE_IDLE)
2640 _idle(oh);
2641 else if (postsetup_state == _HWMOD_STATE_DISABLED)
2642 _shutdown(oh);
2643 else if (postsetup_state != _HWMOD_STATE_ENABLED)
2644 WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
2645 oh->name, postsetup_state);
2646
2647 return;
2648}
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666static int __init _setup(struct omap_hwmod *oh, void *data)
2667{
2668 if (oh->_state != _HWMOD_STATE_INITIALIZED)
2669 return 0;
2670
2671 if (oh->parent_hwmod) {
2672 int r;
2673
2674 r = _enable(oh->parent_hwmod);
2675 WARN(r, "hwmod: %s: setup: failed to enable parent hwmod %s\n",
2676 oh->name, oh->parent_hwmod->name);
2677 }
2678
2679 _setup_iclk_autoidle(oh);
2680
2681 if (!_setup_reset(oh))
2682 _setup_postsetup(oh);
2683
2684 if (oh->parent_hwmod) {
2685 u8 postsetup_state;
2686
2687 postsetup_state = oh->parent_hwmod->_postsetup_state;
2688
2689 if (postsetup_state == _HWMOD_STATE_IDLE)
2690 _idle(oh->parent_hwmod);
2691 else if (postsetup_state == _HWMOD_STATE_DISABLED)
2692 _shutdown(oh->parent_hwmod);
2693 else if (postsetup_state != _HWMOD_STATE_ENABLED)
2694 WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
2695 oh->parent_hwmod->name, postsetup_state);
2696 }
2697
2698 return 0;
2699}
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718static int __init _register(struct omap_hwmod *oh)
2719{
2720 if (!oh || !oh->name || !oh->class || !oh->class->name ||
2721 (oh->_state != _HWMOD_STATE_UNKNOWN))
2722 return -EINVAL;
2723
2724 pr_debug("omap_hwmod: %s: registering\n", oh->name);
2725
2726 if (_lookup(oh->name))
2727 return -EEXIST;
2728
2729 list_add_tail(&oh->node, &omap_hwmod_list);
2730
2731 INIT_LIST_HEAD(&oh->master_ports);
2732 INIT_LIST_HEAD(&oh->slave_ports);
2733 spin_lock_init(&oh->_lock);
2734 lockdep_set_class(&oh->_lock, &oh->hwmod_key);
2735
2736 oh->_state = _HWMOD_STATE_REGISTERED;
2737
2738
2739
2740
2741
2742 if (!strcmp(oh->name, MPU_INITIATOR_NAME))
2743 mpu_oh = oh;
2744
2745 return 0;
2746}
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761static int __init _alloc_links(struct omap_hwmod_link **ml,
2762 struct omap_hwmod_link **sl)
2763{
2764 unsigned int sz;
2765
2766 if ((free_ls + LINKS_PER_OCP_IF) <= max_ls) {
2767 *ml = &linkspace[free_ls++];
2768 *sl = &linkspace[free_ls++];
2769 return 0;
2770 }
2771
2772 sz = sizeof(struct omap_hwmod_link) * LINKS_PER_OCP_IF;
2773
2774 *sl = NULL;
2775 *ml = memblock_virt_alloc(sz, 0);
2776
2777 *sl = (void *)(*ml) + sizeof(struct omap_hwmod_link);
2778
2779 ls_supp++;
2780 pr_debug("omap_hwmod: supplemental link allocations needed: %d\n",
2781 ls_supp * LINKS_PER_OCP_IF);
2782
2783 return 0;
2784};
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797static int __init _add_link(struct omap_hwmod_ocp_if *oi)
2798{
2799 struct omap_hwmod_link *ml, *sl;
2800
2801 pr_debug("omap_hwmod: %s -> %s: adding link\n", oi->master->name,
2802 oi->slave->name);
2803
2804 _alloc_links(&ml, &sl);
2805
2806 ml->ocp_if = oi;
2807 list_add(&ml->node, &oi->master->master_ports);
2808 oi->master->masters_cnt++;
2809
2810 sl->ocp_if = oi;
2811 list_add(&sl->node, &oi->slave->slave_ports);
2812 oi->slave->slaves_cnt++;
2813
2814 return 0;
2815}
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830static int __init _register_link(struct omap_hwmod_ocp_if *oi)
2831{
2832 if (!oi || !oi->master || !oi->slave || !oi->user)
2833 return -EINVAL;
2834
2835 if (oi->_int_flags & _OCPIF_INT_FLAGS_REGISTERED)
2836 return -EEXIST;
2837
2838 pr_debug("omap_hwmod: registering link from %s to %s\n",
2839 oi->master->name, oi->slave->name);
2840
2841
2842
2843
2844
2845 if (oi->master->_state != _HWMOD_STATE_REGISTERED)
2846 _register(oi->master);
2847
2848 if (oi->slave->_state != _HWMOD_STATE_REGISTERED)
2849 _register(oi->slave);
2850
2851 _add_link(oi);
2852
2853 oi->_int_flags |= _OCPIF_INT_FLAGS_REGISTERED;
2854
2855 return 0;
2856}
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)
2874{
2875 unsigned int i = 0;
2876 unsigned int sz;
2877
2878 if (linkspace) {
2879 WARN(1, "linkspace already allocated\n");
2880 return -EEXIST;
2881 }
2882
2883 if (max_ls == 0)
2884 while (ois[i++])
2885 max_ls += LINKS_PER_OCP_IF;
2886
2887 sz = sizeof(struct omap_hwmod_link) * max_ls;
2888
2889 pr_debug("omap_hwmod: %s: allocating %d byte linkspace (%d links)\n",
2890 __func__, sz, max_ls);
2891
2892 linkspace = memblock_virt_alloc(sz, 0);
2893
2894 return 0;
2895}
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908static int _omap2xxx_3xxx_wait_target_ready(struct omap_hwmod *oh)
2909{
2910 if (!oh)
2911 return -EINVAL;
2912
2913 if (oh->flags & HWMOD_NO_IDLEST)
2914 return 0;
2915
2916 if (!_find_mpu_rt_port(oh))
2917 return 0;
2918
2919
2920
2921 return omap_cm_wait_module_ready(0, oh->prcm.omap2.module_offs,
2922 oh->prcm.omap2.idlest_reg_id,
2923 oh->prcm.omap2.idlest_idle_bit);
2924}
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935static int _omap4_wait_target_ready(struct omap_hwmod *oh)
2936{
2937 if (!oh)
2938 return -EINVAL;
2939
2940 if (oh->flags & HWMOD_NO_IDLEST || !oh->clkdm)
2941 return 0;
2942
2943 if (!_find_mpu_rt_port(oh))
2944 return 0;
2945
2946
2947
2948 return omap_cm_wait_module_ready(oh->clkdm->prcm_partition,
2949 oh->clkdm->cm_inst,
2950 oh->prcm.omap4.clkctrl_offs, 0);
2951}
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964static int _omap2_assert_hardreset(struct omap_hwmod *oh,
2965 struct omap_hwmod_rst_info *ohri)
2966{
2967 return omap_prm_assert_hardreset(ohri->rst_shift, 0,
2968 oh->prcm.omap2.module_offs, 0);
2969}
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982static int _omap2_deassert_hardreset(struct omap_hwmod *oh,
2983 struct omap_hwmod_rst_info *ohri)
2984{
2985 return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0,
2986 oh->prcm.omap2.module_offs, 0, 0);
2987}
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh,
3002 struct omap_hwmod_rst_info *ohri)
3003{
3004 return omap_prm_is_hardreset_asserted(ohri->st_shift, 0,
3005 oh->prcm.omap2.module_offs, 0);
3006}
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020static int _omap4_assert_hardreset(struct omap_hwmod *oh,
3021 struct omap_hwmod_rst_info *ohri)
3022{
3023 if (!oh->clkdm)
3024 return -EINVAL;
3025
3026 return omap_prm_assert_hardreset(ohri->rst_shift,
3027 oh->clkdm->pwrdm.ptr->prcm_partition,
3028 oh->clkdm->pwrdm.ptr->prcm_offs,
3029 oh->prcm.omap4.rstctrl_offs);
3030}
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044static int _omap4_deassert_hardreset(struct omap_hwmod *oh,
3045 struct omap_hwmod_rst_info *ohri)
3046{
3047 if (!oh->clkdm)
3048 return -EINVAL;
3049
3050 if (ohri->st_shift)
3051 pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
3052 oh->name, ohri->name);
3053 return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->rst_shift,
3054 oh->clkdm->pwrdm.ptr->prcm_partition,
3055 oh->clkdm->pwrdm.ptr->prcm_offs,
3056 oh->prcm.omap4.rstctrl_offs,
3057 oh->prcm.omap4.rstctrl_offs +
3058 OMAP4_RST_CTRL_ST_OFFSET);
3059}
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
3074 struct omap_hwmod_rst_info *ohri)
3075{
3076 if (!oh->clkdm)
3077 return -EINVAL;
3078
3079 return omap_prm_is_hardreset_asserted(ohri->rst_shift,
3080 oh->clkdm->pwrdm.ptr->
3081 prcm_partition,
3082 oh->clkdm->pwrdm.ptr->prcm_offs,
3083 oh->prcm.omap4.rstctrl_offs);
3084}
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
3099 struct omap_hwmod_rst_info *ohri)
3100{
3101 return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift,
3102 oh->clkdm->pwrdm.ptr->prcm_partition,
3103 oh->clkdm->pwrdm.ptr->prcm_offs,
3104 oh->prcm.omap4.rstctrl_offs,
3105 oh->prcm.omap4.rstst_offs);
3106}
3107
3108
3109
3110u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
3111{
3112 if (oh->flags & HWMOD_16BIT_REG)
3113 return readw_relaxed(oh->_mpu_rt_va + reg_offs);
3114 else
3115 return readl_relaxed(oh->_mpu_rt_va + reg_offs);
3116}
3117
3118void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs)
3119{
3120 if (oh->flags & HWMOD_16BIT_REG)
3121 writew_relaxed(v, oh->_mpu_rt_va + reg_offs);
3122 else
3123 writel_relaxed(v, oh->_mpu_rt_va + reg_offs);
3124}
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135int omap_hwmod_softreset(struct omap_hwmod *oh)
3136{
3137 u32 v;
3138 int ret;
3139
3140 if (!oh || !(oh->_sysc_cache))
3141 return -EINVAL;
3142
3143 v = oh->_sysc_cache;
3144 ret = _set_softreset(oh, &v);
3145 if (ret)
3146 goto error;
3147 _write_sysconfig(v, oh);
3148
3149 ret = _clear_softreset(oh, &v);
3150 if (ret)
3151 goto error;
3152 _write_sysconfig(v, oh);
3153
3154error:
3155 return ret;
3156}
3157
3158
3159
3160
3161
3162
3163
3164
3165struct omap_hwmod *omap_hwmod_lookup(const char *name)
3166{
3167 struct omap_hwmod *oh;
3168
3169 if (!name)
3170 return NULL;
3171
3172 oh = _lookup(name);
3173
3174 return oh;
3175}
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
3190 void *data)
3191{
3192 struct omap_hwmod *temp_oh;
3193 int ret = 0;
3194
3195 if (!fn)
3196 return -EINVAL;
3197
3198 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
3199 ret = (*fn)(temp_oh, data);
3200 if (ret)
3201 break;
3202 }
3203
3204 return ret;
3205}
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois)
3219{
3220 int r, i;
3221
3222 if (!inited)
3223 return -EINVAL;
3224
3225 if (!ois)
3226 return 0;
3227
3228 if (ois[0] == NULL)
3229 return 0;
3230
3231 if (!linkspace) {
3232 if (_alloc_linkspace(ois)) {
3233 pr_err("omap_hwmod: could not allocate link space\n");
3234 return -ENOMEM;
3235 }
3236 }
3237
3238 i = 0;
3239 do {
3240 r = _register_link(ois[i]);
3241 WARN(r && r != -EEXIST,
3242 "omap_hwmod: _register_link(%s -> %s) returned %d\n",
3243 ois[i]->master->name, ois[i]->slave->name, r);
3244 } while (ois[++i]);
3245
3246 return 0;
3247}
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259static void __init _ensure_mpu_hwmod_is_setup(struct omap_hwmod *oh)
3260{
3261 if (!mpu_oh || mpu_oh->_state == _HWMOD_STATE_UNKNOWN)
3262 pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n",
3263 __func__, MPU_INITIATOR_NAME);
3264 else if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh)
3265 omap_hwmod_setup_one(MPU_INITIATOR_NAME);
3266}
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279int __init omap_hwmod_setup_one(const char *oh_name)
3280{
3281 struct omap_hwmod *oh;
3282
3283 pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__);
3284
3285 oh = _lookup(oh_name);
3286 if (!oh) {
3287 WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name);
3288 return -EINVAL;
3289 }
3290
3291 _ensure_mpu_hwmod_is_setup(oh);
3292
3293 _init(oh, NULL);
3294 _setup(oh, NULL);
3295
3296 return 0;
3297}
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307static int __init omap_hwmod_setup_all(void)
3308{
3309 _ensure_mpu_hwmod_is_setup(NULL);
3310
3311 omap_hwmod_for_each(_init, NULL);
3312 omap_hwmod_for_each(_setup, NULL);
3313
3314 return 0;
3315}
3316omap_core_initcall(omap_hwmod_setup_all);
3317
3318
3319
3320
3321
3322
3323
3324
3325int omap_hwmod_enable(struct omap_hwmod *oh)
3326{
3327 int r;
3328 unsigned long flags;
3329
3330 if (!oh)
3331 return -EINVAL;
3332
3333 spin_lock_irqsave(&oh->_lock, flags);
3334 r = _enable(oh);
3335 spin_unlock_irqrestore(&oh->_lock, flags);
3336
3337 return r;
3338}
3339
3340
3341
3342
3343
3344
3345
3346
3347int omap_hwmod_idle(struct omap_hwmod *oh)
3348{
3349 int r;
3350 unsigned long flags;
3351
3352 if (!oh)
3353 return -EINVAL;
3354
3355 spin_lock_irqsave(&oh->_lock, flags);
3356 r = _idle(oh);
3357 spin_unlock_irqrestore(&oh->_lock, flags);
3358
3359 return r;
3360}
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370int omap_hwmod_shutdown(struct omap_hwmod *oh)
3371{
3372 int r;
3373 unsigned long flags;
3374
3375 if (!oh)
3376 return -EINVAL;
3377
3378 spin_lock_irqsave(&oh->_lock, flags);
3379 r = _shutdown(oh);
3380 spin_unlock_irqrestore(&oh->_lock, flags);
3381
3382 return r;
3383}
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags)
3406{
3407 int ret = 0;
3408
3409 if (flags & IORESOURCE_IRQ)
3410 ret += _count_mpu_irqs(oh);
3411
3412 if (flags & IORESOURCE_DMA)
3413 ret += _count_sdma_reqs(oh);
3414
3415 if (flags & IORESOURCE_MEM) {
3416 int i = 0;
3417 struct omap_hwmod_ocp_if *os;
3418 struct list_head *p = oh->slave_ports.next;
3419
3420 while (i < oh->slaves_cnt) {
3421 os = _fetch_next_ocp_if(&p, &i);
3422 ret += _count_ocp_if_addr_spaces(os);
3423 }
3424 }
3425
3426 return ret;
3427}
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
3440{
3441 struct omap_hwmod_ocp_if *os;
3442 struct list_head *p;
3443 int i, j, mpu_irqs_cnt, sdma_reqs_cnt, addr_cnt;
3444 int r = 0;
3445
3446
3447
3448 mpu_irqs_cnt = _count_mpu_irqs(oh);
3449 for (i = 0; i < mpu_irqs_cnt; i++) {
3450 unsigned int irq;
3451
3452 if (oh->xlate_irq)
3453 irq = oh->xlate_irq((oh->mpu_irqs + i)->irq);
3454 else
3455 irq = (oh->mpu_irqs + i)->irq;
3456 (res + r)->name = (oh->mpu_irqs + i)->name;
3457 (res + r)->start = irq;
3458 (res + r)->end = irq;
3459 (res + r)->flags = IORESOURCE_IRQ;
3460 r++;
3461 }
3462
3463 sdma_reqs_cnt = _count_sdma_reqs(oh);
3464 for (i = 0; i < sdma_reqs_cnt; i++) {
3465 (res + r)->name = (oh->sdma_reqs + i)->name;
3466 (res + r)->start = (oh->sdma_reqs + i)->dma_req;
3467 (res + r)->end = (oh->sdma_reqs + i)->dma_req;
3468 (res + r)->flags = IORESOURCE_DMA;
3469 r++;
3470 }
3471
3472 p = oh->slave_ports.next;
3473
3474 i = 0;
3475 while (i < oh->slaves_cnt) {
3476 os = _fetch_next_ocp_if(&p, &i);
3477 addr_cnt = _count_ocp_if_addr_spaces(os);
3478
3479 for (j = 0; j < addr_cnt; j++) {
3480 (res + r)->name = (os->addr + j)->name;
3481 (res + r)->start = (os->addr + j)->pa_start;
3482 (res + r)->end = (os->addr + j)->pa_end;
3483 (res + r)->flags = IORESOURCE_MEM;
3484 r++;
3485 }
3486 }
3487
3488 return r;
3489}
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res)
3502{
3503 int i, sdma_reqs_cnt;
3504 int r = 0;
3505
3506 sdma_reqs_cnt = _count_sdma_reqs(oh);
3507 for (i = 0; i < sdma_reqs_cnt; i++) {
3508 (res + r)->name = (oh->sdma_reqs + i)->name;
3509 (res + r)->start = (oh->sdma_reqs + i)->dma_req;
3510 (res + r)->end = (oh->sdma_reqs + i)->dma_req;
3511 (res + r)->flags = IORESOURCE_DMA;
3512 r++;
3513 }
3514
3515 return r;
3516}
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
3541 const char *name, struct resource *rsrc)
3542{
3543 int r;
3544 unsigned int irq, dma;
3545 u32 pa_start, pa_end;
3546
3547 if (!oh || !rsrc)
3548 return -EINVAL;
3549
3550 if (type == IORESOURCE_IRQ) {
3551 r = _get_mpu_irq_by_name(oh, name, &irq);
3552 if (r)
3553 return r;
3554
3555 rsrc->start = irq;
3556 rsrc->end = irq;
3557 } else if (type == IORESOURCE_DMA) {
3558 r = _get_sdma_req_by_name(oh, name, &dma);
3559 if (r)
3560 return r;
3561
3562 rsrc->start = dma;
3563 rsrc->end = dma;
3564 } else if (type == IORESOURCE_MEM) {
3565 r = _get_addr_space_by_name(oh, name, &pa_start, &pa_end);
3566 if (r)
3567 return r;
3568
3569 rsrc->start = pa_start;
3570 rsrc->end = pa_end;
3571 } else {
3572 return -EINVAL;
3573 }
3574
3575 rsrc->flags = type;
3576 rsrc->name = name;
3577
3578 return 0;
3579}
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
3593{
3594 struct clk *c;
3595 struct omap_hwmod_ocp_if *oi;
3596 struct clockdomain *clkdm;
3597 struct clk_hw_omap *clk;
3598
3599 if (!oh)
3600 return NULL;
3601
3602 if (oh->clkdm)
3603 return oh->clkdm->pwrdm.ptr;
3604
3605 if (oh->_clk) {
3606 c = oh->_clk;
3607 } else {
3608 oi = _find_mpu_rt_port(oh);
3609 if (!oi)
3610 return NULL;
3611 c = oi->_clk;
3612 }
3613
3614 clk = to_clk_hw_omap(__clk_get_hw(c));
3615 clkdm = clk->clkdm;
3616 if (!clkdm)
3617 return NULL;
3618
3619 return clkdm->pwrdm.ptr;
3620}
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
3632{
3633 if (!oh)
3634 return NULL;
3635
3636 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
3637 return NULL;
3638
3639 if (oh->_state == _HWMOD_STATE_UNKNOWN)
3640 return NULL;
3641
3642 return oh->_mpu_rt_va;
3643}
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
3664{
3665 unsigned long flags;
3666 u32 v;
3667
3668 spin_lock_irqsave(&oh->_lock, flags);
3669
3670 if (oh->class->sysc &&
3671 (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
3672 v = oh->_sysc_cache;
3673 _enable_wakeup(oh, &v);
3674 _write_sysconfig(v, oh);
3675 }
3676
3677 _set_idle_ioring_wakeup(oh, true);
3678 spin_unlock_irqrestore(&oh->_lock, flags);
3679
3680 return 0;
3681}
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
3697{
3698 unsigned long flags;
3699 u32 v;
3700
3701 spin_lock_irqsave(&oh->_lock, flags);
3702
3703 if (oh->class->sysc &&
3704 (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
3705 v = oh->_sysc_cache;
3706 _disable_wakeup(oh, &v);
3707 _write_sysconfig(v, oh);
3708 }
3709
3710 _set_idle_ioring_wakeup(oh, false);
3711 spin_unlock_irqrestore(&oh->_lock, flags);
3712
3713 return 0;
3714}
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name)
3729{
3730 int ret;
3731 unsigned long flags;
3732
3733 if (!oh)
3734 return -EINVAL;
3735
3736 spin_lock_irqsave(&oh->_lock, flags);
3737 ret = _assert_hardreset(oh, name);
3738 spin_unlock_irqrestore(&oh->_lock, flags);
3739
3740 return ret;
3741}
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name)
3756{
3757 int ret;
3758 unsigned long flags;
3759
3760 if (!oh)
3761 return -EINVAL;
3762
3763 spin_lock_irqsave(&oh->_lock, flags);
3764 ret = _deassert_hardreset(oh, name);
3765 spin_unlock_irqrestore(&oh->_lock, flags);
3766
3767 return ret;
3768}
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782int omap_hwmod_for_each_by_class(const char *classname,
3783 int (*fn)(struct omap_hwmod *oh,
3784 void *user),
3785 void *user)
3786{
3787 struct omap_hwmod *temp_oh;
3788 int ret = 0;
3789
3790 if (!classname || !fn)
3791 return -EINVAL;
3792
3793 pr_debug("omap_hwmod: %s: looking for modules of class %s\n",
3794 __func__, classname);
3795
3796 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
3797 if (!strcmp(temp_oh->class->name, classname)) {
3798 pr_debug("omap_hwmod: %s: %s: calling callback fn\n",
3799 __func__, temp_oh->name);
3800 ret = (*fn)(temp_oh, user);
3801 if (ret)
3802 break;
3803 }
3804 }
3805
3806 if (ret)
3807 pr_debug("omap_hwmod: %s: iterator terminated early: %d\n",
3808 __func__, ret);
3809
3810 return ret;
3811}
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state)
3825{
3826 int ret;
3827 unsigned long flags;
3828
3829 if (!oh)
3830 return -EINVAL;
3831
3832 if (state != _HWMOD_STATE_DISABLED &&
3833 state != _HWMOD_STATE_ENABLED &&
3834 state != _HWMOD_STATE_IDLE)
3835 return -EINVAL;
3836
3837 spin_lock_irqsave(&oh->_lock, flags);
3838
3839 if (oh->_state != _HWMOD_STATE_REGISTERED) {
3840 ret = -EINVAL;
3841 goto ohsps_unlock;
3842 }
3843
3844 oh->_postsetup_state = state;
3845 ret = 0;
3846
3847ohsps_unlock:
3848 spin_unlock_irqrestore(&oh->_lock, flags);
3849
3850 return ret;
3851}
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
3865{
3866 struct powerdomain *pwrdm;
3867 int ret = 0;
3868
3869 if (soc_ops.get_context_lost)
3870 return soc_ops.get_context_lost(oh);
3871
3872 pwrdm = omap_hwmod_get_pwrdm(oh);
3873 if (pwrdm)
3874 ret = pwrdm_get_context_loss_count(pwrdm);
3875
3876 return ret;
3877}
3878
3879
3880
3881
3882
3883
3884
3885
3886void __init omap_hwmod_init(void)
3887{
3888 if (cpu_is_omap24xx()) {
3889 soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready;
3890 soc_ops.assert_hardreset = _omap2_assert_hardreset;
3891 soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
3892 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
3893 } else if (cpu_is_omap34xx()) {
3894 soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready;
3895 soc_ops.assert_hardreset = _omap2_assert_hardreset;
3896 soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
3897 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
3898 soc_ops.init_clkdm = _init_clkdm;
3899 } else if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) {
3900 soc_ops.enable_module = _omap4_enable_module;
3901 soc_ops.disable_module = _omap4_disable_module;
3902 soc_ops.wait_target_ready = _omap4_wait_target_ready;
3903 soc_ops.assert_hardreset = _omap4_assert_hardreset;
3904 soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
3905 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
3906 soc_ops.init_clkdm = _init_clkdm;
3907 soc_ops.update_context_lost = _omap4_update_context_lost;
3908 soc_ops.get_context_lost = _omap4_get_context_lost;
3909 } else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() ||
3910 soc_is_am43xx()) {
3911 soc_ops.enable_module = _omap4_enable_module;
3912 soc_ops.disable_module = _omap4_disable_module;
3913 soc_ops.wait_target_ready = _omap4_wait_target_ready;
3914 soc_ops.assert_hardreset = _omap4_assert_hardreset;
3915 soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
3916 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
3917 soc_ops.init_clkdm = _init_clkdm;
3918 } else {
3919 WARN(1, "omap_hwmod: unknown SoC type\n");
3920 }
3921
3922 inited = true;
3923}
3924
3925
3926
3927
3928
3929
3930
3931
3932const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh)
3933{
3934 if (!oh)
3935 return NULL;
3936
3937 return oh->main_clk;
3938}
3939