aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/pm.c')
-rw-r--r--arch/arm/mach-omap2/pm.c107
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
27static struct omap_device_pm_latency *pm_lats; 28static struct omap_device_pm_latency *pm_lats;
28 29
29static struct device *mpu_dev; 30static int _init_omap_device(char *name)
30static struct device *iva_dev;
31static struct device *l3_dev;
32static struct device *dsp_dev;
33
34struct device *omap2_get_mpuss_device(void)
35{
36 WARN_ON_ONCE(!mpu_dev);
37 return mpu_dev;
38}
39
40struct device *omap2_get_iva_device(void)
41{
42 WARN_ON_ONCE(!iva_dev);
43 return iva_dev;
44}
45
46struct device *omap2_get_l3_device(void)
47{
48 WARN_ON_ONCE(!l3_dev);
49 return l3_dev;
50}
51
52struct device *omap4_get_dsp_device(void)
53{
54 WARN_ON_ONCE(!dsp_dev);
55 return dsp_dev;
56}
57EXPORT_SYMBOL(omap4_get_dsp_device);
58
59/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
60static 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 */
83static void omap2_init_processor_devices(void) 51static 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);
161err: 127err:
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 */
173static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, 139static 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
220exit: 193exit:
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
235static void __init omap4_init_voltages(void) 207static 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
245static int __init omap2_common_pm_init(void) 217static 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;