diff options
author | Rajendra Nayak <rnayak@ti.com> | 2010-12-21 22:01:19 -0500 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2010-12-21 22:01:19 -0500 |
commit | 9b7fc907d9378f86eb6b823bbe84ec9ed584b091 (patch) | |
tree | b4519c2eb01d58ca4a407048bcb3fd83cf846e1f /arch/arm/mach-omap2 | |
parent | 12627578523d2d9396cae76b1dad0ed3dccf1730 (diff) |
OMAP: powerdomain: Arch specific funcs for mem control
Define the following architecture specific funtions for omap2/3/4
.pwrdm_set_mem_onst
.pwrdm_set_mem_retst
.pwrdm_read_mem_pwrst
.pwrdm_read_prev_mem_pwrst
.pwrdm_read_mem_retst
.pwrdm_clear_all_prev_pwrst
.pwrdm_enable_hdwr_sar
.pwrdm_disable_hdwr_sar
.pwrdm_wait_transition
.pwrdm_set_lowpwrstchange
Convert the platform-independent framework to call these functions.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
[paul@pwsan.com: rearranged Makefile changes]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Reviewed-by: Kevin Hilman <khilman@deeprootsystems.com>
Tested-by: Kevin Hilman <khilman@deeprootsystems.com>
Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/powerdomain-common.c | 111 | ||||
-rw-r--r-- | arch/arm/mach-omap2/powerdomain.c | 303 | ||||
-rw-r--r-- | arch/arm/mach-omap2/powerdomain2xxx_3xxx.c | 131 | ||||
-rw-r--r-- | arch/arm/mach-omap2/powerdomain44xx.c | 85 | ||||
-rw-r--r-- | arch/arm/mach-omap2/powerdomains.h | 5 |
6 files changed, 389 insertions, 248 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index c43948c8d543..1a1e978cd4bf 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -78,7 +78,7 @@ obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm.o | |||
78 | obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm4xxx.o | 78 | obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm4xxx.o |
79 | 79 | ||
80 | # OMAP powerdomain framework | 80 | # OMAP powerdomain framework |
81 | powerdomain-common += powerdomain.o powerdomains_data.o | 81 | powerdomain-common += powerdomain.o powerdomains_data.o powerdomain-common.o |
82 | obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common) \ | 82 | obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common) \ |
83 | powerdomain2xxx_3xxx.o | 83 | powerdomain2xxx_3xxx.o |
84 | obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common) \ | 84 | obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common) \ |
diff --git a/arch/arm/mach-omap2/powerdomain-common.c b/arch/arm/mach-omap2/powerdomain-common.c new file mode 100644 index 000000000000..cb01c7a3689a --- /dev/null +++ b/arch/arm/mach-omap2/powerdomain-common.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/powerdomain-common.c | ||
3 | * Contains common powerdomain framework functions | ||
4 | * | ||
5 | * Copyright (C) 2010 Texas Instruments, Inc. | ||
6 | * Copyright (C) 2010 Nokia Corporation | ||
7 | * | ||
8 | * Derived from mach-omap2/powerdomain.c written by Paul Walmsley | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/errno.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include "pm.h" | ||
18 | #include "cm.h" | ||
19 | #include "cm-regbits-34xx.h" | ||
20 | #include "cm-regbits-44xx.h" | ||
21 | #include "prm-regbits-34xx.h" | ||
22 | #include "prm-regbits-44xx.h" | ||
23 | #include "powerdomains.h" | ||
24 | |||
25 | /* | ||
26 | * OMAP3 and OMAP4 specific register bit initialisations | ||
27 | * Notice that the names here are not according to each power | ||
28 | * domain but the bit mapping used applies to all of them | ||
29 | */ | ||
30 | /* OMAP3 and OMAP4 Memory Onstate Masks (common across all power domains) */ | ||
31 | #define OMAP_MEM0_ONSTATE_MASK OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK | ||
32 | #define OMAP_MEM1_ONSTATE_MASK OMAP3430_L1FLATMEMONSTATE_MASK | ||
33 | #define OMAP_MEM2_ONSTATE_MASK OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK | ||
34 | #define OMAP_MEM3_ONSTATE_MASK OMAP3430_L2FLATMEMONSTATE_MASK | ||
35 | #define OMAP_MEM4_ONSTATE_MASK OMAP4430_OCP_NRET_BANK_ONSTATE_MASK | ||
36 | |||
37 | /* OMAP3 and OMAP4 Memory Retstate Masks (common across all power domains) */ | ||
38 | #define OMAP_MEM0_RETSTATE_MASK OMAP3430_SHAREDL1CACHEFLATRETSTATE_MASK | ||
39 | #define OMAP_MEM1_RETSTATE_MASK OMAP3430_L1FLATMEMRETSTATE_MASK | ||
40 | #define OMAP_MEM2_RETSTATE_MASK OMAP3430_SHAREDL2CACHEFLATRETSTATE_MASK | ||
41 | #define OMAP_MEM3_RETSTATE_MASK OMAP3430_L2FLATMEMRETSTATE_MASK | ||
42 | #define OMAP_MEM4_RETSTATE_MASK OMAP4430_OCP_NRET_BANK_RETSTATE_MASK | ||
43 | |||
44 | /* OMAP3 and OMAP4 Memory Status bits */ | ||
45 | #define OMAP_MEM0_STATEST_MASK OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK | ||
46 | #define OMAP_MEM1_STATEST_MASK OMAP3430_L1FLATMEMSTATEST_MASK | ||
47 | #define OMAP_MEM2_STATEST_MASK OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK | ||
48 | #define OMAP_MEM3_STATEST_MASK OMAP3430_L2FLATMEMSTATEST_MASK | ||
49 | #define OMAP_MEM4_STATEST_MASK OMAP4430_OCP_NRET_BANK_STATEST_MASK | ||
50 | |||
51 | /* Common Internal functions used across OMAP rev's*/ | ||
52 | u32 omap2_pwrdm_get_mem_bank_onstate_mask(u8 bank) | ||
53 | { | ||
54 | switch (bank) { | ||
55 | case 0: | ||
56 | return OMAP_MEM0_ONSTATE_MASK; | ||
57 | case 1: | ||
58 | return OMAP_MEM1_ONSTATE_MASK; | ||
59 | case 2: | ||
60 | return OMAP_MEM2_ONSTATE_MASK; | ||
61 | case 3: | ||
62 | return OMAP_MEM3_ONSTATE_MASK; | ||
63 | case 4: | ||
64 | return OMAP_MEM4_ONSTATE_MASK; | ||
65 | default: | ||
66 | WARN_ON(1); /* should never happen */ | ||
67 | return -EEXIST; | ||
68 | } | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | u32 omap2_pwrdm_get_mem_bank_retst_mask(u8 bank) | ||
73 | { | ||
74 | switch (bank) { | ||
75 | case 0: | ||
76 | return OMAP_MEM0_RETSTATE_MASK; | ||
77 | case 1: | ||
78 | return OMAP_MEM1_RETSTATE_MASK; | ||
79 | case 2: | ||
80 | return OMAP_MEM2_RETSTATE_MASK; | ||
81 | case 3: | ||
82 | return OMAP_MEM3_RETSTATE_MASK; | ||
83 | case 4: | ||
84 | return OMAP_MEM4_RETSTATE_MASK; | ||
85 | default: | ||
86 | WARN_ON(1); /* should never happen */ | ||
87 | return -EEXIST; | ||
88 | } | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank) | ||
93 | { | ||
94 | switch (bank) { | ||
95 | case 0: | ||
96 | return OMAP_MEM0_STATEST_MASK; | ||
97 | case 1: | ||
98 | return OMAP_MEM1_STATEST_MASK; | ||
99 | case 2: | ||
100 | return OMAP_MEM2_STATEST_MASK; | ||
101 | case 3: | ||
102 | return OMAP_MEM3_STATEST_MASK; | ||
103 | case 4: | ||
104 | return OMAP_MEM4_STATEST_MASK; | ||
105 | default: | ||
106 | WARN_ON(1); /* should never happen */ | ||
107 | return -EEXIST; | ||
108 | } | ||
109 | return 0; | ||
110 | } | ||
111 | |||
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 562a3fe9db5b..620672135768 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c | |||
@@ -15,23 +15,10 @@ | |||
15 | #undef DEBUG | 15 | #undef DEBUG |
16 | 16 | ||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | ||
19 | #include <linux/types.h> | 18 | #include <linux/types.h> |
20 | #include <linux/delay.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/list.h> | 19 | #include <linux/list.h> |
23 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
24 | #include <linux/err.h> | 21 | #include <linux/string.h> |
25 | #include <linux/io.h> | ||
26 | |||
27 | #include <asm/atomic.h> | ||
28 | |||
29 | #include "cm.h" | ||
30 | #include "cm-regbits-34xx.h" | ||
31 | #include "cm-regbits-44xx.h" | ||
32 | #include "prm.h" | ||
33 | #include "prm-regbits-34xx.h" | ||
34 | #include "prm-regbits-44xx.h" | ||
35 | 22 | ||
36 | #include <plat/cpu.h> | 23 | #include <plat/cpu.h> |
37 | #include <plat/powerdomain.h> | 24 | #include <plat/powerdomain.h> |
@@ -45,37 +32,6 @@ enum { | |||
45 | PWRDM_STATE_PREV, | 32 | PWRDM_STATE_PREV, |
46 | }; | 33 | }; |
47 | 34 | ||
48 | /* Variable holding value of the CPU dependent PWRSTCTRL Register Offset */ | ||
49 | static u16 pwrstctrl_reg_offs; | ||
50 | |||
51 | /* Variable holding value of the CPU dependent PWRSTST Register Offset */ | ||
52 | static u16 pwrstst_reg_offs; | ||
53 | |||
54 | /* OMAP3 and OMAP4 specific register bit initialisations | ||
55 | * Notice that the names here are not according to each power | ||
56 | * domain but the bit mapping used applies to all of them | ||
57 | */ | ||
58 | |||
59 | /* OMAP3 and OMAP4 Memory Onstate Masks (common across all power domains) */ | ||
60 | #define OMAP_MEM0_ONSTATE_MASK OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK | ||
61 | #define OMAP_MEM1_ONSTATE_MASK OMAP3430_L1FLATMEMONSTATE_MASK | ||
62 | #define OMAP_MEM2_ONSTATE_MASK OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK | ||
63 | #define OMAP_MEM3_ONSTATE_MASK OMAP3430_L2FLATMEMONSTATE_MASK | ||
64 | #define OMAP_MEM4_ONSTATE_MASK OMAP4430_OCP_NRET_BANK_ONSTATE_MASK | ||
65 | |||
66 | /* OMAP3 and OMAP4 Memory Retstate Masks (common across all power domains) */ | ||
67 | #define OMAP_MEM0_RETSTATE_MASK OMAP3430_SHAREDL1CACHEFLATRETSTATE_MASK | ||
68 | #define OMAP_MEM1_RETSTATE_MASK OMAP3430_L1FLATMEMRETSTATE_MASK | ||
69 | #define OMAP_MEM2_RETSTATE_MASK OMAP3430_SHAREDL2CACHEFLATRETSTATE_MASK | ||
70 | #define OMAP_MEM3_RETSTATE_MASK OMAP3430_L2FLATMEMRETSTATE_MASK | ||
71 | #define OMAP_MEM4_RETSTATE_MASK OMAP4430_OCP_NRET_BANK_RETSTATE_MASK | ||
72 | |||
73 | /* OMAP3 and OMAP4 Memory Status bits */ | ||
74 | #define OMAP_MEM0_STATEST_MASK OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK | ||
75 | #define OMAP_MEM1_STATEST_MASK OMAP3430_L1FLATMEMSTATEST_MASK | ||
76 | #define OMAP_MEM2_STATEST_MASK OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK | ||
77 | #define OMAP_MEM3_STATEST_MASK OMAP3430_L2FLATMEMSTATEST_MASK | ||
78 | #define OMAP_MEM4_STATEST_MASK OMAP4430_OCP_NRET_BANK_STATEST_MASK | ||
79 | 35 | ||
80 | /* pwrdm_list contains all registered struct powerdomains */ | 36 | /* pwrdm_list contains all registered struct powerdomains */ |
81 | static LIST_HEAD(pwrdm_list); | 37 | static LIST_HEAD(pwrdm_list); |
@@ -225,18 +181,6 @@ void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs) | |||
225 | { | 181 | { |
226 | struct powerdomain **p = NULL; | 182 | struct powerdomain **p = NULL; |
227 | 183 | ||
228 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | ||
229 | pwrstctrl_reg_offs = OMAP2_PM_PWSTCTRL; | ||
230 | pwrstst_reg_offs = OMAP2_PM_PWSTST; | ||
231 | } else if (cpu_is_omap44xx()) { | ||
232 | pwrstctrl_reg_offs = OMAP4_PM_PWSTCTRL; | ||
233 | pwrstst_reg_offs = OMAP4_PM_PWSTST; | ||
234 | } else { | ||
235 | printk(KERN_ERR "Power Domain struct not supported for " \ | ||
236 | "this CPU\n"); | ||
237 | return; | ||
238 | } | ||
239 | |||
240 | if (!custom_funcs) | 184 | if (!custom_funcs) |
241 | WARN(1, "powerdomain: No custom pwrdm functions registered\n"); | 185 | WARN(1, "powerdomain: No custom pwrdm functions registered\n"); |
242 | else | 186 | else |
@@ -566,7 +510,7 @@ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) | |||
566 | */ | 510 | */ |
567 | int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) | 511 | int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) |
568 | { | 512 | { |
569 | u32 m; | 513 | int ret = -EINVAL; |
570 | 514 | ||
571 | if (!pwrdm) | 515 | if (!pwrdm) |
572 | return -EINVAL; | 516 | return -EINVAL; |
@@ -580,37 +524,10 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) | |||
580 | pr_debug("powerdomain: setting next memory powerstate for domain %s " | 524 | pr_debug("powerdomain: setting next memory powerstate for domain %s " |
581 | "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst); | 525 | "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst); |
582 | 526 | ||
583 | /* | 527 | if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst) |
584 | * The register bit names below may not correspond to the | 528 | ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst); |
585 | * actual names of the bits in each powerdomain's register, | ||
586 | * but the type of value returned is the same for each | ||
587 | * powerdomain. | ||
588 | */ | ||
589 | switch (bank) { | ||
590 | case 0: | ||
591 | m = OMAP_MEM0_ONSTATE_MASK; | ||
592 | break; | ||
593 | case 1: | ||
594 | m = OMAP_MEM1_ONSTATE_MASK; | ||
595 | break; | ||
596 | case 2: | ||
597 | m = OMAP_MEM2_ONSTATE_MASK; | ||
598 | break; | ||
599 | case 3: | ||
600 | m = OMAP_MEM3_ONSTATE_MASK; | ||
601 | break; | ||
602 | case 4: | ||
603 | m = OMAP_MEM4_ONSTATE_MASK; | ||
604 | break; | ||
605 | default: | ||
606 | WARN_ON(1); /* should never happen */ | ||
607 | return -EEXIST; | ||
608 | } | ||
609 | |||
610 | prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), | ||
611 | pwrdm->prcm_offs, pwrstctrl_reg_offs); | ||
612 | 529 | ||
613 | return 0; | 530 | return ret; |
614 | } | 531 | } |
615 | 532 | ||
616 | /** | 533 | /** |
@@ -631,7 +548,7 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) | |||
631 | */ | 548 | */ |
632 | int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) | 549 | int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) |
633 | { | 550 | { |
634 | u32 m; | 551 | int ret = -EINVAL; |
635 | 552 | ||
636 | if (!pwrdm) | 553 | if (!pwrdm) |
637 | return -EINVAL; | 554 | return -EINVAL; |
@@ -645,37 +562,10 @@ int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) | |||
645 | pr_debug("powerdomain: setting next memory powerstate for domain %s " | 562 | pr_debug("powerdomain: setting next memory powerstate for domain %s " |
646 | "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst); | 563 | "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst); |
647 | 564 | ||
648 | /* | 565 | if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst) |
649 | * The register bit names below may not correspond to the | 566 | ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst); |
650 | * actual names of the bits in each powerdomain's register, | ||
651 | * but the type of value returned is the same for each | ||
652 | * powerdomain. | ||
653 | */ | ||
654 | switch (bank) { | ||
655 | case 0: | ||
656 | m = OMAP_MEM0_RETSTATE_MASK; | ||
657 | break; | ||
658 | case 1: | ||
659 | m = OMAP_MEM1_RETSTATE_MASK; | ||
660 | break; | ||
661 | case 2: | ||
662 | m = OMAP_MEM2_RETSTATE_MASK; | ||
663 | break; | ||
664 | case 3: | ||
665 | m = OMAP_MEM3_RETSTATE_MASK; | ||
666 | break; | ||
667 | case 4: | ||
668 | m = OMAP_MEM4_RETSTATE_MASK; | ||
669 | break; | ||
670 | default: | ||
671 | WARN_ON(1); /* should never happen */ | ||
672 | return -EEXIST; | ||
673 | } | ||
674 | |||
675 | prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, | ||
676 | pwrstctrl_reg_offs); | ||
677 | 567 | ||
678 | return 0; | 568 | return ret; |
679 | } | 569 | } |
680 | 570 | ||
681 | /** | 571 | /** |
@@ -754,46 +644,21 @@ int pwrdm_read_logic_retst(struct powerdomain *pwrdm) | |||
754 | */ | 644 | */ |
755 | int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) | 645 | int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) |
756 | { | 646 | { |
757 | u32 m; | 647 | int ret = -EINVAL; |
758 | 648 | ||
759 | if (!pwrdm) | 649 | if (!pwrdm) |
760 | return -EINVAL; | 650 | return ret; |
761 | 651 | ||
762 | if (pwrdm->banks < (bank + 1)) | 652 | if (pwrdm->banks < (bank + 1)) |
763 | return -EEXIST; | 653 | return ret; |
764 | 654 | ||
765 | if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK) | 655 | if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK) |
766 | bank = 1; | 656 | bank = 1; |
767 | 657 | ||
768 | /* | 658 | if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_pwrst) |
769 | * The register bit names below may not correspond to the | 659 | ret = arch_pwrdm->pwrdm_read_mem_pwrst(pwrdm, bank); |
770 | * actual names of the bits in each powerdomain's register, | ||
771 | * but the type of value returned is the same for each | ||
772 | * powerdomain. | ||
773 | */ | ||
774 | switch (bank) { | ||
775 | case 0: | ||
776 | m = OMAP_MEM0_STATEST_MASK; | ||
777 | break; | ||
778 | case 1: | ||
779 | m = OMAP_MEM1_STATEST_MASK; | ||
780 | break; | ||
781 | case 2: | ||
782 | m = OMAP_MEM2_STATEST_MASK; | ||
783 | break; | ||
784 | case 3: | ||
785 | m = OMAP_MEM3_STATEST_MASK; | ||
786 | break; | ||
787 | case 4: | ||
788 | m = OMAP_MEM4_STATEST_MASK; | ||
789 | break; | ||
790 | default: | ||
791 | WARN_ON(1); /* should never happen */ | ||
792 | return -EEXIST; | ||
793 | } | ||
794 | 660 | ||
795 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, | 661 | return ret; |
796 | pwrstst_reg_offs, m); | ||
797 | } | 662 | } |
798 | 663 | ||
799 | /** | 664 | /** |
@@ -809,43 +674,21 @@ int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) | |||
809 | */ | 674 | */ |
810 | int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) | 675 | int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) |
811 | { | 676 | { |
812 | u32 m; | 677 | int ret = -EINVAL; |
813 | 678 | ||
814 | if (!pwrdm) | 679 | if (!pwrdm) |
815 | return -EINVAL; | 680 | return ret; |
816 | 681 | ||
817 | if (pwrdm->banks < (bank + 1)) | 682 | if (pwrdm->banks < (bank + 1)) |
818 | return -EEXIST; | 683 | return ret; |
819 | 684 | ||
820 | if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK) | 685 | if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK) |
821 | bank = 1; | 686 | bank = 1; |
822 | 687 | ||
823 | /* | 688 | if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_mem_pwrst) |
824 | * The register bit names below may not correspond to the | 689 | ret = arch_pwrdm->pwrdm_read_prev_mem_pwrst(pwrdm, bank); |
825 | * actual names of the bits in each powerdomain's register, | ||
826 | * but the type of value returned is the same for each | ||
827 | * powerdomain. | ||
828 | */ | ||
829 | switch (bank) { | ||
830 | case 0: | ||
831 | m = OMAP3430_LASTMEM1STATEENTERED_MASK; | ||
832 | break; | ||
833 | case 1: | ||
834 | m = OMAP3430_LASTMEM2STATEENTERED_MASK; | ||
835 | break; | ||
836 | case 2: | ||
837 | m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK; | ||
838 | break; | ||
839 | case 3: | ||
840 | m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK; | ||
841 | break; | ||
842 | default: | ||
843 | WARN_ON(1); /* should never happen */ | ||
844 | return -EEXIST; | ||
845 | } | ||
846 | 690 | ||
847 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, | 691 | return ret; |
848 | OMAP3430_PM_PREPWSTST, m); | ||
849 | } | 692 | } |
850 | 693 | ||
851 | /** | 694 | /** |
@@ -860,43 +703,18 @@ int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) | |||
860 | */ | 703 | */ |
861 | int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) | 704 | int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) |
862 | { | 705 | { |
863 | u32 m; | 706 | int ret = -EINVAL; |
864 | 707 | ||
865 | if (!pwrdm) | 708 | if (!pwrdm) |
866 | return -EINVAL; | 709 | return ret; |
867 | 710 | ||
868 | if (pwrdm->banks < (bank + 1)) | 711 | if (pwrdm->banks < (bank + 1)) |
869 | return -EEXIST; | 712 | return ret; |
870 | 713 | ||
871 | /* | 714 | if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst) |
872 | * The register bit names below may not correspond to the | 715 | ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank); |
873 | * actual names of the bits in each powerdomain's register, | ||
874 | * but the type of value returned is the same for each | ||
875 | * powerdomain. | ||
876 | */ | ||
877 | switch (bank) { | ||
878 | case 0: | ||
879 | m = OMAP_MEM0_RETSTATE_MASK; | ||
880 | break; | ||
881 | case 1: | ||
882 | m = OMAP_MEM1_RETSTATE_MASK; | ||
883 | break; | ||
884 | case 2: | ||
885 | m = OMAP_MEM2_RETSTATE_MASK; | ||
886 | break; | ||
887 | case 3: | ||
888 | m = OMAP_MEM3_RETSTATE_MASK; | ||
889 | break; | ||
890 | case 4: | ||
891 | m = OMAP_MEM4_RETSTATE_MASK; | ||
892 | break; | ||
893 | default: | ||
894 | WARN_ON(1); /* should never happen */ | ||
895 | return -EEXIST; | ||
896 | } | ||
897 | 716 | ||
898 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, | 717 | return ret; |
899 | pwrstctrl_reg_offs, m); | ||
900 | } | 718 | } |
901 | 719 | ||
902 | /** | 720 | /** |
@@ -910,8 +728,10 @@ int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) | |||
910 | */ | 728 | */ |
911 | int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) | 729 | int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) |
912 | { | 730 | { |
731 | int ret = -EINVAL; | ||
732 | |||
913 | if (!pwrdm) | 733 | if (!pwrdm) |
914 | return -EINVAL; | 734 | return ret; |
915 | 735 | ||
916 | /* | 736 | /* |
917 | * XXX should get the powerdomain's current state here; | 737 | * XXX should get the powerdomain's current state here; |
@@ -921,9 +741,10 @@ int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) | |||
921 | pr_debug("powerdomain: clearing previous power state reg for %s\n", | 741 | pr_debug("powerdomain: clearing previous power state reg for %s\n", |
922 | pwrdm->name); | 742 | pwrdm->name); |
923 | 743 | ||
924 | prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST); | 744 | if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst) |
745 | ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm); | ||
925 | 746 | ||
926 | return 0; | 747 | return ret; |
927 | } | 748 | } |
928 | 749 | ||
929 | /** | 750 | /** |
@@ -939,19 +760,21 @@ int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) | |||
939 | */ | 760 | */ |
940 | int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) | 761 | int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) |
941 | { | 762 | { |
763 | int ret = -EINVAL; | ||
764 | |||
942 | if (!pwrdm) | 765 | if (!pwrdm) |
943 | return -EINVAL; | 766 | return ret; |
944 | 767 | ||
945 | if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) | 768 | if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) |
946 | return -EINVAL; | 769 | return ret; |
947 | 770 | ||
948 | pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", | 771 | pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", |
949 | pwrdm->name); | 772 | pwrdm->name); |
950 | 773 | ||
951 | prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, | 774 | if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar) |
952 | pwrdm->prcm_offs, pwrstctrl_reg_offs); | 775 | ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm); |
953 | 776 | ||
954 | return 0; | 777 | return ret; |
955 | } | 778 | } |
956 | 779 | ||
957 | /** | 780 | /** |
@@ -967,19 +790,21 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) | |||
967 | */ | 790 | */ |
968 | int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) | 791 | int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) |
969 | { | 792 | { |
793 | int ret = -EINVAL; | ||
794 | |||
970 | if (!pwrdm) | 795 | if (!pwrdm) |
971 | return -EINVAL; | 796 | return ret; |
972 | 797 | ||
973 | if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) | 798 | if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) |
974 | return -EINVAL; | 799 | return ret; |
975 | 800 | ||
976 | pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", | 801 | pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", |
977 | pwrdm->name); | 802 | pwrdm->name); |
978 | 803 | ||
979 | prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0, | 804 | if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar) |
980 | pwrdm->prcm_offs, pwrstctrl_reg_offs); | 805 | ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm); |
981 | 806 | ||
982 | return 0; | 807 | return ret; |
983 | } | 808 | } |
984 | 809 | ||
985 | /** | 810 | /** |
@@ -1006,6 +831,8 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) | |||
1006 | */ | 831 | */ |
1007 | int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) | 832 | int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) |
1008 | { | 833 | { |
834 | int ret = -EINVAL; | ||
835 | |||
1009 | if (!pwrdm) | 836 | if (!pwrdm) |
1010 | return -EINVAL; | 837 | return -EINVAL; |
1011 | 838 | ||
@@ -1015,11 +842,10 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) | |||
1015 | pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n", | 842 | pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n", |
1016 | pwrdm->name); | 843 | pwrdm->name); |
1017 | 844 | ||
1018 | prm_rmw_mod_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK, | 845 | if (arch_pwrdm && arch_pwrdm->pwrdm_set_lowpwrstchange) |
1019 | (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT), | 846 | ret = arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm); |
1020 | pwrdm->prcm_offs, pwrstctrl_reg_offs); | ||
1021 | 847 | ||
1022 | return 0; | 848 | return ret; |
1023 | } | 849 | } |
1024 | 850 | ||
1025 | /** | 851 | /** |
@@ -1034,32 +860,15 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) | |||
1034 | */ | 860 | */ |
1035 | int pwrdm_wait_transition(struct powerdomain *pwrdm) | 861 | int pwrdm_wait_transition(struct powerdomain *pwrdm) |
1036 | { | 862 | { |
1037 | u32 c = 0; | 863 | int ret = -EINVAL; |
1038 | 864 | ||
1039 | if (!pwrdm) | 865 | if (!pwrdm) |
1040 | return -EINVAL; | 866 | return -EINVAL; |
1041 | 867 | ||
1042 | /* | 868 | if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition) |
1043 | * REVISIT: pwrdm_wait_transition() may be better implemented | 869 | ret = arch_pwrdm->pwrdm_wait_transition(pwrdm); |
1044 | * via a callback and a periodic timer check -- how long do we expect | ||
1045 | * powerdomain transitions to take? | ||
1046 | */ | ||
1047 | 870 | ||
1048 | /* XXX Is this udelay() value meaningful? */ | 871 | return ret; |
1049 | while ((prm_read_mod_reg(pwrdm->prcm_offs, pwrstst_reg_offs) & | ||
1050 | OMAP_INTRANSITION_MASK) && | ||
1051 | (c++ < PWRDM_TRANSITION_BAILOUT)) | ||
1052 | udelay(1); | ||
1053 | |||
1054 | if (c > PWRDM_TRANSITION_BAILOUT) { | ||
1055 | printk(KERN_ERR "powerdomain: waited too long for " | ||
1056 | "powerdomain %s to complete transition\n", pwrdm->name); | ||
1057 | return -EAGAIN; | ||
1058 | } | ||
1059 | |||
1060 | pr_debug("powerdomain: completed transition in %d loops\n", c); | ||
1061 | |||
1062 | return 0; | ||
1063 | } | 872 | } |
1064 | 873 | ||
1065 | int pwrdm_state_switch(struct powerdomain *pwrdm) | 874 | int pwrdm_state_switch(struct powerdomain *pwrdm) |
diff --git a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c index b7ea191539e5..6cdf67860cb3 100644 --- a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c +++ b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c | |||
@@ -41,6 +41,50 @@ static int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm) | |||
41 | OMAP2_PM_PWSTST, OMAP_POWERSTATEST_MASK); | 41 | OMAP2_PM_PWSTST, OMAP_POWERSTATEST_MASK); |
42 | } | 42 | } |
43 | 43 | ||
44 | static int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, | ||
45 | u8 pwrst) | ||
46 | { | ||
47 | u32 m; | ||
48 | |||
49 | m = omap2_pwrdm_get_mem_bank_onstate_mask(bank); | ||
50 | |||
51 | prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, | ||
52 | OMAP2_PM_PWSTCTRL); | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, | ||
58 | u8 pwrst) | ||
59 | { | ||
60 | u32 m; | ||
61 | |||
62 | m = omap2_pwrdm_get_mem_bank_retst_mask(bank); | ||
63 | |||
64 | prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, | ||
65 | OMAP2_PM_PWSTCTRL); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) | ||
71 | { | ||
72 | u32 m; | ||
73 | |||
74 | m = omap2_pwrdm_get_mem_bank_stst_mask(bank); | ||
75 | |||
76 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTST, m); | ||
77 | } | ||
78 | |||
79 | static int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) | ||
80 | { | ||
81 | u32 m; | ||
82 | |||
83 | m = omap2_pwrdm_get_mem_bank_retst_mask(bank); | ||
84 | |||
85 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL, m); | ||
86 | } | ||
87 | |||
44 | static int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) | 88 | static int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) |
45 | { | 89 | { |
46 | u32 v; | 90 | u32 v; |
@@ -52,6 +96,33 @@ static int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) | |||
52 | return 0; | 96 | return 0; |
53 | } | 97 | } |
54 | 98 | ||
99 | static int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm) | ||
100 | { | ||
101 | u32 c = 0; | ||
102 | |||
103 | /* | ||
104 | * REVISIT: pwrdm_wait_transition() may be better implemented | ||
105 | * via a callback and a periodic timer check -- how long do we expect | ||
106 | * powerdomain transitions to take? | ||
107 | */ | ||
108 | |||
109 | /* XXX Is this udelay() value meaningful? */ | ||
110 | while ((prm_read_mod_reg(pwrdm->prcm_offs, OMAP2_PM_PWSTST) & | ||
111 | OMAP_INTRANSITION_MASK) && | ||
112 | (c++ < PWRDM_TRANSITION_BAILOUT)) | ||
113 | udelay(1); | ||
114 | |||
115 | if (c > PWRDM_TRANSITION_BAILOUT) { | ||
116 | printk(KERN_ERR "powerdomain: waited too long for " | ||
117 | "powerdomain %s to complete transition\n", pwrdm->name); | ||
118 | return -EAGAIN; | ||
119 | } | ||
120 | |||
121 | pr_debug("powerdomain: completed transition in %d loops\n", c); | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
55 | /* Applicable only for OMAP3. Not supported on OMAP2 */ | 126 | /* Applicable only for OMAP3. Not supported on OMAP2 */ |
56 | static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) | 127 | static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) |
57 | { | 128 | { |
@@ -77,11 +148,62 @@ static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) | |||
77 | OMAP3430_LASTLOGICSTATEENTERED_MASK); | 148 | OMAP3430_LASTLOGICSTATEENTERED_MASK); |
78 | } | 149 | } |
79 | 150 | ||
151 | static int omap3_get_mem_bank_lastmemst_mask(u8 bank) | ||
152 | { | ||
153 | switch (bank) { | ||
154 | case 0: | ||
155 | return OMAP3430_LASTMEM1STATEENTERED_MASK; | ||
156 | case 1: | ||
157 | return OMAP3430_LASTMEM2STATEENTERED_MASK; | ||
158 | case 2: | ||
159 | return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK; | ||
160 | case 3: | ||
161 | return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK; | ||
162 | default: | ||
163 | WARN_ON(1); /* should never happen */ | ||
164 | return -EEXIST; | ||
165 | } | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) | ||
170 | { | ||
171 | u32 m; | ||
172 | |||
173 | m = omap3_get_mem_bank_lastmemst_mask(bank); | ||
174 | |||
175 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, | ||
176 | OMAP3430_PM_PREPWSTST, m); | ||
177 | } | ||
178 | |||
179 | static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) | ||
180 | { | ||
181 | prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST); | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) | ||
186 | { | ||
187 | return prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, | ||
188 | pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL); | ||
189 | } | ||
190 | |||
191 | static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) | ||
192 | { | ||
193 | return prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0, | ||
194 | pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL); | ||
195 | } | ||
196 | |||
80 | struct pwrdm_ops omap2_pwrdm_operations = { | 197 | struct pwrdm_ops omap2_pwrdm_operations = { |
81 | .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst, | 198 | .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst, |
82 | .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst, | 199 | .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst, |
83 | .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst, | 200 | .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst, |
84 | .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst, | 201 | .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst, |
202 | .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst, | ||
203 | .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst, | ||
204 | .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst, | ||
205 | .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst, | ||
206 | .pwrdm_wait_transition = omap2_pwrdm_wait_transition, | ||
85 | }; | 207 | }; |
86 | 208 | ||
87 | struct pwrdm_ops omap3_pwrdm_operations = { | 209 | struct pwrdm_ops omap3_pwrdm_operations = { |
@@ -93,4 +215,13 @@ struct pwrdm_ops omap3_pwrdm_operations = { | |||
93 | .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst, | 215 | .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst, |
94 | .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst, | 216 | .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst, |
95 | .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst, | 217 | .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst, |
218 | .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst, | ||
219 | .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst, | ||
220 | .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst, | ||
221 | .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst, | ||
222 | .pwrdm_read_prev_mem_pwrst = omap3_pwrdm_read_prev_mem_pwrst, | ||
223 | .pwrdm_clear_all_prev_pwrst = omap3_pwrdm_clear_all_prev_pwrst, | ||
224 | .pwrdm_enable_hdwr_sar = omap3_pwrdm_enable_hdwr_sar, | ||
225 | .pwrdm_disable_hdwr_sar = omap3_pwrdm_disable_hdwr_sar, | ||
226 | .pwrdm_wait_transition = omap2_pwrdm_wait_transition, | ||
96 | }; | 227 | }; |
diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c index 996790acebc9..123a25f3b96f 100644 --- a/arch/arm/mach-omap2/powerdomain44xx.c +++ b/arch/arm/mach-omap2/powerdomain44xx.c | |||
@@ -47,6 +47,14 @@ static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) | |||
47 | OMAP4430_LASTPOWERSTATEENTERED_MASK); | 47 | OMAP4430_LASTPOWERSTATEENTERED_MASK); |
48 | } | 48 | } |
49 | 49 | ||
50 | static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) | ||
51 | { | ||
52 | prm_rmw_mod_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK, | ||
53 | (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT), | ||
54 | pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); | ||
55 | return 0; | ||
56 | } | ||
57 | |||
50 | static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) | 58 | static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) |
51 | { | 59 | { |
52 | u32 v; | 60 | u32 v; |
@@ -58,6 +66,32 @@ static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) | |||
58 | return 0; | 66 | return 0; |
59 | } | 67 | } |
60 | 68 | ||
69 | static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, | ||
70 | u8 pwrst) | ||
71 | { | ||
72 | u32 m; | ||
73 | |||
74 | m = omap2_pwrdm_get_mem_bank_onstate_mask(bank); | ||
75 | |||
76 | prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, | ||
77 | OMAP4_PM_PWSTCTRL); | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, | ||
83 | u8 pwrst) | ||
84 | { | ||
85 | u32 m; | ||
86 | |||
87 | m = omap2_pwrdm_get_mem_bank_retst_mask(bank); | ||
88 | |||
89 | prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, | ||
90 | OMAP4_PM_PWSTCTRL); | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
61 | static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) | 95 | static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) |
62 | { | 96 | { |
63 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST, | 97 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST, |
@@ -70,12 +104,63 @@ static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) | |||
70 | OMAP4430_LOGICRETSTATE_MASK); | 104 | OMAP4430_LOGICRETSTATE_MASK); |
71 | } | 105 | } |
72 | 106 | ||
107 | static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) | ||
108 | { | ||
109 | u32 m; | ||
110 | |||
111 | m = omap2_pwrdm_get_mem_bank_stst_mask(bank); | ||
112 | |||
113 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST, m); | ||
114 | } | ||
115 | |||
116 | static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) | ||
117 | { | ||
118 | u32 m; | ||
119 | |||
120 | m = omap2_pwrdm_get_mem_bank_retst_mask(bank); | ||
121 | |||
122 | return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL, m); | ||
123 | } | ||
124 | |||
125 | static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) | ||
126 | { | ||
127 | u32 c = 0; | ||
128 | |||
129 | /* | ||
130 | * REVISIT: pwrdm_wait_transition() may be better implemented | ||
131 | * via a callback and a periodic timer check -- how long do we expect | ||
132 | * powerdomain transitions to take? | ||
133 | */ | ||
134 | |||
135 | /* XXX Is this udelay() value meaningful? */ | ||
136 | while ((prm_read_mod_reg(pwrdm->prcm_offs, OMAP4_PM_PWSTST) & | ||
137 | OMAP_INTRANSITION_MASK) && | ||
138 | (c++ < PWRDM_TRANSITION_BAILOUT)) | ||
139 | udelay(1); | ||
140 | |||
141 | if (c > PWRDM_TRANSITION_BAILOUT) { | ||
142 | printk(KERN_ERR "powerdomain: waited too long for " | ||
143 | "powerdomain %s to complete transition\n", pwrdm->name); | ||
144 | return -EAGAIN; | ||
145 | } | ||
146 | |||
147 | pr_debug("powerdomain: completed transition in %d loops\n", c); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
73 | struct pwrdm_ops omap4_pwrdm_operations = { | 152 | struct pwrdm_ops omap4_pwrdm_operations = { |
74 | .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst, | 153 | .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst, |
75 | .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst, | 154 | .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst, |
76 | .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst, | 155 | .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst, |
77 | .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst, | 156 | .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst, |
157 | .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange, | ||
78 | .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, | 158 | .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, |
79 | .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, | 159 | .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, |
80 | .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, | 160 | .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, |
161 | .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst, | ||
162 | .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst, | ||
163 | .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, | ||
164 | .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, | ||
165 | .pwrdm_wait_transition = omap4_pwrdm_wait_transition, | ||
81 | }; | 166 | }; |
diff --git a/arch/arm/mach-omap2/powerdomains.h b/arch/arm/mach-omap2/powerdomains.h index e57bc41ef4aa..55cd8e6aa104 100644 --- a/arch/arm/mach-omap2/powerdomains.h +++ b/arch/arm/mach-omap2/powerdomains.h | |||
@@ -19,4 +19,9 @@ extern struct pwrdm_ops omap2_pwrdm_operations; | |||
19 | extern struct pwrdm_ops omap3_pwrdm_operations; | 19 | extern struct pwrdm_ops omap3_pwrdm_operations; |
20 | extern struct pwrdm_ops omap4_pwrdm_operations; | 20 | extern struct pwrdm_ops omap4_pwrdm_operations; |
21 | 21 | ||
22 | /* Common Internal functions used across OMAP rev's */ | ||
23 | extern u32 omap2_pwrdm_get_mem_bank_onstate_mask(u8 bank); | ||
24 | extern u32 omap2_pwrdm_get_mem_bank_retst_mask(u8 bank); | ||
25 | extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank); | ||
26 | |||
22 | #endif /* ARCH_ARM_MACH_OMAP2_POWERDOMAINS */ | 27 | #endif /* ARCH_ARM_MACH_OMAP2_POWERDOMAINS */ |