1.. SPDX-License-Identifier: GPL-2.0 2.. include:: ../disclaimer-zh_CN.rst 3 4:Original: Documentation/power/opp.rst 5 6:������: 7 8 ��������� Tang Yizhou <tangyeechou@gmail.com> 9 10====================== 11������������������OPP������ 12====================== 13 14(C) 2009-2010 Nishanth Menon <nm@ti.com>, ������������������ 15 16.. ������ 17 18 1. ������ 19 2. OPP������������������ 20 3. OPP������������ 21 4. OPP��������������������� 22 5. OPP������������������ 23 6. ������������ 24 251. ������ 26======= 27 281.1 ������������������������OPP������ 29------------------------------ 30 31������������������������������SoC������������������������������������������������������������������������������������������ 32������������������������������SoC���������������������������������������������������������������������������������SoC��� 33���������������������������������������������������������������������������������������������������������������������������/ 34��������������������� 35 36������������������������������������������������������������������������������������������������������������������OPPs��� 37 38��������������� 39 40���������������������������������������������������������������������������MPU������������ 41{300MHz������������������1V}, {800MHz������������������1.2V}, {1GHz������������������1.3V} 42 43���������������������������3���OPP������������{Hz, uV}��������������������������������������������������������������� 44������������ 45 46- {300000000, 1000000} 47- {800000000, 1200000} 48- {1000000000, 1300000} 49 501.2 ������������������ 51---------------- 52 53OPP������������������������������������������������OPP���������������������drivers/opp/������������������������ 54������include/linux/pm_opp.h������OPP���������������������CONFIG_PM_OPP������������������SoC��� 55������������������OMAP������������������������cpufreq������������������������������OPP������������ 56 57OPP������������������������:: 58 59 ������������ -> ���������������������OPP������ -> ��������� 60 ���SoC��������� -> ���������������������������������OPP������������ -> OPP layer 61 -> ������/��������������������� -> 62 63OPP������������������������������������������������������������SoC���������OPP��������������������������������������� 64OPP������������������������������������������������������������������������������������������5��������������������������� 65������OPP������������������������������������������������������������ 66 67������OPP������������������ 68^^^^^^^^^^^^^^^^^^^ 69 70������������������������SoC������������������������������������������������������OPP��������������������������������������� 71������������������������������������������������SoC������������������������������������������������OPP������������������ 72������������������OPP������������������������������������ 73 74OPP���������������������������������������������������������������������������������OPP��������� 75dev_pm_opp_find_freq_{ceil, floor}, dev_pm_opp_get_voltage, 76dev_pm_opp_get_freq, dev_pm_opp_get_opp_count��� 77 78dev_pm_opp_find_freq_exact���������������OPP���������������������������������dev_pm_opp_enable/ 79disable������������������OPP������������������������������ 80 81������������������������������������dev_pm_opp_enable/disable���������OPP������������������������ 82dev_pm_opp_get_opp_count���������OPP������������������������������������������������������������������������ 83������������������cpufreq������������������������������������OPP������SoC��������������������������������������������� 84������������������������������cpufreq������ 85 862. OPP������������������ 87================== 88SoC������������������������dev_pm_opp_add������������������������������OPP���������SoC��������������������� 89������������OPP������ - ���������������������������5���������������OPP���������OPP������������������������������������ 90������OPP������������SoC������������������������dev_pm_opp_enable / disable��������������� 91������OPP��������������� 92 93dev_pm_opp_add 94 ������������������������������������������������������OPP���OPP��������������������������������������������� 95 ���������OPP���������������������������������dev_pm_opp_enable/disable������������������������������ 96 OPP������������dev_pm_opp������������������������������������������������������������SoC������������SoC 97 ������������������������������������������������������ 98 99 ��������� 100 ��������������������������������������������� 101 102 ������:: 103 104 soc_pm_init() 105 { 106 /* ��������������� */ 107 r = dev_pm_opp_add(mpu_dev, 1000000, 900000); 108 if (!r) { 109 pr_err("%s: unable to register mpu opp(%d)\n", r); 110 goto no_cpufreq; 111 } 112 /* ������������cpufreq��������������� */ 113 no_cpufreq: 114 /* ������������������ */ 115 } 116 1173. OPP������������ 118============== 119cpufreq������������������������������������������������������������������������OPP���OPP��������������������������� 120���������OPP������������������OPP������������������������������������������������OPP���������������������OPP������������ 121���������������������������������������������������������������������IS_ERR()������������������������������������������ 122��������� 123 124���������������������������������������OPP���������dev_pm_opp_put()������������OPP������������������������ 125������������������������������������ 126 127dev_pm_opp_find_freq_exact 128 ������ *���������* ���������������������������OPP������������������������������������OPP��������������� 129 ������������SoC������������������������������������������������������������������������������������ 130 dev_pm_opp_enable������������OPP:: 131 132 opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); 133 dev_pm_opp_put(opp); 134 /* ������������������.. ������������������������.. */ 135 if (IS_ERR(opp)) { 136 pr_err("frequency not disabled!\n"); 137 /* ���������������������.. */ 138 } else { 139 dev_pm_opp_enable(dev,1000000000); 140 } 141 142 ��������� 143 ���������������������������������������OPP������������ 144 145dev_pm_opp_find_freq_floor 146 ������������ *������* ���������������������������OPP��������������������������������������������������� 147 ���������������������OPP��������������������� 148 ���������������������������������������OPP:: 149 150 freq = ULONG_MAX; 151 opp = dev_pm_opp_find_freq_floor(dev, &freq); 152 dev_pm_opp_put(opp); 153 154dev_pm_opp_find_freq_ceil 155 ������������ *������* ���������������������������OPP��������������������������������������������������� 156 ���������������������OPP��������������������� 157 ���1������������������������������OPP:: 158 159 freq = 0; 160 opp = dev_pm_opp_find_freq_ceil(dev, &freq); 161 dev_pm_opp_put(opp); 162 163 ���: ������SoC���cpufreq_driver->target���������������:: 164 165 soc_cpufreq_target(..) 166 { 167 /* ������������������������ */ 168 /* ��������������������������������� */ 169 opp = dev_pm_opp_find_freq_ceil(dev, &freq); 170 dev_pm_opp_put(opp); 171 if (!IS_ERR(opp)) 172 soc_switch_to_freq_voltage(freq); 173 else 174 /* ��������������������������������������� */ 175 /* ������������ */ 176 } 177 1784. OPP��������������������� 179==================== 180���OPP���������������������OPP������������������������������������������������OPP��������������������������������� 181OPP������������������OPP������������������������SoC������������������������������������������OPP������������������ 182������������������������������������������������������������ *���������* ������������OPP��������������������������� 183���������������������OPP������ 184 185��������� 186 ��������������������������������������������� 187 188dev_pm_opp_enable 189 ���������OPP������������������ 190 ���������������1GHz���OPP���������SoC���������������������������������������SoC��������������������� 191 ������������������������:: 192 193 if (cur_temp < temp_low_thresh) { 194 /* ���1GHz��������������������� */ 195 opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); 196 dev_pm_opp_put(opp); 197 /* ��������������������� */ 198 if (!IS_ERR(opp)) 199 ret = dev_pm_opp_enable(dev, 1000000000); 200 else 201 goto try_something_else; 202 } 203 204dev_pm_opp_disable 205 ���������OPP��������������������� 206 ���������������1GHz���OPP���������SoC���������������������������������������SoC��������������������� 207 ������������������������:: 208 209 if (cur_temp > temp_high_thresh) { 210 /* ���1GHz��������������������� */ 211 opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true); 212 dev_pm_opp_put(opp); 213 /* ��������������������� */ 214 if (!IS_ERR(opp)) 215 ret = dev_pm_opp_disable(dev, 1000000000); 216 else 217 goto try_something_else; 218 } 219 2205. OPP������������������ 221================== 222������OPP������OPP���������������������������������������������������������������dev_pm_opp������������������ 223������������������������������������������������OPP���������������������������������SoC������������������OPP��� 224������������������������ 225 226dev_pm_opp_get_voltage 227 ������OPP������������������������ 228 ������: ���cpufreq������������������������������SoC���������������������������������OPP������ 229 ������������������������������������������������������:: 230 231 soc_switch_to_freq_voltage(freq) 232 { 233 /* ��������������� */ 234 opp = dev_pm_opp_find_freq_ceil(dev, &freq); 235 v = dev_pm_opp_get_voltage(opp); 236 dev_pm_opp_put(opp); 237 if (v) 238 regulator_set_voltage(.., v); 239 /* ������������ */ 240 } 241 242dev_pm_opp_get_freq 243 ������OPP������������������������ 244 ���������������������SoC������������������������������������������������������������������������OPP 245 ���������������������������������������������������������������������������������:: 246 247 soc_cpufreq_target(..) 248 { 249 /* ���������������.. */ 250 max_freq = ULONG_MAX; 251 max_opp = dev_pm_opp_find_freq_floor(dev,&max_freq); 252 requested_opp = dev_pm_opp_find_freq_ceil(dev,&freq); 253 if (!IS_ERR(max_opp) && !IS_ERR(requested_opp)) 254 r = soc_test_validity(max_opp, requested_opp); 255 dev_pm_opp_put(max_opp); 256 dev_pm_opp_put(requested_opp); 257 /* ������������ */ 258 } 259 soc_test_validity(..) 260 { 261 if(dev_pm_opp_get_voltage(max_opp) < dev_pm_opp_get_voltage(requested_opp)) 262 return -EINVAL; 263 if(dev_pm_opp_get_freq(max_opp) < dev_pm_opp_get_freq(requested_opp)) 264 return -EINVAL; 265 /* ���������������.. */ 266 } 267 268dev_pm_opp_get_opp_count 269 ���������������������������OPP��������� 270 ���������������SoC������������������������������������������������������������������������������������ 271 ���������������������������:: 272 273 soc_notify_coproc_available_frequencies() 274 { 275 /* ��������������� */ 276 num_available = dev_pm_opp_get_opp_count(dev); 277 speeds = kcalloc(num_available, sizeof(u32), GFP_KERNEL); 278 /* ������������������ */ 279 freq = 0; 280 while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) { 281 speeds[i] = freq; 282 freq++; 283 i++; 284 dev_pm_opp_put(opp); 285 } 286 287 soc_notify_coproc(AVAILABLE_FREQs, speeds, num_available); 288 /* ������������ */ 289 } 290 2916. ������������ 292=========== 293���������������SoC������������������������������������������������������������������������OPP��������������������� 294���������������������:: 295 296 SoC 297 |- device 1 298 | |- opp 1 (availability, freq, voltage) 299 | |- opp 2 .. 300 ... ... 301 | `- opp n .. 302 |- device 2 303 ... 304 `- device m 305 306OPP���������������������������������SoC��������������������������������������������������������������������������� 307������OPP���������������������OPP������������������������������������������������������������������������������������ 308 309struct dev_pm_opp 310 OPP���������������������������������������������OPP������������������������������������������������ 311 ������������OPP��������������������������������������������������������������������������������� 312 ���������������SoC������������������������OPP���������������������OPP��������������� 313 314 ��������� 315 ���������dev_pm_opp������������������������������������������������������������������������ 316 dev_pm_opp_add������������OPP���������������dev_pm_opp_enable/disable������ 317 ��������� 318 319struct device 320 ������������OPP���������������������������������������������������������OPP������������������������ 321 ���SoC��������� 322 323������������������������������������������������������������������������������������������������:: 324 325 ��������� / ������: 326 +-----+ /- dev_pm_opp_enable 327 dev_pm_opp_add --> | opp | <------- 328 | +-----+ \- dev_pm_opp_disable 329 \-------> domain_info(device) 330 331 ������������: 332 /-- dev_pm_opp_find_freq_ceil ---\ +-----+ 333 domain_info<---- dev_pm_opp_find_freq_exact -----> | opp | 334 \-- dev_pm_opp_find_freq_floor ---/ +-----+ 335 336 ������������: 337 +-----+ /- dev_pm_opp_get_voltage 338 | opp | <--- 339 +-----+ \- dev_pm_opp_get_freq 340 341 domain_info <- dev_pm_opp_get_opp_count 342