Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.10-rc2 606 lines 16 kB view raw
1/* 2 * Copyright (c) 2015 Linaro Ltd. 3 * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 15#include <linux/clk.h> 16#include <linux/cpu.h> 17#include <linux/cpu_cooling.h> 18#include <linux/cpufreq.h> 19#include <linux/cpumask.h> 20#include <linux/module.h> 21#include <linux/of.h> 22#include <linux/platform_device.h> 23#include <linux/pm_opp.h> 24#include <linux/regulator/consumer.h> 25#include <linux/slab.h> 26#include <linux/thermal.h> 27 28#define MIN_VOLT_SHIFT (100000) 29#define MAX_VOLT_SHIFT (200000) 30#define MAX_VOLT_LIMIT (1150000) 31#define VOLT_TOL (10000) 32 33/* 34 * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS 35 * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in 36 * Mediatek SoCs has two voltage inputs, Vproc and Vsram. In some cases the two 37 * voltage inputs need to be controlled under a hardware limitation: 38 * 100mV < Vsram - Vproc < 200mV 39 * 40 * When scaling the clock frequency of a CPU clock domain, the clock source 41 * needs to be switched to another stable PLL clock temporarily until 42 * the original PLL becomes stable at target frequency. 43 */ 44struct mtk_cpu_dvfs_info { 45 struct cpumask cpus; 46 struct device *cpu_dev; 47 struct regulator *proc_reg; 48 struct regulator *sram_reg; 49 struct clk *cpu_clk; 50 struct clk *inter_clk; 51 struct thermal_cooling_device *cdev; 52 struct list_head list_head; 53 int intermediate_voltage; 54 bool need_voltage_tracking; 55}; 56 57static LIST_HEAD(dvfs_info_list); 58 59static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_lookup(int cpu) 60{ 61 struct mtk_cpu_dvfs_info *info; 62 63 list_for_each_entry(info, &dvfs_info_list, list_head) { 64 if (cpumask_test_cpu(cpu, &info->cpus)) 65 return info; 66 } 67 68 return NULL; 69} 70 71static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info, 72 int new_vproc) 73{ 74 struct regulator *proc_reg = info->proc_reg; 75 struct regulator *sram_reg = info->sram_reg; 76 int old_vproc, old_vsram, new_vsram, vsram, vproc, ret; 77 78 old_vproc = regulator_get_voltage(proc_reg); 79 if (old_vproc < 0) { 80 pr_err("%s: invalid Vproc value: %d\n", __func__, old_vproc); 81 return old_vproc; 82 } 83 /* Vsram should not exceed the maximum allowed voltage of SoC. */ 84 new_vsram = min(new_vproc + MIN_VOLT_SHIFT, MAX_VOLT_LIMIT); 85 86 if (old_vproc < new_vproc) { 87 /* 88 * When scaling up voltages, Vsram and Vproc scale up step 89 * by step. At each step, set Vsram to (Vproc + 200mV) first, 90 * then set Vproc to (Vsram - 100mV). 91 * Keep doing it until Vsram and Vproc hit target voltages. 92 */ 93 do { 94 old_vsram = regulator_get_voltage(sram_reg); 95 if (old_vsram < 0) { 96 pr_err("%s: invalid Vsram value: %d\n", 97 __func__, old_vsram); 98 return old_vsram; 99 } 100 old_vproc = regulator_get_voltage(proc_reg); 101 if (old_vproc < 0) { 102 pr_err("%s: invalid Vproc value: %d\n", 103 __func__, old_vproc); 104 return old_vproc; 105 } 106 107 vsram = min(new_vsram, old_vproc + MAX_VOLT_SHIFT); 108 109 if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) { 110 vsram = MAX_VOLT_LIMIT; 111 112 /* 113 * If the target Vsram hits the maximum voltage, 114 * try to set the exact voltage value first. 115 */ 116 ret = regulator_set_voltage(sram_reg, vsram, 117 vsram); 118 if (ret) 119 ret = regulator_set_voltage(sram_reg, 120 vsram - VOLT_TOL, 121 vsram); 122 123 vproc = new_vproc; 124 } else { 125 ret = regulator_set_voltage(sram_reg, vsram, 126 vsram + VOLT_TOL); 127 128 vproc = vsram - MIN_VOLT_SHIFT; 129 } 130 if (ret) 131 return ret; 132 133 ret = regulator_set_voltage(proc_reg, vproc, 134 vproc + VOLT_TOL); 135 if (ret) { 136 regulator_set_voltage(sram_reg, old_vsram, 137 old_vsram); 138 return ret; 139 } 140 } while (vproc < new_vproc || vsram < new_vsram); 141 } else if (old_vproc > new_vproc) { 142 /* 143 * When scaling down voltages, Vsram and Vproc scale down step 144 * by step. At each step, set Vproc to (Vsram - 200mV) first, 145 * then set Vproc to (Vproc + 100mV). 146 * Keep doing it until Vsram and Vproc hit target voltages. 147 */ 148 do { 149 old_vproc = regulator_get_voltage(proc_reg); 150 if (old_vproc < 0) { 151 pr_err("%s: invalid Vproc value: %d\n", 152 __func__, old_vproc); 153 return old_vproc; 154 } 155 old_vsram = regulator_get_voltage(sram_reg); 156 if (old_vsram < 0) { 157 pr_err("%s: invalid Vsram value: %d\n", 158 __func__, old_vsram); 159 return old_vsram; 160 } 161 162 vproc = max(new_vproc, old_vsram - MAX_VOLT_SHIFT); 163 ret = regulator_set_voltage(proc_reg, vproc, 164 vproc + VOLT_TOL); 165 if (ret) 166 return ret; 167 168 if (vproc == new_vproc) 169 vsram = new_vsram; 170 else 171 vsram = max(new_vsram, vproc + MIN_VOLT_SHIFT); 172 173 if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) { 174 vsram = MAX_VOLT_LIMIT; 175 176 /* 177 * If the target Vsram hits the maximum voltage, 178 * try to set the exact voltage value first. 179 */ 180 ret = regulator_set_voltage(sram_reg, vsram, 181 vsram); 182 if (ret) 183 ret = regulator_set_voltage(sram_reg, 184 vsram - VOLT_TOL, 185 vsram); 186 } else { 187 ret = regulator_set_voltage(sram_reg, vsram, 188 vsram + VOLT_TOL); 189 } 190 191 if (ret) { 192 regulator_set_voltage(proc_reg, old_vproc, 193 old_vproc); 194 return ret; 195 } 196 } while (vproc > new_vproc + VOLT_TOL || 197 vsram > new_vsram + VOLT_TOL); 198 } 199 200 return 0; 201} 202 203static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc) 204{ 205 if (info->need_voltage_tracking) 206 return mtk_cpufreq_voltage_tracking(info, vproc); 207 else 208 return regulator_set_voltage(info->proc_reg, vproc, 209 vproc + VOLT_TOL); 210} 211 212static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, 213 unsigned int index) 214{ 215 struct cpufreq_frequency_table *freq_table = policy->freq_table; 216 struct clk *cpu_clk = policy->clk; 217 struct clk *armpll = clk_get_parent(cpu_clk); 218 struct mtk_cpu_dvfs_info *info = policy->driver_data; 219 struct device *cpu_dev = info->cpu_dev; 220 struct dev_pm_opp *opp; 221 long freq_hz, old_freq_hz; 222 int vproc, old_vproc, inter_vproc, target_vproc, ret; 223 224 inter_vproc = info->intermediate_voltage; 225 226 old_freq_hz = clk_get_rate(cpu_clk); 227 old_vproc = regulator_get_voltage(info->proc_reg); 228 if (old_vproc < 0) { 229 pr_err("%s: invalid Vproc value: %d\n", __func__, old_vproc); 230 return old_vproc; 231 } 232 233 freq_hz = freq_table[index].frequency * 1000; 234 235 rcu_read_lock(); 236 opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz); 237 if (IS_ERR(opp)) { 238 rcu_read_unlock(); 239 pr_err("cpu%d: failed to find OPP for %ld\n", 240 policy->cpu, freq_hz); 241 return PTR_ERR(opp); 242 } 243 vproc = dev_pm_opp_get_voltage(opp); 244 rcu_read_unlock(); 245 246 /* 247 * If the new voltage or the intermediate voltage is higher than the 248 * current voltage, scale up voltage first. 249 */ 250 target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc; 251 if (old_vproc < target_vproc) { 252 ret = mtk_cpufreq_set_voltage(info, target_vproc); 253 if (ret) { 254 pr_err("cpu%d: failed to scale up voltage!\n", 255 policy->cpu); 256 mtk_cpufreq_set_voltage(info, old_vproc); 257 return ret; 258 } 259 } 260 261 /* Reparent the CPU clock to intermediate clock. */ 262 ret = clk_set_parent(cpu_clk, info->inter_clk); 263 if (ret) { 264 pr_err("cpu%d: failed to re-parent cpu clock!\n", 265 policy->cpu); 266 mtk_cpufreq_set_voltage(info, old_vproc); 267 WARN_ON(1); 268 return ret; 269 } 270 271 /* Set the original PLL to target rate. */ 272 ret = clk_set_rate(armpll, freq_hz); 273 if (ret) { 274 pr_err("cpu%d: failed to scale cpu clock rate!\n", 275 policy->cpu); 276 clk_set_parent(cpu_clk, armpll); 277 mtk_cpufreq_set_voltage(info, old_vproc); 278 return ret; 279 } 280 281 /* Set parent of CPU clock back to the original PLL. */ 282 ret = clk_set_parent(cpu_clk, armpll); 283 if (ret) { 284 pr_err("cpu%d: failed to re-parent cpu clock!\n", 285 policy->cpu); 286 mtk_cpufreq_set_voltage(info, inter_vproc); 287 WARN_ON(1); 288 return ret; 289 } 290 291 /* 292 * If the new voltage is lower than the intermediate voltage or the 293 * original voltage, scale down to the new voltage. 294 */ 295 if (vproc < inter_vproc || vproc < old_vproc) { 296 ret = mtk_cpufreq_set_voltage(info, vproc); 297 if (ret) { 298 pr_err("cpu%d: failed to scale down voltage!\n", 299 policy->cpu); 300 clk_set_parent(cpu_clk, info->inter_clk); 301 clk_set_rate(armpll, old_freq_hz); 302 clk_set_parent(cpu_clk, armpll); 303 return ret; 304 } 305 } 306 307 return 0; 308} 309 310#define DYNAMIC_POWER "dynamic-power-coefficient" 311 312static void mtk_cpufreq_ready(struct cpufreq_policy *policy) 313{ 314 struct mtk_cpu_dvfs_info *info = policy->driver_data; 315 struct device_node *np = of_node_get(info->cpu_dev->of_node); 316 u32 capacitance = 0; 317 318 if (WARN_ON(!np)) 319 return; 320 321 if (of_find_property(np, "#cooling-cells", NULL)) { 322 of_property_read_u32(np, DYNAMIC_POWER, &capacitance); 323 324 info->cdev = of_cpufreq_power_cooling_register(np, 325 policy->related_cpus, 326 capacitance, 327 NULL); 328 329 if (IS_ERR(info->cdev)) { 330 dev_err(info->cpu_dev, 331 "running cpufreq without cooling device: %ld\n", 332 PTR_ERR(info->cdev)); 333 334 info->cdev = NULL; 335 } 336 } 337 338 of_node_put(np); 339} 340 341static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) 342{ 343 struct device *cpu_dev; 344 struct regulator *proc_reg = ERR_PTR(-ENODEV); 345 struct regulator *sram_reg = ERR_PTR(-ENODEV); 346 struct clk *cpu_clk = ERR_PTR(-ENODEV); 347 struct clk *inter_clk = ERR_PTR(-ENODEV); 348 struct dev_pm_opp *opp; 349 unsigned long rate; 350 int ret; 351 352 cpu_dev = get_cpu_device(cpu); 353 if (!cpu_dev) { 354 pr_err("failed to get cpu%d device\n", cpu); 355 return -ENODEV; 356 } 357 358 cpu_clk = clk_get(cpu_dev, "cpu"); 359 if (IS_ERR(cpu_clk)) { 360 if (PTR_ERR(cpu_clk) == -EPROBE_DEFER) 361 pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu); 362 else 363 pr_err("failed to get cpu clk for cpu%d\n", cpu); 364 365 ret = PTR_ERR(cpu_clk); 366 return ret; 367 } 368 369 inter_clk = clk_get(cpu_dev, "intermediate"); 370 if (IS_ERR(inter_clk)) { 371 if (PTR_ERR(inter_clk) == -EPROBE_DEFER) 372 pr_warn("intermediate clk for cpu%d not ready, retry.\n", 373 cpu); 374 else 375 pr_err("failed to get intermediate clk for cpu%d\n", 376 cpu); 377 378 ret = PTR_ERR(inter_clk); 379 goto out_free_resources; 380 } 381 382 proc_reg = regulator_get_exclusive(cpu_dev, "proc"); 383 if (IS_ERR(proc_reg)) { 384 if (PTR_ERR(proc_reg) == -EPROBE_DEFER) 385 pr_warn("proc regulator for cpu%d not ready, retry.\n", 386 cpu); 387 else 388 pr_err("failed to get proc regulator for cpu%d\n", 389 cpu); 390 391 ret = PTR_ERR(proc_reg); 392 goto out_free_resources; 393 } 394 395 /* Both presence and absence of sram regulator are valid cases. */ 396 sram_reg = regulator_get_exclusive(cpu_dev, "sram"); 397 398 /* Get OPP-sharing information from "operating-points-v2" bindings */ 399 ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, &info->cpus); 400 if (ret) { 401 pr_err("failed to get OPP-sharing information for cpu%d\n", 402 cpu); 403 goto out_free_resources; 404 } 405 406 ret = dev_pm_opp_of_cpumask_add_table(&info->cpus); 407 if (ret) { 408 pr_warn("no OPP table for cpu%d\n", cpu); 409 goto out_free_resources; 410 } 411 412 /* Search a safe voltage for intermediate frequency. */ 413 rate = clk_get_rate(inter_clk); 414 rcu_read_lock(); 415 opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate); 416 if (IS_ERR(opp)) { 417 rcu_read_unlock(); 418 pr_err("failed to get intermediate opp for cpu%d\n", cpu); 419 ret = PTR_ERR(opp); 420 goto out_free_opp_table; 421 } 422 info->intermediate_voltage = dev_pm_opp_get_voltage(opp); 423 rcu_read_unlock(); 424 425 info->cpu_dev = cpu_dev; 426 info->proc_reg = proc_reg; 427 info->sram_reg = IS_ERR(sram_reg) ? NULL : sram_reg; 428 info->cpu_clk = cpu_clk; 429 info->inter_clk = inter_clk; 430 431 /* 432 * If SRAM regulator is present, software "voltage tracking" is needed 433 * for this CPU power domain. 434 */ 435 info->need_voltage_tracking = !IS_ERR(sram_reg); 436 437 return 0; 438 439out_free_opp_table: 440 dev_pm_opp_of_cpumask_remove_table(&info->cpus); 441 442out_free_resources: 443 if (!IS_ERR(proc_reg)) 444 regulator_put(proc_reg); 445 if (!IS_ERR(sram_reg)) 446 regulator_put(sram_reg); 447 if (!IS_ERR(cpu_clk)) 448 clk_put(cpu_clk); 449 if (!IS_ERR(inter_clk)) 450 clk_put(inter_clk); 451 452 return ret; 453} 454 455static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info) 456{ 457 if (!IS_ERR(info->proc_reg)) 458 regulator_put(info->proc_reg); 459 if (!IS_ERR(info->sram_reg)) 460 regulator_put(info->sram_reg); 461 if (!IS_ERR(info->cpu_clk)) 462 clk_put(info->cpu_clk); 463 if (!IS_ERR(info->inter_clk)) 464 clk_put(info->inter_clk); 465 466 dev_pm_opp_of_cpumask_remove_table(&info->cpus); 467} 468 469static int mtk_cpufreq_init(struct cpufreq_policy *policy) 470{ 471 struct mtk_cpu_dvfs_info *info; 472 struct cpufreq_frequency_table *freq_table; 473 int ret; 474 475 info = mtk_cpu_dvfs_info_lookup(policy->cpu); 476 if (!info) { 477 pr_err("dvfs info for cpu%d is not initialized.\n", 478 policy->cpu); 479 return -EINVAL; 480 } 481 482 ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table); 483 if (ret) { 484 pr_err("failed to init cpufreq table for cpu%d: %d\n", 485 policy->cpu, ret); 486 return ret; 487 } 488 489 ret = cpufreq_table_validate_and_show(policy, freq_table); 490 if (ret) { 491 pr_err("%s: invalid frequency table: %d\n", __func__, ret); 492 goto out_free_cpufreq_table; 493 } 494 495 cpumask_copy(policy->cpus, &info->cpus); 496 policy->driver_data = info; 497 policy->clk = info->cpu_clk; 498 499 return 0; 500 501out_free_cpufreq_table: 502 dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table); 503 return ret; 504} 505 506static int mtk_cpufreq_exit(struct cpufreq_policy *policy) 507{ 508 struct mtk_cpu_dvfs_info *info = policy->driver_data; 509 510 cpufreq_cooling_unregister(info->cdev); 511 dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table); 512 513 return 0; 514} 515 516static struct cpufreq_driver mt8173_cpufreq_driver = { 517 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK | 518 CPUFREQ_HAVE_GOVERNOR_PER_POLICY, 519 .verify = cpufreq_generic_frequency_table_verify, 520 .target_index = mtk_cpufreq_set_target, 521 .get = cpufreq_generic_get, 522 .init = mtk_cpufreq_init, 523 .exit = mtk_cpufreq_exit, 524 .ready = mtk_cpufreq_ready, 525 .name = "mtk-cpufreq", 526 .attr = cpufreq_generic_attr, 527}; 528 529static int mt8173_cpufreq_probe(struct platform_device *pdev) 530{ 531 struct mtk_cpu_dvfs_info *info, *tmp; 532 int cpu, ret; 533 534 for_each_possible_cpu(cpu) { 535 info = mtk_cpu_dvfs_info_lookup(cpu); 536 if (info) 537 continue; 538 539 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 540 if (!info) { 541 ret = -ENOMEM; 542 goto release_dvfs_info_list; 543 } 544 545 ret = mtk_cpu_dvfs_info_init(info, cpu); 546 if (ret) { 547 dev_err(&pdev->dev, 548 "failed to initialize dvfs info for cpu%d\n", 549 cpu); 550 goto release_dvfs_info_list; 551 } 552 553 list_add(&info->list_head, &dvfs_info_list); 554 } 555 556 ret = cpufreq_register_driver(&mt8173_cpufreq_driver); 557 if (ret) { 558 dev_err(&pdev->dev, "failed to register mtk cpufreq driver\n"); 559 goto release_dvfs_info_list; 560 } 561 562 return 0; 563 564release_dvfs_info_list: 565 list_for_each_entry_safe(info, tmp, &dvfs_info_list, list_head) { 566 mtk_cpu_dvfs_info_release(info); 567 list_del(&info->list_head); 568 } 569 570 return ret; 571} 572 573static struct platform_driver mt8173_cpufreq_platdrv = { 574 .driver = { 575 .name = "mt8173-cpufreq", 576 }, 577 .probe = mt8173_cpufreq_probe, 578}; 579 580static int mt8173_cpufreq_driver_init(void) 581{ 582 struct platform_device *pdev; 583 int err; 584 585 if (!of_machine_is_compatible("mediatek,mt8173")) 586 return -ENODEV; 587 588 err = platform_driver_register(&mt8173_cpufreq_platdrv); 589 if (err) 590 return err; 591 592 /* 593 * Since there's no place to hold device registration code and no 594 * device tree based way to match cpufreq driver yet, both the driver 595 * and the device registration codes are put here to handle defer 596 * probing. 597 */ 598 pdev = platform_device_register_simple("mt8173-cpufreq", -1, NULL, 0); 599 if (IS_ERR(pdev)) { 600 pr_err("failed to register mtk-cpufreq platform device\n"); 601 return PTR_ERR(pdev); 602 } 603 604 return 0; 605} 606device_initcall(mt8173_cpufreq_driver_init);