···3333 compatible = "marvell,armada-3700-nb-pm", "syscon";3434 reg = <0x14000 0x60>;3535}3636+3737+AVS3838+---3939+4040+For AVS an other component is needed:4141+4242+Required properties:4343+- compatible : should contain "marvell,armada-3700-avs", "syscon";4444+- reg : the register start and length for the AVS4545+4646+Example:4747+avs: avs@11500 {4848+ compatible = "marvell,armada-3700-avs", "syscon";4949+ reg = <0x11500 0x40>;5050+}
+160-3
drivers/cpufreq/armada-37xx-cpufreq.c
···5151#define ARMADA_37XX_DVFS_LOAD_2 25252#define ARMADA_37XX_DVFS_LOAD_3 353535454+/* AVS register set */5555+#define ARMADA_37XX_AVS_CTL0 0x05656+#define ARMADA_37XX_AVS_ENABLE BIT(30)5757+#define ARMADA_37XX_AVS_HIGH_VDD_LIMIT 165858+#define ARMADA_37XX_AVS_LOW_VDD_LIMIT 225959+#define ARMADA_37XX_AVS_VDD_MASK 0x3F6060+#define ARMADA_37XX_AVS_CTL2 0x86161+#define ARMADA_37XX_AVS_LOW_VDD_EN BIT(6)6262+#define ARMADA_37XX_AVS_VSET(x) (0x1C + 4 * (x))6363+5464/*5565 * On Armada 37xx the Power management manages 4 level of CPU load,5666 * each level can be associated with a CPU clock source, a CPU5767 * divider, a VDD level, etc...5868 */5969#define LOAD_LEVEL_NR 47070+7171+#define MIN_VOLT_MV 10007272+7373+/* AVS value for the corresponding voltage (in mV) */7474+static int avs_map[] = {7575+ 747, 758, 770, 782, 793, 805, 817, 828, 840, 852, 863, 875, 887, 898,7676+ 910, 922, 933, 945, 957, 968, 980, 992, 1003, 1015, 1027, 1038, 1050,7777+ 1062, 1073, 1085, 1097, 1108, 1120, 1132, 1143, 1155, 1167, 1178, 1190,7878+ 1202, 1213, 1225, 1237, 1248, 1260, 1272, 1283, 1295, 1307, 1318, 1330,7979+ 13428080+};60816182struct armada37xx_cpufreq_state {6283 struct regmap *regmap;···9271struct armada_37xx_dvfs {9372 u32 cpu_freq_max;9473 u8 divider[LOAD_LEVEL_NR];7474+ u32 avs[LOAD_LEVEL_NR];9575};96769777static struct armada_37xx_dvfs armada_37xx_dvfs[] = {···170148 clk_set_parent(clk, parent);171149}172150151151+/*152152+ * Find out the armada 37x supported AVS value whose voltage value is153153+ * the round-up closest to the target voltage value.154154+ */155155+static u32 armada_37xx_avs_val_match(int target_vm)156156+{157157+ u32 avs;158158+159159+ /* Find out the round-up closest supported voltage value */160160+ for (avs = 0; avs < ARRAY_SIZE(avs_map); avs++)161161+ if (avs_map[avs] >= target_vm)162162+ break;163163+164164+ /*165165+ * If all supported voltages are smaller than target one,166166+ * choose the largest supported voltage167167+ */168168+ if (avs == ARRAY_SIZE(avs_map))169169+ avs = ARRAY_SIZE(avs_map) - 1;170170+171171+ return avs;172172+}173173+174174+/*175175+ * For Armada 37xx soc, L0(VSET0) VDD AVS value is set to SVC revision176176+ * value or a default value when SVC is not supported.177177+ * - L0 can be read out from the register of AVS_CTRL_0 and L0 voltage178178+ * can be got from the mapping table of avs_map.179179+ * - L1 voltage should be about 100mv smaller than L0 voltage180180+ * - L2 & L3 voltage should be about 150mv smaller than L0 voltage.181181+ * This function calculates L1 & L2 & L3 AVS values dynamically based182182+ * on L0 voltage and fill all AVS values to the AVS value table.183183+ */184184+static void __init armada37xx_cpufreq_avs_configure(struct regmap *base,185185+ struct armada_37xx_dvfs *dvfs)186186+{187187+ unsigned int target_vm;188188+ int load_level = 0;189189+ u32 l0_vdd_min;190190+191191+ if (base == NULL)192192+ return;193193+194194+ /* Get L0 VDD min value */195195+ regmap_read(base, ARMADA_37XX_AVS_CTL0, &l0_vdd_min);196196+ l0_vdd_min = (l0_vdd_min >> ARMADA_37XX_AVS_LOW_VDD_LIMIT) &197197+ ARMADA_37XX_AVS_VDD_MASK;198198+ if (l0_vdd_min >= ARRAY_SIZE(avs_map)) {199199+ pr_err("L0 VDD MIN %d is not correct.\n", l0_vdd_min);200200+ return;201201+ }202202+ dvfs->avs[0] = l0_vdd_min;203203+204204+ if (avs_map[l0_vdd_min] <= MIN_VOLT_MV) {205205+ /*206206+ * If L0 voltage is smaller than 1000mv, then all VDD sets207207+ * use L0 voltage;208208+ */209209+ u32 avs_min = armada_37xx_avs_val_match(MIN_VOLT_MV);210210+211211+ for (load_level = 1; load_level < LOAD_LEVEL_NR; load_level++)212212+ dvfs->avs[load_level] = avs_min;213213+214214+ return;215215+ }216216+217217+ /*218218+ * L1 voltage is equal to L0 voltage - 100mv and it must be219219+ * larger than 1000mv220220+ */221221+222222+ target_vm = avs_map[l0_vdd_min] - 100;223223+ target_vm = target_vm > MIN_VOLT_MV ? target_vm : MIN_VOLT_MV;224224+ dvfs->avs[1] = armada_37xx_avs_val_match(target_vm);225225+226226+ /*227227+ * L2 & L3 voltage is equal to L0 voltage - 150mv and it must228228+ * be larger than 1000mv229229+ */230230+ target_vm = avs_map[l0_vdd_min] - 150;231231+ target_vm = target_vm > MIN_VOLT_MV ? target_vm : MIN_VOLT_MV;232232+ dvfs->avs[2] = dvfs->avs[3] = armada_37xx_avs_val_match(target_vm);233233+}234234+235235+static void __init armada37xx_cpufreq_avs_setup(struct regmap *base,236236+ struct armada_37xx_dvfs *dvfs)237237+{238238+ unsigned int avs_val = 0, freq;239239+ int load_level = 0;240240+241241+ if (base == NULL)242242+ return;243243+244244+ /* Disable AVS before the configuration */245245+ regmap_update_bits(base, ARMADA_37XX_AVS_CTL0,246246+ ARMADA_37XX_AVS_ENABLE, 0);247247+248248+249249+ /* Enable low voltage mode */250250+ regmap_update_bits(base, ARMADA_37XX_AVS_CTL2,251251+ ARMADA_37XX_AVS_LOW_VDD_EN,252252+ ARMADA_37XX_AVS_LOW_VDD_EN);253253+254254+255255+ for (load_level = 1; load_level < LOAD_LEVEL_NR; load_level++) {256256+ freq = dvfs->cpu_freq_max / dvfs->divider[load_level];257257+258258+ avs_val = dvfs->avs[load_level];259259+ regmap_update_bits(base, ARMADA_37XX_AVS_VSET(load_level-1),260260+ ARMADA_37XX_AVS_VDD_MASK << ARMADA_37XX_AVS_HIGH_VDD_LIMIT |261261+ ARMADA_37XX_AVS_VDD_MASK << ARMADA_37XX_AVS_LOW_VDD_LIMIT,262262+ avs_val << ARMADA_37XX_AVS_HIGH_VDD_LIMIT |263263+ avs_val << ARMADA_37XX_AVS_LOW_VDD_LIMIT);264264+ }265265+266266+ /* Enable AVS after the configuration */267267+ regmap_update_bits(base, ARMADA_37XX_AVS_CTL0,268268+ ARMADA_37XX_AVS_ENABLE,269269+ ARMADA_37XX_AVS_ENABLE);270270+271271+}272272+173273static void armada37xx_cpufreq_disable_dvfs(struct regmap *base)174274{175275 unsigned int reg = ARMADA_37XX_NB_DYN_MOD,···360216 struct platform_device *pdev;361217 unsigned long freq;362218 unsigned int cur_frequency;363363- struct regmap *nb_pm_base;219219+ struct regmap *nb_pm_base, *avs_base;364220 struct device *cpu_dev;365221 int load_lvl, ret;366222 struct clk *clk;···371227 if (IS_ERR(nb_pm_base))372228 return -ENODEV;373229230230+ avs_base =231231+ syscon_regmap_lookup_by_compatible("marvell,armada-3700-avs");232232+233233+ /* if AVS is not present don't use it but still try to setup dvfs */234234+ if (IS_ERR(avs_base)) {235235+ pr_info("Syscon failed for Adapting Voltage Scaling: skip it\n");236236+ avs_base = NULL;237237+ }374238 /* Before doing any configuration on the DVFS first, disable it */375239 armada37xx_cpufreq_disable_dvfs(nb_pm_base);376240···422270423271 armada37xx_cpufreq_state->regmap = nb_pm_base;424272273273+ armada37xx_cpufreq_avs_configure(avs_base, dvfs);274274+ armada37xx_cpufreq_avs_setup(avs_base, dvfs);275275+425276 armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider);426277 clk_put(clk);427278428279 for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;429280 load_lvl++) {281281+ unsigned long u_volt = avs_map[dvfs->avs[load_lvl]] * 1000;430282 freq = cur_frequency / dvfs->divider[load_lvl];431431-432432- ret = dev_pm_opp_add(cpu_dev, freq, 0);283283+ ret = dev_pm_opp_add(cpu_dev, freq, u_volt);433284 if (ret)434285 goto remove_opp;286286+287287+435288 }436289437290 /* Now that everything is setup, enable the DVFS at hardware level */
···657657{658658 struct cpudata *cpu_data = all_cpu_data[policy->cpu];659659 char str_preference[21];660660- int ret, i = 0;660660+ int ret;661661662662 ret = sscanf(buf, "%20s", str_preference);663663 if (ret != 1)664664 return -EINVAL;665665666666- while (energy_perf_strings[i] != NULL) {667667- if (!strcmp(str_preference, energy_perf_strings[i])) {668668- intel_pstate_set_energy_pref_index(cpu_data, i);669669- return count;670670- }671671- ++i;672672- }666666+ ret = match_string(energy_perf_strings, -1, str_preference);667667+ if (ret < 0)668668+ return ret;673669674674- return -EINVAL;670670+ intel_pstate_set_energy_pref_index(cpu_data, ret);671671+ return count;675672}676673677674static ssize_t show_energy_performance_preference(···20682071 policy->cpuinfo.max_freq = global.turbo_disabled ?20692072 cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;20702073 policy->cpuinfo.max_freq *= cpu->pstate.scaling;20742074+20752075+ if (hwp_active) {20762076+ unsigned int max_freq;20772077+20782078+ max_freq = global.turbo_disabled ?20792079+ cpu->pstate.max_freq : cpu->pstate.turbo_freq;20802080+ if (max_freq < policy->cpuinfo.max_freq)20812081+ policy->cpuinfo.max_freq = max_freq;20822082+ }2071208320722084 intel_pstate_init_acpi_perf_limits(policy);20732085
+9
drivers/cpufreq/pcc-cpufreq.c
···593593 return ret;594594 }595595596596+ if (num_present_cpus() > 4) {597597+ pcc_cpufreq_driver.flags |= CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING;598598+ pr_err("%s: Too many CPUs, dynamic performance scaling disabled\n",599599+ __func__);600600+ pr_err("%s: Try to enable another scaling driver through BIOS settings\n",601601+ __func__);602602+ pr_err("%s: and complain to the system vendor\n", __func__);603603+ }604604+596605 ret = cpufreq_register_driver(&pcc_cpufreq_driver);597606598607 return ret;
+3-2
drivers/cpufreq/qcom-cpufreq-kryo.c
···109109 speedbin_nvmem = of_nvmem_cell_get(np, NULL);110110 of_node_put(np);111111 if (IS_ERR(speedbin_nvmem)) {112112- dev_err(cpu_dev, "Could not get nvmem cell: %ld\n",113113- PTR_ERR(speedbin_nvmem));112112+ if (PTR_ERR(speedbin_nvmem) != -EPROBE_DEFER)113113+ dev_err(cpu_dev, "Could not get nvmem cell: %ld\n",114114+ PTR_ERR(speedbin_nvmem));114115 return PTR_ERR(speedbin_nvmem);115116 }116117
+24-4
drivers/thermal/imx_thermal.c
···33// Copyright 2013 Freescale Semiconductor, Inc.4455#include <linux/clk.h>66+#include <linux/cpu.h>67#include <linux/cpufreq.h>78#include <linux/cpu_cooling.h>89#include <linux/delay.h>···645644};646645MODULE_DEVICE_TABLE(of, of_imx_thermal_match);647646647647+/*648648+ * Create cooling device in case no #cooling-cells property is available in649649+ * CPU node650650+ */651651+static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)652652+{653653+ struct device_node *np = of_get_cpu_node(data->policy->cpu, NULL);654654+ int ret;655655+656656+ if (!np || !of_find_property(np, "#cooling-cells", NULL)) {657657+ data->cdev = cpufreq_cooling_register(data->policy);658658+ if (IS_ERR(data->cdev)) {659659+ ret = PTR_ERR(data->cdev);660660+ cpufreq_cpu_put(data->policy);661661+ return ret;662662+ }663663+ }664664+665665+ return 0;666666+}667667+648668static int imx_thermal_probe(struct platform_device *pdev)649669{650670 struct imx_thermal_data *data;···746724 return -EPROBE_DEFER;747725 }748726749749- data->cdev = cpufreq_cooling_register(data->policy);750750- if (IS_ERR(data->cdev)) {751751- ret = PTR_ERR(data->cdev);727727+ ret = imx_thermal_register_legacy_cooling(data);728728+ if (ret) {752729 dev_err(&pdev->dev,753730 "failed to register cpufreq cooling device: %d\n", ret);754754- cpufreq_cpu_put(data->policy);755731 return ret;756732 }757733