diff options
Diffstat (limited to 'arch/arm/mach-tegra/powergate.c')
-rw-r--r-- | arch/arm/mach-tegra/powergate.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c index 948306491a59..c238699ae86f 100644 --- a/arch/arm/mach-tegra/powergate.c +++ b/arch/arm/mach-tegra/powergate.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <mach/iomap.h> | 31 | #include <mach/iomap.h> |
32 | #include <mach/powergate.h> | 32 | #include <mach/powergate.h> |
33 | 33 | ||
34 | #include "fuse.h" | ||
35 | |||
34 | #define PWRGATE_TOGGLE 0x30 | 36 | #define PWRGATE_TOGGLE 0x30 |
35 | #define PWRGATE_TOGGLE_START (1 << 8) | 37 | #define PWRGATE_TOGGLE_START (1 << 8) |
36 | 38 | ||
@@ -38,6 +40,16 @@ | |||
38 | 40 | ||
39 | #define PWRGATE_STATUS 0x38 | 41 | #define PWRGATE_STATUS 0x38 |
40 | 42 | ||
43 | static int tegra_num_powerdomains; | ||
44 | static int tegra_num_cpu_domains; | ||
45 | static u8 *tegra_cpu_domains; | ||
46 | static u8 tegra30_cpu_domains[] = { | ||
47 | TEGRA_POWERGATE_CPU0, | ||
48 | TEGRA_POWERGATE_CPU1, | ||
49 | TEGRA_POWERGATE_CPU2, | ||
50 | TEGRA_POWERGATE_CPU3, | ||
51 | }; | ||
52 | |||
41 | static DEFINE_SPINLOCK(tegra_powergate_lock); | 53 | static DEFINE_SPINLOCK(tegra_powergate_lock); |
42 | 54 | ||
43 | static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); | 55 | static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); |
@@ -75,7 +87,7 @@ static int tegra_powergate_set(int id, bool new_state) | |||
75 | 87 | ||
76 | int tegra_powergate_power_on(int id) | 88 | int tegra_powergate_power_on(int id) |
77 | { | 89 | { |
78 | if (id < 0 || id >= TEGRA_NUM_POWERGATE) | 90 | if (id < 0 || id >= tegra_num_powerdomains) |
79 | return -EINVAL; | 91 | return -EINVAL; |
80 | 92 | ||
81 | return tegra_powergate_set(id, true); | 93 | return tegra_powergate_set(id, true); |
@@ -83,17 +95,18 @@ int tegra_powergate_power_on(int id) | |||
83 | 95 | ||
84 | int tegra_powergate_power_off(int id) | 96 | int tegra_powergate_power_off(int id) |
85 | { | 97 | { |
86 | if (id < 0 || id >= TEGRA_NUM_POWERGATE) | 98 | if (id < 0 || id >= tegra_num_powerdomains) |
87 | return -EINVAL; | 99 | return -EINVAL; |
88 | 100 | ||
89 | return tegra_powergate_set(id, false); | 101 | return tegra_powergate_set(id, false); |
90 | } | 102 | } |
91 | 103 | ||
92 | static bool tegra_powergate_is_powered(int id) | 104 | int tegra_powergate_is_powered(int id) |
93 | { | 105 | { |
94 | u32 status; | 106 | u32 status; |
95 | 107 | ||
96 | WARN_ON(id < 0 || id >= TEGRA_NUM_POWERGATE); | 108 | if (id < 0 || id >= tegra_num_powerdomains) |
109 | return -EINVAL; | ||
97 | 110 | ||
98 | status = pmc_read(PWRGATE_STATUS) & (1 << id); | 111 | status = pmc_read(PWRGATE_STATUS) & (1 << id); |
99 | return !!status; | 112 | return !!status; |
@@ -103,7 +116,7 @@ int tegra_powergate_remove_clamping(int id) | |||
103 | { | 116 | { |
104 | u32 mask; | 117 | u32 mask; |
105 | 118 | ||
106 | if (id < 0 || id >= TEGRA_NUM_POWERGATE) | 119 | if (id < 0 || id >= tegra_num_powerdomains) |
107 | return -EINVAL; | 120 | return -EINVAL; |
108 | 121 | ||
109 | /* | 122 | /* |
@@ -156,6 +169,34 @@ err_power: | |||
156 | return ret; | 169 | return ret; |
157 | } | 170 | } |
158 | 171 | ||
172 | int tegra_cpu_powergate_id(int cpuid) | ||
173 | { | ||
174 | if (cpuid > 0 && cpuid < tegra_num_cpu_domains) | ||
175 | return tegra_cpu_domains[cpuid]; | ||
176 | |||
177 | return -EINVAL; | ||
178 | } | ||
179 | |||
180 | int __init tegra_powergate_init(void) | ||
181 | { | ||
182 | switch (tegra_chip_id) { | ||
183 | case TEGRA20: | ||
184 | tegra_num_powerdomains = 7; | ||
185 | break; | ||
186 | case TEGRA30: | ||
187 | tegra_num_powerdomains = 14; | ||
188 | tegra_num_cpu_domains = 4; | ||
189 | tegra_cpu_domains = tegra30_cpu_domains; | ||
190 | break; | ||
191 | default: | ||
192 | /* Unknown Tegra variant. Disable powergating */ | ||
193 | tegra_num_powerdomains = 0; | ||
194 | break; | ||
195 | } | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
159 | #ifdef CONFIG_DEBUG_FS | 200 | #ifdef CONFIG_DEBUG_FS |
160 | 201 | ||
161 | static const char * const powergate_name[] = { | 202 | static const char * const powergate_name[] = { |
@@ -175,7 +216,7 @@ static int powergate_show(struct seq_file *s, void *data) | |||
175 | seq_printf(s, " powergate powered\n"); | 216 | seq_printf(s, " powergate powered\n"); |
176 | seq_printf(s, "------------------\n"); | 217 | seq_printf(s, "------------------\n"); |
177 | 218 | ||
178 | for (i = 0; i < TEGRA_NUM_POWERGATE; i++) | 219 | for (i = 0; i < tegra_num_powerdomains; i++) |
179 | seq_printf(s, " %9s %7s\n", powergate_name[i], | 220 | seq_printf(s, " %9s %7s\n", powergate_name[i], |
180 | tegra_powergate_is_powered(i) ? "yes" : "no"); | 221 | tegra_powergate_is_powered(i) ? "yes" : "no"); |
181 | return 0; | 222 | return 0; |