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