533 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2013 Freescale Semiconductor, Inc.4 */5 6#include <linux/clk.h>7#include <linux/cpu.h>8#include <linux/cpufreq.h>9#include <linux/err.h>10#include <linux/module.h>11#include <linux/nvmem-consumer.h>12#include <linux/of.h>13#include <linux/of_address.h>14#include <linux/pm_opp.h>15#include <linux/platform_device.h>16#include <linux/regulator/consumer.h>17#include <linux/mfd/syscon.h>18#include <linux/regmap.h>19 20#define PU_SOC_VOLTAGE_NORMAL 125000021#define PU_SOC_VOLTAGE_HIGH 127500022#define FREQ_1P2_GHZ 120000000023 24static struct regulator *arm_reg;25static struct regulator *pu_reg;26static struct regulator *soc_reg;27 28enum IMX6_CPUFREQ_CLKS {29 ARM,30 PLL1_SYS,31 STEP,32 PLL1_SW,33 PLL2_PFD2_396M,34 /* MX6UL requires two more clks */35 PLL2_BUS,36 SECONDARY_SEL,37};38#define IMX6Q_CPUFREQ_CLK_NUM 539#define IMX6UL_CPUFREQ_CLK_NUM 740 41static int num_clks;42static struct clk_bulk_data clks[] = {43 { .id = "arm" },44 { .id = "pll1_sys" },45 { .id = "step" },46 { .id = "pll1_sw" },47 { .id = "pll2_pfd2_396m" },48 { .id = "pll2_bus" },49 { .id = "secondary_sel" },50};51 52static struct device *cpu_dev;53static struct cpufreq_frequency_table *freq_table;54static unsigned int max_freq;55static unsigned int transition_latency;56 57static u32 *imx6_soc_volt;58static u32 soc_opp_count;59 60static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)61{62 struct dev_pm_opp *opp;63 unsigned long freq_hz, volt, volt_old;64 unsigned int old_freq, new_freq;65 bool pll1_sys_temp_enabled = false;66 int ret;67 68 new_freq = freq_table[index].frequency;69 freq_hz = new_freq * 1000;70 old_freq = clk_get_rate(clks[ARM].clk) / 1000;71 72 opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);73 if (IS_ERR(opp)) {74 dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);75 return PTR_ERR(opp);76 }77 78 volt = dev_pm_opp_get_voltage(opp);79 dev_pm_opp_put(opp);80 81 volt_old = regulator_get_voltage(arm_reg);82 83 dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",84 old_freq / 1000, volt_old / 1000,85 new_freq / 1000, volt / 1000);86 87 /* scaling up? scale voltage before frequency */88 if (new_freq > old_freq) {89 if (!IS_ERR(pu_reg)) {90 ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);91 if (ret) {92 dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);93 return ret;94 }95 }96 ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);97 if (ret) {98 dev_err(cpu_dev, "failed to scale vddsoc up: %d\n", ret);99 return ret;100 }101 ret = regulator_set_voltage_tol(arm_reg, volt, 0);102 if (ret) {103 dev_err(cpu_dev,104 "failed to scale vddarm up: %d\n", ret);105 return ret;106 }107 }108 109 /*110 * The setpoints are selected per PLL/PDF frequencies, so we need to111 * reprogram PLL for frequency scaling. The procedure of reprogramming112 * PLL1 is as below.113 * For i.MX6UL, it has a secondary clk mux, the cpu frequency change114 * flow is slightly different from other i.MX6 OSC.115 * The cpu frequeny change flow for i.MX6(except i.MX6UL) is as below:116 * - Enable pll2_pfd2_396m_clk and reparent pll1_sw_clk to it117 * - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it118 * - Disable pll2_pfd2_396m_clk119 */120 if (of_machine_is_compatible("fsl,imx6ul") ||121 of_machine_is_compatible("fsl,imx6ull")) {122 /*123 * When changing pll1_sw_clk's parent to pll1_sys_clk,124 * CPU may run at higher than 528MHz, this will lead to125 * the system unstable if the voltage is lower than the126 * voltage of 528MHz, so lower the CPU frequency to one127 * half before changing CPU frequency.128 */129 clk_set_rate(clks[ARM].clk, (old_freq >> 1) * 1000);130 clk_set_parent(clks[PLL1_SW].clk, clks[PLL1_SYS].clk);131 if (freq_hz > clk_get_rate(clks[PLL2_PFD2_396M].clk))132 clk_set_parent(clks[SECONDARY_SEL].clk,133 clks[PLL2_BUS].clk);134 else135 clk_set_parent(clks[SECONDARY_SEL].clk,136 clks[PLL2_PFD2_396M].clk);137 clk_set_parent(clks[STEP].clk, clks[SECONDARY_SEL].clk);138 clk_set_parent(clks[PLL1_SW].clk, clks[STEP].clk);139 if (freq_hz > clk_get_rate(clks[PLL2_BUS].clk)) {140 clk_set_rate(clks[PLL1_SYS].clk, new_freq * 1000);141 clk_set_parent(clks[PLL1_SW].clk, clks[PLL1_SYS].clk);142 }143 } else {144 clk_set_parent(clks[STEP].clk, clks[PLL2_PFD2_396M].clk);145 clk_set_parent(clks[PLL1_SW].clk, clks[STEP].clk);146 if (freq_hz > clk_get_rate(clks[PLL2_PFD2_396M].clk)) {147 clk_set_rate(clks[PLL1_SYS].clk, new_freq * 1000);148 clk_set_parent(clks[PLL1_SW].clk, clks[PLL1_SYS].clk);149 } else {150 /* pll1_sys needs to be enabled for divider rate change to work. */151 pll1_sys_temp_enabled = true;152 clk_prepare_enable(clks[PLL1_SYS].clk);153 }154 }155 156 /* Ensure the arm clock divider is what we expect */157 ret = clk_set_rate(clks[ARM].clk, new_freq * 1000);158 if (ret) {159 int ret1;160 161 dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);162 ret1 = regulator_set_voltage_tol(arm_reg, volt_old, 0);163 if (ret1)164 dev_warn(cpu_dev,165 "failed to restore vddarm voltage: %d\n", ret1);166 return ret;167 }168 169 /* PLL1 is only needed until after ARM-PODF is set. */170 if (pll1_sys_temp_enabled)171 clk_disable_unprepare(clks[PLL1_SYS].clk);172 173 /* scaling down? scale voltage after frequency */174 if (new_freq < old_freq) {175 ret = regulator_set_voltage_tol(arm_reg, volt, 0);176 if (ret)177 dev_warn(cpu_dev,178 "failed to scale vddarm down: %d\n", ret);179 ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);180 if (ret)181 dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);182 if (!IS_ERR(pu_reg)) {183 ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);184 if (ret)185 dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);186 }187 }188 189 return 0;190}191 192static int imx6q_cpufreq_init(struct cpufreq_policy *policy)193{194 policy->clk = clks[ARM].clk;195 cpufreq_generic_init(policy, freq_table, transition_latency);196 policy->suspend_freq = max_freq;197 198 return 0;199}200 201static struct cpufreq_driver imx6q_cpufreq_driver = {202 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |203 CPUFREQ_IS_COOLING_DEV,204 .verify = cpufreq_generic_frequency_table_verify,205 .target_index = imx6q_set_target,206 .get = cpufreq_generic_get,207 .init = imx6q_cpufreq_init,208 .register_em = cpufreq_register_em_with_opp,209 .name = "imx6q-cpufreq",210 .attr = cpufreq_generic_attr,211 .suspend = cpufreq_generic_suspend,212};213 214static void imx6x_disable_freq_in_opp(struct device *dev, unsigned long freq)215{216 int ret = dev_pm_opp_disable(dev, freq);217 218 if (ret < 0 && ret != -ENODEV)219 dev_warn(dev, "failed to disable %ldMHz OPP\n", freq / 1000000);220}221 222#define OCOTP_CFG3 0x440223#define OCOTP_CFG3_SPEED_SHIFT 16224#define OCOTP_CFG3_SPEED_1P2GHZ 0x3225#define OCOTP_CFG3_SPEED_996MHZ 0x2226#define OCOTP_CFG3_SPEED_852MHZ 0x1227 228static int imx6q_opp_check_speed_grading(struct device *dev)229{230 u32 val;231 int ret;232 233 if (of_property_present(dev->of_node, "nvmem-cells")) {234 ret = nvmem_cell_read_u32(dev, "speed_grade", &val);235 if (ret)236 return ret;237 } else {238 struct regmap *ocotp;239 240 ocotp = syscon_regmap_lookup_by_compatible("fsl,imx6q-ocotp");241 if (IS_ERR(ocotp))242 return -ENOENT;243 244 /*245 * SPEED_GRADING[1:0] defines the max speed of ARM:246 * 2b'11: 1200000000Hz;247 * 2b'10: 996000000Hz;248 * 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.249 * 2b'00: 792000000Hz;250 * We need to set the max speed of ARM according to fuse map.251 */252 regmap_read(ocotp, OCOTP_CFG3, &val);253 }254 255 val >>= OCOTP_CFG3_SPEED_SHIFT;256 val &= 0x3;257 258 if (val < OCOTP_CFG3_SPEED_996MHZ)259 imx6x_disable_freq_in_opp(dev, 996000000);260 261 if (of_machine_is_compatible("fsl,imx6q") ||262 of_machine_is_compatible("fsl,imx6qp")) {263 if (val != OCOTP_CFG3_SPEED_852MHZ)264 imx6x_disable_freq_in_opp(dev, 852000000);265 266 if (val != OCOTP_CFG3_SPEED_1P2GHZ)267 imx6x_disable_freq_in_opp(dev, 1200000000);268 }269 270 return 0;271}272 273#define OCOTP_CFG3_6UL_SPEED_696MHZ 0x2274#define OCOTP_CFG3_6ULL_SPEED_792MHZ 0x2275#define OCOTP_CFG3_6ULL_SPEED_900MHZ 0x3276 277static int imx6ul_opp_check_speed_grading(struct device *dev)278{279 u32 val;280 int ret = 0;281 282 if (of_property_present(dev->of_node, "nvmem-cells")) {283 ret = nvmem_cell_read_u32(dev, "speed_grade", &val);284 if (ret)285 return ret;286 } else {287 struct regmap *ocotp;288 289 ocotp = syscon_regmap_lookup_by_compatible("fsl,imx6ul-ocotp");290 if (IS_ERR(ocotp))291 ocotp = syscon_regmap_lookup_by_compatible("fsl,imx6ull-ocotp");292 293 if (IS_ERR(ocotp))294 return -ENOENT;295 296 regmap_read(ocotp, OCOTP_CFG3, &val);297 }298 299 /*300 * Speed GRADING[1:0] defines the max speed of ARM:301 * 2b'00: Reserved;302 * 2b'01: 528000000Hz;303 * 2b'10: 696000000Hz on i.MX6UL, 792000000Hz on i.MX6ULL;304 * 2b'11: 900000000Hz on i.MX6ULL only;305 * We need to set the max speed of ARM according to fuse map.306 */307 val >>= OCOTP_CFG3_SPEED_SHIFT;308 val &= 0x3;309 310 if (of_machine_is_compatible("fsl,imx6ul"))311 if (val != OCOTP_CFG3_6UL_SPEED_696MHZ)312 imx6x_disable_freq_in_opp(dev, 696000000);313 314 if (of_machine_is_compatible("fsl,imx6ull")) {315 if (val < OCOTP_CFG3_6ULL_SPEED_792MHZ)316 imx6x_disable_freq_in_opp(dev, 792000000);317 318 if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ)319 imx6x_disable_freq_in_opp(dev, 900000000);320 }321 322 return ret;323}324 325static int imx6q_cpufreq_probe(struct platform_device *pdev)326{327 struct device_node *np;328 struct dev_pm_opp *opp;329 unsigned long min_volt, max_volt;330 int num, ret;331 const struct property *prop;332 const __be32 *val;333 u32 nr, i, j;334 335 cpu_dev = get_cpu_device(0);336 if (!cpu_dev) {337 pr_err("failed to get cpu0 device\n");338 return -ENODEV;339 }340 341 np = of_node_get(cpu_dev->of_node);342 if (!np) {343 dev_err(cpu_dev, "failed to find cpu0 node\n");344 return -ENOENT;345 }346 347 if (of_machine_is_compatible("fsl,imx6ul") ||348 of_machine_is_compatible("fsl,imx6ull"))349 num_clks = IMX6UL_CPUFREQ_CLK_NUM;350 else351 num_clks = IMX6Q_CPUFREQ_CLK_NUM;352 353 ret = clk_bulk_get(cpu_dev, num_clks, clks);354 if (ret)355 goto put_node;356 357 arm_reg = regulator_get(cpu_dev, "arm");358 pu_reg = regulator_get_optional(cpu_dev, "pu");359 soc_reg = regulator_get(cpu_dev, "soc");360 if (PTR_ERR(arm_reg) == -EPROBE_DEFER ||361 PTR_ERR(soc_reg) == -EPROBE_DEFER ||362 PTR_ERR(pu_reg) == -EPROBE_DEFER) {363 ret = -EPROBE_DEFER;364 dev_dbg(cpu_dev, "regulators not ready, defer\n");365 goto put_reg;366 }367 if (IS_ERR(arm_reg) || IS_ERR(soc_reg)) {368 dev_err(cpu_dev, "failed to get regulators\n");369 ret = -ENOENT;370 goto put_reg;371 }372 373 ret = dev_pm_opp_of_add_table(cpu_dev);374 if (ret < 0) {375 dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);376 goto put_reg;377 }378 379 if (of_machine_is_compatible("fsl,imx6ul") ||380 of_machine_is_compatible("fsl,imx6ull")) {381 ret = imx6ul_opp_check_speed_grading(cpu_dev);382 } else {383 ret = imx6q_opp_check_speed_grading(cpu_dev);384 }385 if (ret) {386 dev_err_probe(cpu_dev, ret, "failed to read ocotp\n");387 goto out_free_opp;388 }389 390 num = dev_pm_opp_get_opp_count(cpu_dev);391 if (num < 0) {392 ret = num;393 dev_err(cpu_dev, "no OPP table is found: %d\n", ret);394 goto out_free_opp;395 }396 397 ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);398 if (ret) {399 dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);400 goto out_free_opp;401 }402 403 /* Make imx6_soc_volt array's size same as arm opp number */404 imx6_soc_volt = devm_kcalloc(cpu_dev, num, sizeof(*imx6_soc_volt),405 GFP_KERNEL);406 if (imx6_soc_volt == NULL) {407 ret = -ENOMEM;408 goto free_freq_table;409 }410 411 prop = of_find_property(np, "fsl,soc-operating-points", NULL);412 if (!prop || !prop->value)413 goto soc_opp_out;414 415 /*416 * Each OPP is a set of tuples consisting of frequency and417 * voltage like <freq-kHz vol-uV>.418 */419 nr = prop->length / sizeof(u32);420 if (nr % 2 || (nr / 2) < num)421 goto soc_opp_out;422 423 for (j = 0; j < num; j++) {424 val = prop->value;425 for (i = 0; i < nr / 2; i++) {426 unsigned long freq = be32_to_cpup(val++);427 unsigned long volt = be32_to_cpup(val++);428 if (freq_table[j].frequency == freq) {429 imx6_soc_volt[soc_opp_count++] = volt;430 break;431 }432 }433 }434 435soc_opp_out:436 /* use fixed soc opp volt if no valid soc opp info found in dtb */437 if (soc_opp_count != num) {438 dev_warn(cpu_dev, "can NOT find valid fsl,soc-operating-points property in dtb, use default value!\n");439 for (j = 0; j < num; j++)440 imx6_soc_volt[j] = PU_SOC_VOLTAGE_NORMAL;441 if (freq_table[num - 1].frequency * 1000 == FREQ_1P2_GHZ)442 imx6_soc_volt[num - 1] = PU_SOC_VOLTAGE_HIGH;443 }444 445 if (of_property_read_u32(np, "clock-latency", &transition_latency))446 transition_latency = CPUFREQ_ETERNAL;447 448 /*449 * Calculate the ramp time for max voltage change in the450 * VDDSOC and VDDPU regulators.451 */452 ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);453 if (ret > 0)454 transition_latency += ret * 1000;455 if (!IS_ERR(pu_reg)) {456 ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);457 if (ret > 0)458 transition_latency += ret * 1000;459 }460 461 /*462 * OPP is maintained in order of increasing frequency, and463 * freq_table initialised from OPP is therefore sorted in the464 * same order.465 */466 max_freq = freq_table[--num].frequency;467 opp = dev_pm_opp_find_freq_exact(cpu_dev,468 freq_table[0].frequency * 1000, true);469 min_volt = dev_pm_opp_get_voltage(opp);470 dev_pm_opp_put(opp);471 opp = dev_pm_opp_find_freq_exact(cpu_dev, max_freq * 1000, true);472 max_volt = dev_pm_opp_get_voltage(opp);473 dev_pm_opp_put(opp);474 475 ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt);476 if (ret > 0)477 transition_latency += ret * 1000;478 479 ret = cpufreq_register_driver(&imx6q_cpufreq_driver);480 if (ret) {481 dev_err(cpu_dev, "failed register driver: %d\n", ret);482 goto free_freq_table;483 }484 485 of_node_put(np);486 return 0;487 488free_freq_table:489 dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);490out_free_opp:491 dev_pm_opp_of_remove_table(cpu_dev);492put_reg:493 if (!IS_ERR(arm_reg))494 regulator_put(arm_reg);495 if (!IS_ERR(pu_reg))496 regulator_put(pu_reg);497 if (!IS_ERR(soc_reg))498 regulator_put(soc_reg);499 500 clk_bulk_put(num_clks, clks);501put_node:502 of_node_put(np);503 504 return ret;505}506 507static void imx6q_cpufreq_remove(struct platform_device *pdev)508{509 cpufreq_unregister_driver(&imx6q_cpufreq_driver);510 dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);511 dev_pm_opp_of_remove_table(cpu_dev);512 regulator_put(arm_reg);513 if (!IS_ERR(pu_reg))514 regulator_put(pu_reg);515 regulator_put(soc_reg);516 517 clk_bulk_put(num_clks, clks);518}519 520static struct platform_driver imx6q_cpufreq_platdrv = {521 .driver = {522 .name = "imx6q-cpufreq",523 },524 .probe = imx6q_cpufreq_probe,525 .remove_new = imx6q_cpufreq_remove,526};527module_platform_driver(imx6q_cpufreq_platdrv);528 529MODULE_ALIAS("platform:imx6q-cpufreq");530MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");531MODULE_DESCRIPTION("Freescale i.MX6Q cpufreq driver");532MODULE_LICENSE("GPL");533