diff options
Diffstat (limited to 'arch/arm/mach-omap2/pm.c')
-rw-r--r-- | arch/arm/mach-omap2/pm.c | 107 |
1 files changed, 40 insertions, 67 deletions
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 3feb35911a32..1e79bdf313e3 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/opp.h> | 16 | #include <linux/opp.h> |
17 | #include <linux/export.h> | ||
17 | 18 | ||
18 | #include <plat/omap-pm.h> | 19 | #include <plat/omap-pm.h> |
19 | #include <plat/omap_device.h> | 20 | #include <plat/omap_device.h> |
@@ -26,54 +27,21 @@ | |||
26 | 27 | ||
27 | static struct omap_device_pm_latency *pm_lats; | 28 | static struct omap_device_pm_latency *pm_lats; |
28 | 29 | ||
29 | static struct device *mpu_dev; | 30 | static int _init_omap_device(char *name) |
30 | static struct device *iva_dev; | ||
31 | static struct device *l3_dev; | ||
32 | static struct device *dsp_dev; | ||
33 | |||
34 | struct device *omap2_get_mpuss_device(void) | ||
35 | { | ||
36 | WARN_ON_ONCE(!mpu_dev); | ||
37 | return mpu_dev; | ||
38 | } | ||
39 | |||
40 | struct device *omap2_get_iva_device(void) | ||
41 | { | ||
42 | WARN_ON_ONCE(!iva_dev); | ||
43 | return iva_dev; | ||
44 | } | ||
45 | |||
46 | struct device *omap2_get_l3_device(void) | ||
47 | { | ||
48 | WARN_ON_ONCE(!l3_dev); | ||
49 | return l3_dev; | ||
50 | } | ||
51 | |||
52 | struct device *omap4_get_dsp_device(void) | ||
53 | { | ||
54 | WARN_ON_ONCE(!dsp_dev); | ||
55 | return dsp_dev; | ||
56 | } | ||
57 | EXPORT_SYMBOL(omap4_get_dsp_device); | ||
58 | |||
59 | /* static int _init_omap_device(struct omap_hwmod *oh, void *user) */ | ||
60 | static int _init_omap_device(char *name, struct device **new_dev) | ||
61 | { | 31 | { |
62 | struct omap_hwmod *oh; | 32 | struct omap_hwmod *oh; |
63 | struct omap_device *od; | 33 | struct platform_device *pdev; |
64 | 34 | ||
65 | oh = omap_hwmod_lookup(name); | 35 | oh = omap_hwmod_lookup(name); |
66 | if (WARN(!oh, "%s: could not find omap_hwmod for %s\n", | 36 | if (WARN(!oh, "%s: could not find omap_hwmod for %s\n", |
67 | __func__, name)) | 37 | __func__, name)) |
68 | return -ENODEV; | 38 | return -ENODEV; |
69 | 39 | ||
70 | od = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false); | 40 | pdev = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false); |
71 | if (WARN(IS_ERR(od), "%s: could not build omap_device for %s\n", | 41 | if (WARN(IS_ERR(pdev), "%s: could not build omap_device for %s\n", |
72 | __func__, name)) | 42 | __func__, name)) |
73 | return -ENODEV; | 43 | return -ENODEV; |
74 | 44 | ||
75 | *new_dev = &od->pdev.dev; | ||
76 | |||
77 | return 0; | 45 | return 0; |
78 | } | 46 | } |
79 | 47 | ||
@@ -82,16 +50,16 @@ static int _init_omap_device(char *name, struct device **new_dev) | |||
82 | */ | 50 | */ |
83 | static void omap2_init_processor_devices(void) | 51 | static void omap2_init_processor_devices(void) |
84 | { | 52 | { |
85 | _init_omap_device("mpu", &mpu_dev); | 53 | _init_omap_device("mpu"); |
86 | if (omap3_has_iva()) | 54 | if (omap3_has_iva()) |
87 | _init_omap_device("iva", &iva_dev); | 55 | _init_omap_device("iva"); |
88 | 56 | ||
89 | if (cpu_is_omap44xx()) { | 57 | if (cpu_is_omap44xx()) { |
90 | _init_omap_device("l3_main_1", &l3_dev); | 58 | _init_omap_device("l3_main_1"); |
91 | _init_omap_device("dsp", &dsp_dev); | 59 | _init_omap_device("dsp"); |
92 | _init_omap_device("iva", &iva_dev); | 60 | _init_omap_device("iva"); |
93 | } else { | 61 | } else { |
94 | _init_omap_device("l3_main", &l3_dev); | 62 | _init_omap_device("l3_main"); |
95 | } | 63 | } |
96 | } | 64 | } |
97 | 65 | ||
@@ -130,15 +98,14 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) | |||
130 | } else { | 98 | } else { |
131 | hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]); | 99 | hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]); |
132 | clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); | 100 | clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); |
133 | pwrdm_wait_transition(pwrdm); | ||
134 | sleep_switch = FORCEWAKEUP_SWITCH; | 101 | sleep_switch = FORCEWAKEUP_SWITCH; |
135 | } | 102 | } |
136 | } | 103 | } |
137 | 104 | ||
138 | ret = pwrdm_set_next_pwrst(pwrdm, state); | 105 | ret = pwrdm_set_next_pwrst(pwrdm, state); |
139 | if (ret) { | 106 | if (ret) { |
140 | printk(KERN_ERR "Unable to set state of powerdomain: %s\n", | 107 | pr_err("%s: unable to set state of powerdomain: %s\n", |
141 | pwrdm->name); | 108 | __func__, pwrdm->name); |
142 | goto err; | 109 | goto err; |
143 | } | 110 | } |
144 | 111 | ||
@@ -156,44 +123,50 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) | |||
156 | return ret; | 123 | return ret; |
157 | } | 124 | } |
158 | 125 | ||
159 | pwrdm_wait_transition(pwrdm); | ||
160 | pwrdm_state_switch(pwrdm); | 126 | pwrdm_state_switch(pwrdm); |
161 | err: | 127 | err: |
162 | return ret; | 128 | return ret; |
163 | } | 129 | } |
164 | 130 | ||
165 | /* | 131 | /* |
166 | * This API is to be called during init to put the various voltage | 132 | * This API is to be called during init to set the various voltage |
167 | * domains to the voltage as per the opp table. Typically we boot up | 133 | * domains to the voltage as per the opp table. Typically we boot up |
168 | * at the nominal voltage. So this function finds out the rate of | 134 | * at the nominal voltage. So this function finds out the rate of |
169 | * the clock associated with the voltage domain, finds out the correct | 135 | * the clock associated with the voltage domain, finds out the correct |
170 | * opp entry and puts the voltage domain to the voltage specifies | 136 | * opp entry and sets the voltage domain to the voltage specified |
171 | * in the opp entry | 137 | * in the opp entry |
172 | */ | 138 | */ |
173 | static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, | 139 | static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, |
174 | struct device *dev) | 140 | const char *oh_name) |
175 | { | 141 | { |
176 | struct voltagedomain *voltdm; | 142 | struct voltagedomain *voltdm; |
177 | struct clk *clk; | 143 | struct clk *clk; |
178 | struct opp *opp; | 144 | struct opp *opp; |
179 | unsigned long freq, bootup_volt; | 145 | unsigned long freq, bootup_volt; |
146 | struct device *dev; | ||
147 | |||
148 | if (!vdd_name || !clk_name || !oh_name) { | ||
149 | pr_err("%s: invalid parameters\n", __func__); | ||
150 | goto exit; | ||
151 | } | ||
180 | 152 | ||
181 | if (!vdd_name || !clk_name || !dev) { | 153 | dev = omap_device_get_by_hwmod_name(oh_name); |
182 | printk(KERN_ERR "%s: Invalid parameters!\n", __func__); | 154 | if (IS_ERR(dev)) { |
155 | pr_err("%s: Unable to get dev pointer for hwmod %s\n", | ||
156 | __func__, oh_name); | ||
183 | goto exit; | 157 | goto exit; |
184 | } | 158 | } |
185 | 159 | ||
186 | voltdm = omap_voltage_domain_lookup(vdd_name); | 160 | voltdm = voltdm_lookup(vdd_name); |
187 | if (IS_ERR(voltdm)) { | 161 | if (IS_ERR(voltdm)) { |
188 | printk(KERN_ERR "%s: Unable to get vdd pointer for vdd_%s\n", | 162 | pr_err("%s: unable to get vdd pointer for vdd_%s\n", |
189 | __func__, vdd_name); | 163 | __func__, vdd_name); |
190 | goto exit; | 164 | goto exit; |
191 | } | 165 | } |
192 | 166 | ||
193 | clk = clk_get(NULL, clk_name); | 167 | clk = clk_get(NULL, clk_name); |
194 | if (IS_ERR(clk)) { | 168 | if (IS_ERR(clk)) { |
195 | printk(KERN_ERR "%s: unable to get clk %s\n", | 169 | pr_err("%s: unable to get clk %s\n", __func__, clk_name); |
196 | __func__, clk_name); | ||
197 | goto exit; | 170 | goto exit; |
198 | } | 171 | } |
199 | 172 | ||
@@ -202,24 +175,23 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, | |||
202 | 175 | ||
203 | opp = opp_find_freq_ceil(dev, &freq); | 176 | opp = opp_find_freq_ceil(dev, &freq); |
204 | if (IS_ERR(opp)) { | 177 | if (IS_ERR(opp)) { |
205 | printk(KERN_ERR "%s: unable to find boot up OPP for vdd_%s\n", | 178 | pr_err("%s: unable to find boot up OPP for vdd_%s\n", |
206 | __func__, vdd_name); | 179 | __func__, vdd_name); |
207 | goto exit; | 180 | goto exit; |
208 | } | 181 | } |
209 | 182 | ||
210 | bootup_volt = opp_get_voltage(opp); | 183 | bootup_volt = opp_get_voltage(opp); |
211 | if (!bootup_volt) { | 184 | if (!bootup_volt) { |
212 | printk(KERN_ERR "%s: unable to find voltage corresponding" | 185 | pr_err("%s: unable to find voltage corresponding " |
213 | "to the bootup OPP for vdd_%s\n", __func__, vdd_name); | 186 | "to the bootup OPP for vdd_%s\n", __func__, vdd_name); |
214 | goto exit; | 187 | goto exit; |
215 | } | 188 | } |
216 | 189 | ||
217 | omap_voltage_scale_vdd(voltdm, bootup_volt); | 190 | voltdm_scale(voltdm, bootup_volt); |
218 | return 0; | 191 | return 0; |
219 | 192 | ||
220 | exit: | 193 | exit: |
221 | printk(KERN_ERR "%s: Unable to put vdd_%s to its init voltage\n\n", | 194 | pr_err("%s: unable to set vdd_%s\n", __func__, vdd_name); |
222 | __func__, vdd_name); | ||
223 | return -EINVAL; | 195 | return -EINVAL; |
224 | } | 196 | } |
225 | 197 | ||
@@ -228,8 +200,8 @@ static void __init omap3_init_voltages(void) | |||
228 | if (!cpu_is_omap34xx()) | 200 | if (!cpu_is_omap34xx()) |
229 | return; | 201 | return; |
230 | 202 | ||
231 | omap2_set_init_voltage("mpu", "dpll1_ck", mpu_dev); | 203 | omap2_set_init_voltage("mpu_iva", "dpll1_ck", "mpu"); |
232 | omap2_set_init_voltage("core", "l3_ick", l3_dev); | 204 | omap2_set_init_voltage("core", "l3_ick", "l3_main"); |
233 | } | 205 | } |
234 | 206 | ||
235 | static void __init omap4_init_voltages(void) | 207 | static void __init omap4_init_voltages(void) |
@@ -237,14 +209,15 @@ static void __init omap4_init_voltages(void) | |||
237 | if (!cpu_is_omap44xx()) | 209 | if (!cpu_is_omap44xx()) |
238 | return; | 210 | return; |
239 | 211 | ||
240 | omap2_set_init_voltage("mpu", "dpll_mpu_ck", mpu_dev); | 212 | omap2_set_init_voltage("mpu", "dpll_mpu_ck", "mpu"); |
241 | omap2_set_init_voltage("core", "l3_div_ck", l3_dev); | 213 | omap2_set_init_voltage("core", "l3_div_ck", "l3_main_1"); |
242 | omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", iva_dev); | 214 | omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva"); |
243 | } | 215 | } |
244 | 216 | ||
245 | static int __init omap2_common_pm_init(void) | 217 | static int __init omap2_common_pm_init(void) |
246 | { | 218 | { |
247 | omap2_init_processor_devices(); | 219 | if (!of_have_populated_dt()) |
220 | omap2_init_processor_devices(); | ||
248 | omap_pm_if_init(); | 221 | omap_pm_if_init(); |
249 | 222 | ||
250 | return 0; | 223 | return 0; |