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