diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-10-03 06:52:30 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-10-03 06:52:30 -0400 |
commit | fd9470ce3ac6fb54d6026e4b1cdab0936e34805e (patch) | |
tree | f603a75958f584452f4d40f2f8f730ed1ff6fa06 /arch/arm/plat-omap | |
parent | b8e6c91c74e9f0279b7c51048779b3d62da60b88 (diff) | |
parent | e89087c99f2be002ff46126742c21da5d357b324 (diff) |
Merge branch 'omap2-clock' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
Merge branch 'omap2-clock' into omap-all
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/Kconfig | 24 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/mach/clock.h | 3 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/mach/clockdomain.h | 106 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/mach/powerdomain.h | 166 |
4 files changed, 299 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index b917206ee906..ef62bf21e179 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig | |||
@@ -29,6 +29,30 @@ config OMAP_DEBUG_LEDS | |||
29 | depends on OMAP_DEBUG_DEVICES | 29 | depends on OMAP_DEBUG_DEVICES |
30 | default y if LEDS || LEDS_OMAP_DEBUG | 30 | default y if LEDS || LEDS_OMAP_DEBUG |
31 | 31 | ||
32 | config OMAP_DEBUG_POWERDOMAIN | ||
33 | bool "Emit debug messages from powerdomain layer" | ||
34 | depends on ARCH_OMAP2 || ARCH_OMAP3 | ||
35 | default n | ||
36 | help | ||
37 | Say Y here if you want to compile in powerdomain layer | ||
38 | debugging messages for OMAP2/3. These messages can | ||
39 | provide more detail as to why some powerdomain calls | ||
40 | may be failing, and will also emit a descriptive message | ||
41 | for every powerdomain register write. However, the | ||
42 | extra detail costs some memory. | ||
43 | |||
44 | config OMAP_DEBUG_CLOCKDOMAIN | ||
45 | bool "Emit debug messages from clockdomain layer" | ||
46 | depends on ARCH_OMAP2 || ARCH_OMAP3 | ||
47 | default n | ||
48 | help | ||
49 | Say Y here if you want to compile in clockdomain layer | ||
50 | debugging messages for OMAP2/3. These messages can | ||
51 | provide more detail as to why some clockdomain calls | ||
52 | may be failing, and will also emit a descriptive message | ||
53 | for every clockdomain register write. However, the | ||
54 | extra detail costs some memory. | ||
55 | |||
32 | config OMAP_RESET_CLOCKS | 56 | config OMAP_RESET_CLOCKS |
33 | bool "Reset unused clocks during boot" | 57 | bool "Reset unused clocks during boot" |
34 | depends on ARCH_OMAP | 58 | depends on ARCH_OMAP |
diff --git a/arch/arm/plat-omap/include/mach/clock.h b/arch/arm/plat-omap/include/mach/clock.h index 92f7c7238fcd..719298554ed7 100644 --- a/arch/arm/plat-omap/include/mach/clock.h +++ b/arch/arm/plat-omap/include/mach/clock.h | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | struct module; | 16 | struct module; |
17 | struct clk; | 17 | struct clk; |
18 | struct clockdomain; | ||
18 | 19 | ||
19 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | 20 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) |
20 | 21 | ||
@@ -79,6 +80,8 @@ struct clk { | |||
79 | u32 clksel_mask; | 80 | u32 clksel_mask; |
80 | const struct clksel *clksel; | 81 | const struct clksel *clksel; |
81 | struct dpll_data *dpll_data; | 82 | struct dpll_data *dpll_data; |
83 | const char *clkdm_name; | ||
84 | struct clockdomain *clkdm; | ||
82 | #else | 85 | #else |
83 | __u8 rate_offset; | 86 | __u8 rate_offset; |
84 | __u8 src_offset; | 87 | __u8 src_offset; |
diff --git a/arch/arm/plat-omap/include/mach/clockdomain.h b/arch/arm/plat-omap/include/mach/clockdomain.h new file mode 100644 index 000000000000..1f51f0173784 --- /dev/null +++ b/arch/arm/plat-omap/include/mach/clockdomain.h | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * linux/include/asm-arm/arch-omap/clockdomain.h | ||
3 | * | ||
4 | * OMAP2/3 clockdomain framework functions | ||
5 | * | ||
6 | * Copyright (C) 2008 Texas Instruments, Inc. | ||
7 | * Copyright (C) 2008 Nokia Corporation | ||
8 | * | ||
9 | * Written by Paul Walmsley | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #ifndef __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H | ||
17 | #define __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H | ||
18 | |||
19 | #include <mach/powerdomain.h> | ||
20 | #include <mach/clock.h> | ||
21 | #include <mach/cpu.h> | ||
22 | |||
23 | /* Clockdomain capability flags */ | ||
24 | #define CLKDM_CAN_FORCE_SLEEP (1 << 0) | ||
25 | #define CLKDM_CAN_FORCE_WAKEUP (1 << 1) | ||
26 | #define CLKDM_CAN_ENABLE_AUTO (1 << 2) | ||
27 | #define CLKDM_CAN_DISABLE_AUTO (1 << 3) | ||
28 | |||
29 | #define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO) | ||
30 | #define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP) | ||
31 | #define CLKDM_CAN_HWSUP_SWSUP (CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP) | ||
32 | |||
33 | /* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */ | ||
34 | #define OMAP24XX_CLKSTCTRL_DISABLE_AUTO 0x0 | ||
35 | #define OMAP24XX_CLKSTCTRL_ENABLE_AUTO 0x1 | ||
36 | |||
37 | /* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */ | ||
38 | #define OMAP34XX_CLKSTCTRL_DISABLE_AUTO 0x0 | ||
39 | #define OMAP34XX_CLKSTCTRL_FORCE_SLEEP 0x1 | ||
40 | #define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP 0x2 | ||
41 | #define OMAP34XX_CLKSTCTRL_ENABLE_AUTO 0x3 | ||
42 | |||
43 | /* | ||
44 | * struct clkdm_pwrdm_autodep - a powerdomain that should have wkdeps | ||
45 | * and sleepdeps added when a powerdomain should stay active in hwsup mode; | ||
46 | * and conversely, removed when the powerdomain should be allowed to go | ||
47 | * inactive in hwsup mode. | ||
48 | */ | ||
49 | struct clkdm_pwrdm_autodep { | ||
50 | |||
51 | /* Name of the powerdomain to add a wkdep/sleepdep on */ | ||
52 | const char *pwrdm_name; | ||
53 | |||
54 | /* Powerdomain pointer (looked up at clkdm_init() time) */ | ||
55 | struct powerdomain *pwrdm; | ||
56 | |||
57 | /* OMAP chip types that this clockdomain dep is valid on */ | ||
58 | const struct omap_chip_id omap_chip; | ||
59 | |||
60 | }; | ||
61 | |||
62 | struct clockdomain { | ||
63 | |||
64 | /* Clockdomain name */ | ||
65 | const char *name; | ||
66 | |||
67 | /* Powerdomain enclosing this clockdomain */ | ||
68 | const char *pwrdm_name; | ||
69 | |||
70 | /* CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg */ | ||
71 | const u16 clktrctrl_mask; | ||
72 | |||
73 | /* Clockdomain capability flags */ | ||
74 | const u8 flags; | ||
75 | |||
76 | /* OMAP chip types that this clockdomain is valid on */ | ||
77 | const struct omap_chip_id omap_chip; | ||
78 | |||
79 | /* Usecount tracking */ | ||
80 | atomic_t usecount; | ||
81 | |||
82 | /* Powerdomain pointer assigned at clkdm_register() */ | ||
83 | struct powerdomain *pwrdm; | ||
84 | |||
85 | struct list_head node; | ||
86 | |||
87 | }; | ||
88 | |||
89 | void clkdm_init(struct clockdomain **clkdms, struct clkdm_pwrdm_autodep *autodeps); | ||
90 | int clkdm_register(struct clockdomain *clkdm); | ||
91 | int clkdm_unregister(struct clockdomain *clkdm); | ||
92 | struct clockdomain *clkdm_lookup(const char *name); | ||
93 | |||
94 | int clkdm_for_each(int (*fn)(struct clockdomain *clkdm)); | ||
95 | struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm); | ||
96 | |||
97 | void omap2_clkdm_allow_idle(struct clockdomain *clkdm); | ||
98 | void omap2_clkdm_deny_idle(struct clockdomain *clkdm); | ||
99 | |||
100 | int omap2_clkdm_wakeup(struct clockdomain *clkdm); | ||
101 | int omap2_clkdm_sleep(struct clockdomain *clkdm); | ||
102 | |||
103 | int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); | ||
104 | int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); | ||
105 | |||
106 | #endif | ||
diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h new file mode 100644 index 000000000000..2806a9c8e4d7 --- /dev/null +++ b/arch/arm/plat-omap/include/mach/powerdomain.h | |||
@@ -0,0 +1,166 @@ | |||
1 | /* | ||
2 | * OMAP2/3 powerdomain control | ||
3 | * | ||
4 | * Copyright (C) 2007-8 Texas Instruments, Inc. | ||
5 | * Copyright (C) 2007-8 Nokia Corporation | ||
6 | * | ||
7 | * Written by Paul Walmsley | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #ifndef ASM_ARM_ARCH_OMAP_POWERDOMAIN | ||
15 | #define ASM_ARM_ARCH_OMAP_POWERDOMAIN | ||
16 | |||
17 | #include <linux/types.h> | ||
18 | #include <linux/list.h> | ||
19 | |||
20 | #include <asm/atomic.h> | ||
21 | |||
22 | #include <mach/cpu.h> | ||
23 | |||
24 | |||
25 | /* Powerdomain basic power states */ | ||
26 | #define PWRDM_POWER_OFF 0x0 | ||
27 | #define PWRDM_POWER_RET 0x1 | ||
28 | #define PWRDM_POWER_INACTIVE 0x2 | ||
29 | #define PWRDM_POWER_ON 0x3 | ||
30 | |||
31 | /* Powerdomain allowable state bitfields */ | ||
32 | #define PWRSTS_OFF_ON ((1 << PWRDM_POWER_OFF) | \ | ||
33 | (1 << PWRDM_POWER_ON)) | ||
34 | |||
35 | #define PWRSTS_OFF_RET ((1 << PWRDM_POWER_OFF) | \ | ||
36 | (1 << PWRDM_POWER_RET)) | ||
37 | |||
38 | #define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON)) | ||
39 | |||
40 | |||
41 | /* Powerdomain flags */ | ||
42 | #define PWRDM_HAS_HDWR_SAR (1 << 0) /* hardware save-and-restore support */ | ||
43 | |||
44 | |||
45 | /* | ||
46 | * Number of memory banks that are power-controllable. On OMAP3430, the | ||
47 | * maximum is 4. | ||
48 | */ | ||
49 | #define PWRDM_MAX_MEM_BANKS 4 | ||
50 | |||
51 | /* | ||
52 | * Maximum number of clockdomains that can be associated with a powerdomain. | ||
53 | * CORE powerdomain is probably the worst case. | ||
54 | */ | ||
55 | #define PWRDM_MAX_CLKDMS 3 | ||
56 | |||
57 | /* XXX A completely arbitrary number. What is reasonable here? */ | ||
58 | #define PWRDM_TRANSITION_BAILOUT 100000 | ||
59 | |||
60 | struct clockdomain; | ||
61 | struct powerdomain; | ||
62 | |||
63 | /* Encodes dependencies between powerdomains - statically defined */ | ||
64 | struct pwrdm_dep { | ||
65 | |||
66 | /* Powerdomain name */ | ||
67 | const char *pwrdm_name; | ||
68 | |||
69 | /* Powerdomain pointer - resolved by the powerdomain code */ | ||
70 | struct powerdomain *pwrdm; | ||
71 | |||
72 | /* Flags to mark OMAP chip restrictions, etc. */ | ||
73 | const struct omap_chip_id omap_chip; | ||
74 | |||
75 | }; | ||
76 | |||
77 | struct powerdomain { | ||
78 | |||
79 | /* Powerdomain name */ | ||
80 | const char *name; | ||
81 | |||
82 | /* the address offset from CM_BASE/PRM_BASE */ | ||
83 | const s16 prcm_offs; | ||
84 | |||
85 | /* Used to represent the OMAP chip types containing this pwrdm */ | ||
86 | const struct omap_chip_id omap_chip; | ||
87 | |||
88 | /* Bit shift of this powerdomain's PM_WKDEP/CM_SLEEPDEP bit */ | ||
89 | const u8 dep_bit; | ||
90 | |||
91 | /* Powerdomains that can be told to wake this powerdomain up */ | ||
92 | struct pwrdm_dep *wkdep_srcs; | ||
93 | |||
94 | /* Powerdomains that can be told to keep this pwrdm from inactivity */ | ||
95 | struct pwrdm_dep *sleepdep_srcs; | ||
96 | |||
97 | /* Possible powerdomain power states */ | ||
98 | const u8 pwrsts; | ||
99 | |||
100 | /* Possible logic power states when pwrdm in RETENTION */ | ||
101 | const u8 pwrsts_logic_ret; | ||
102 | |||
103 | /* Powerdomain flags */ | ||
104 | const u8 flags; | ||
105 | |||
106 | /* Number of software-controllable memory banks in this powerdomain */ | ||
107 | const u8 banks; | ||
108 | |||
109 | /* Possible memory bank pwrstates when pwrdm in RETENTION */ | ||
110 | const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS]; | ||
111 | |||
112 | /* Possible memory bank pwrstates when pwrdm is ON */ | ||
113 | const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS]; | ||
114 | |||
115 | /* Clockdomains in this powerdomain */ | ||
116 | struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS]; | ||
117 | |||
118 | struct list_head node; | ||
119 | |||
120 | }; | ||
121 | |||
122 | |||
123 | void pwrdm_init(struct powerdomain **pwrdm_list); | ||
124 | |||
125 | int pwrdm_register(struct powerdomain *pwrdm); | ||
126 | int pwrdm_unregister(struct powerdomain *pwrdm); | ||
127 | struct powerdomain *pwrdm_lookup(const char *name); | ||
128 | |||
129 | int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm)); | ||
130 | |||
131 | int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); | ||
132 | int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); | ||
133 | int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, | ||
134 | int (*fn)(struct powerdomain *pwrdm, | ||
135 | struct clockdomain *clkdm)); | ||
136 | |||
137 | int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); | ||
138 | int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); | ||
139 | int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); | ||
140 | int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); | ||
141 | int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); | ||
142 | int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); | ||
143 | |||
144 | int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm); | ||
145 | |||
146 | int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); | ||
147 | int pwrdm_read_next_pwrst(struct powerdomain *pwrdm); | ||
148 | int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm); | ||
149 | int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm); | ||
150 | |||
151 | int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst); | ||
152 | int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst); | ||
153 | int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst); | ||
154 | |||
155 | int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm); | ||
156 | int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm); | ||
157 | int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank); | ||
158 | int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank); | ||
159 | |||
160 | int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm); | ||
161 | int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm); | ||
162 | bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); | ||
163 | |||
164 | int pwrdm_wait_transition(struct powerdomain *pwrdm); | ||
165 | |||
166 | #endif | ||