Merge branch 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel...
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 12 May 2020 14:21:03 +0000 (16:21 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 12 May 2020 14:21:03 +0000 (16:21 +0200)
Pull ARM cpufreq updates for v5.8 from Viresh Kumar:

"- Build OMAP cpufreq driver by default for ARCH_OMAP2PLUS platform
  (Anders Roxell).

- Fix compatible bindings for qcom cpufreq driver (Ansuel Smith).

- Update qoriq cpufreq driver to automatically loaded when built as
  module and related changes (Mian Yousaf Kaukab and Geert
  Uytterhoeven).

- Add support for r8a7742 to cpufreq-dt platform driver (Lad
  Prabhakar).

- Add support for i.MX7ULP to imx cpufreq driver (Peng Fan)."

* 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm:
  cpufreq: qoriq: Add platform dependencies
  clk: qoriq: add cpufreq platform device
  cpufreq: qoriq: convert to a platform driver
  cpufreq: qcom: fix wrong compatible binding
  cpufreq: imx-cpufreq-dt: support i.MX7ULP
  cpufreq: dt: Add support for r8a7742
  cpufreq: Add i.MX7ULP to cpufreq-dt-platdev blacklist
  cpufreq: omap: Build driver by default for ARCH_OMAP2PLUS

drivers/clk/clk-qoriq.c
drivers/cpufreq/Kconfig
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/cpufreq-dt-platdev.c
drivers/cpufreq/imx-cpufreq-dt.c
drivers/cpufreq/qcom-cpufreq-nvmem.c
drivers/cpufreq/qoriq-cpufreq.c

index d5946f7486d6c21fd904b46ee9434f891a3c5dcb..374afcab89af5978c076826c21699ab3d58b0b14 100644 (file)
@@ -95,6 +95,7 @@ struct clockgen {
 };
 
 static struct clockgen clockgen;
+static bool add_cpufreq_dev __initdata;
 
 static void cg_out(struct clockgen *cg, u32 val, u32 __iomem *reg)
 {
@@ -1019,7 +1020,7 @@ static void __init create_muxes(struct clockgen *cg)
        }
 }
 
-static void __init clockgen_init(struct device_node *np);
+static void __init _clockgen_init(struct device_node *np, bool legacy);
 
 /*
  * Legacy nodes may get probed before the parent clockgen node.
@@ -1030,7 +1031,7 @@ static void __init clockgen_init(struct device_node *np);
 static void __init legacy_init_clockgen(struct device_node *np)
 {
        if (!clockgen.node)
-               clockgen_init(of_get_parent(np));
+               _clockgen_init(of_get_parent(np), true);
 }
 
 /* Legacy node */
@@ -1447,7 +1448,7 @@ static bool __init has_erratum_a4510(void)
 }
 #endif
 
-static void __init clockgen_init(struct device_node *np)
+static void __init _clockgen_init(struct device_node *np, bool legacy)
 {
        int i, ret;
        bool is_old_ls1021a = false;
@@ -1516,12 +1517,35 @@ static void __init clockgen_init(struct device_node *np)
                       __func__, np, ret);
        }
 
+       /* Don't create cpufreq device for legacy clockgen blocks */
+       add_cpufreq_dev = !legacy;
+
        return;
 err:
        iounmap(clockgen.regs);
        clockgen.regs = NULL;
 }
 
+static void __init clockgen_init(struct device_node *np)
+{
+       _clockgen_init(np, false);
+}
+
+static int __init clockgen_cpufreq_init(void)
+{
+       struct platform_device *pdev;
+
+       if (add_cpufreq_dev) {
+               pdev = platform_device_register_simple("qoriq-cpufreq", -1,
+                               NULL, 0);
+               if (IS_ERR(pdev))
+                       pr_err("Couldn't register qoriq-cpufreq err=%ld\n",
+                               PTR_ERR(pdev));
+       }
+       return 0;
+}
+device_initcall(clockgen_cpufreq_init);
+
 CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init);
 CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init);
 CLK_OF_DECLARE(qoriq_clockgen_b4420, "fsl,b4420-clockgen", clockgen_init);
index c3e6bd59e920882268c695ef03b02d800978e963..e917501325525f168d03c18340d9134eb30ad7aa 100644 (file)
@@ -323,7 +323,8 @@ endif
 
 config QORIQ_CPUFREQ
        tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
-       depends on OF && COMMON_CLK && (PPC_E500MC || ARM || ARM64)
+       depends on OF && COMMON_CLK
+       depends on PPC_E500MC || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST
        select CLK_QORIQ
        help
          This adds the CPUFreq driver support for Freescale QorIQ SoCs
index 15c1a12315164e243050900ffcc78e311d0bf4fd..9481292981f0c9b1a81cd9a77b7c98868f48552d 100644 (file)
@@ -317,6 +317,7 @@ config ARM_TEGRA186_CPUFREQ
 config ARM_TI_CPUFREQ
        bool "Texas Instruments CPUFreq support"
        depends on ARCH_OMAP2PLUS
+       default ARCH_OMAP2PLUS
        help
          This driver enables valid OPPs on the running platform based on
          values contained within the SoC in use. Enable this in order to
index cb9db16bea6176fb825a9aa0a96ae05110d5988d..e8e20fef400b0ce5ef1aa4cd272562f61e58f0a8 100644 (file)
@@ -53,6 +53,7 @@ static const struct of_device_id whitelist[] __initconst = {
        { .compatible = "renesas,r7s72100", },
        { .compatible = "renesas,r8a73a4", },
        { .compatible = "renesas,r8a7740", },
+       { .compatible = "renesas,r8a7742", },
        { .compatible = "renesas,r8a7743", },
        { .compatible = "renesas,r8a7744", },
        { .compatible = "renesas,r8a7745", },
@@ -105,6 +106,7 @@ static const struct of_device_id blacklist[] __initconst = {
        { .compatible = "calxeda,highbank", },
        { .compatible = "calxeda,ecx-2000", },
 
+       { .compatible = "fsl,imx7ulp", },
        { .compatible = "fsl,imx7d", },
        { .compatible = "fsl,imx8mq", },
        { .compatible = "fsl,imx8mm", },
index de206d2745feb4aaf5618e8370c751561c8347d3..3fe9125156b443db3d93529026c91a2e2ce44ff8 100644 (file)
@@ -3,7 +3,9 @@
  * Copyright 2019 NXP
  */
 
+#include <linux/clk.h>
 #include <linux/cpu.h>
+#include <linux/cpufreq.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_opp.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
+#include "cpufreq-dt.h"
+
 #define OCOTP_CFG3_SPEED_GRADE_SHIFT   8
 #define OCOTP_CFG3_SPEED_GRADE_MASK    (0x3 << 8)
 #define IMX8MN_OCOTP_CFG3_SPEED_GRADE_MASK     (0xf << 8)
 #define IMX8MP_OCOTP_CFG3_MKT_SEGMENT_SHIFT    5
 #define IMX8MP_OCOTP_CFG3_MKT_SEGMENT_MASK     (0x3 << 5)
 
+#define IMX7ULP_MAX_RUN_FREQ   528000
+
 /* cpufreq-dt device registered by imx-cpufreq-dt */
 static struct platform_device *cpufreq_dt_pdev;
 static struct opp_table *cpufreq_opp_table;
+static struct device *cpu_dev;
+
+enum IMX7ULP_CPUFREQ_CLKS {
+       ARM,
+       CORE,
+       SCS_SEL,
+       HSRUN_CORE,
+       HSRUN_SCS_SEL,
+       FIRC,
+};
+
+static struct clk_bulk_data imx7ulp_clks[] = {
+       { .id = "arm" },
+       { .id = "core" },
+       { .id = "scs_sel" },
+       { .id = "hsrun_core" },
+       { .id = "hsrun_scs_sel" },
+       { .id = "firc" },
+};
+
+static unsigned int imx7ulp_get_intermediate(struct cpufreq_policy *policy,
+                                            unsigned int index)
+{
+       return clk_get_rate(imx7ulp_clks[FIRC].clk);
+}
+
+static int imx7ulp_target_intermediate(struct cpufreq_policy *policy,
+                                       unsigned int index)
+{
+       unsigned int newfreq = policy->freq_table[index].frequency;
+
+       clk_set_parent(imx7ulp_clks[SCS_SEL].clk, imx7ulp_clks[FIRC].clk);
+       clk_set_parent(imx7ulp_clks[HSRUN_SCS_SEL].clk, imx7ulp_clks[FIRC].clk);
+
+       if (newfreq > IMX7ULP_MAX_RUN_FREQ)
+               clk_set_parent(imx7ulp_clks[ARM].clk,
+                              imx7ulp_clks[HSRUN_CORE].clk);
+       else
+               clk_set_parent(imx7ulp_clks[ARM].clk, imx7ulp_clks[CORE].clk);
+
+       return 0;
+}
+
+static struct cpufreq_dt_platform_data imx7ulp_data = {
+       .target_intermediate = imx7ulp_target_intermediate,
+       .get_intermediate = imx7ulp_get_intermediate,
+};
 
 static int imx_cpufreq_dt_probe(struct platform_device *pdev)
 {
-       struct device *cpu_dev = get_cpu_device(0);
+       struct platform_device *dt_pdev;
        u32 cell_value, supported_hw[2];
        int speed_grade, mkt_segment;
        int ret;
 
+       cpu_dev = get_cpu_device(0);
+
        if (!of_find_property(cpu_dev->of_node, "cpu-supply", NULL))
                return -ENODEV;
 
+       if (of_machine_is_compatible("fsl,imx7ulp")) {
+               ret = clk_bulk_get(cpu_dev, ARRAY_SIZE(imx7ulp_clks),
+                                  imx7ulp_clks);
+               if (ret)
+                       return ret;
+
+               dt_pdev = platform_device_register_data(NULL, "cpufreq-dt",
+                                                       -1, &imx7ulp_data,
+                                                       sizeof(imx7ulp_data));
+               if (IS_ERR(dt_pdev)) {
+                       clk_bulk_put(ARRAY_SIZE(imx7ulp_clks), imx7ulp_clks);
+                       ret = PTR_ERR(dt_pdev);
+                       dev_err(&pdev->dev, "Failed to register cpufreq-dt: %d\n", ret);
+                       return ret;
+               }
+
+               cpufreq_dt_pdev = dt_pdev;
+
+               return 0;
+       }
+
        ret = nvmem_cell_read_u32(cpu_dev, "speed_grade", &cell_value);
        if (ret)
                return ret;
@@ -98,7 +175,10 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev)
 static int imx_cpufreq_dt_remove(struct platform_device *pdev)
 {
        platform_device_unregister(cpufreq_dt_pdev);
-       dev_pm_opp_put_supported_hw(cpufreq_opp_table);
+       if (!of_machine_is_compatible("fsl,imx7ulp"))
+               dev_pm_opp_put_supported_hw(cpufreq_opp_table);
+       else
+               clk_bulk_put(ARRAY_SIZE(imx7ulp_clks), imx7ulp_clks);
 
        return 0;
 }
index a1b8238872a21d012d121d453fcf7250966fdfad..d06b37822c3dff1add1d505474efd9ecb8422f95 100644 (file)
@@ -277,7 +277,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
        if (!np)
                return -ENOENT;
 
-       ret = of_device_is_compatible(np, "operating-points-v2-qcom-cpu");
+       ret = of_device_is_compatible(np, "operating-points-v2-kryo-cpu");
        if (!ret) {
                of_node_put(np);
                return -ENOENT;
index 8e436dc75c8bc84b4cd8011f6062671f3a8ca3a5..6b6b20da2bcfc83846d37a3524de5c4d3f7598f2 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
+#include <linux/platform_device.h>
 
 /**
  * struct cpu_data
@@ -29,12 +30,6 @@ struct cpu_data {
        struct cpufreq_frequency_table *table;
 };
 
-/*
- * Don't use cpufreq on this SoC -- used when the SoC would have otherwise
- * matched a more generic compatible.
- */
-#define SOC_BLACKLIST          1
-
 /**
  * struct soc_data - SoC specific data
  * @flags: SOC_xxx
@@ -264,64 +259,51 @@ static struct cpufreq_driver qoriq_cpufreq_driver = {
        .attr           = cpufreq_generic_attr,
 };
 
-static const struct soc_data blacklist = {
-       .flags = SOC_BLACKLIST,
-};
-
-static const struct of_device_id node_matches[] __initconst = {
+static const struct of_device_id qoriq_cpufreq_blacklist[] = {
        /* e6500 cannot use cpufreq due to erratum A-008083 */
-       { .compatible = "fsl,b4420-clockgen", &blacklist },
-       { .compatible = "fsl,b4860-clockgen", &blacklist },
-       { .compatible = "fsl,t2080-clockgen", &blacklist },
-       { .compatible = "fsl,t4240-clockgen", &blacklist },
-
-       { .compatible = "fsl,ls1012a-clockgen", },
-       { .compatible = "fsl,ls1021a-clockgen", },
-       { .compatible = "fsl,ls1028a-clockgen", },
-       { .compatible = "fsl,ls1043a-clockgen", },
-       { .compatible = "fsl,ls1046a-clockgen", },
-       { .compatible = "fsl,ls1088a-clockgen", },
-       { .compatible = "fsl,ls2080a-clockgen", },
-       { .compatible = "fsl,lx2160a-clockgen", },
-       { .compatible = "fsl,p4080-clockgen", },
-       { .compatible = "fsl,qoriq-clockgen-1.0", },
-       { .compatible = "fsl,qoriq-clockgen-2.0", },
+       { .compatible = "fsl,b4420-clockgen", },
+       { .compatible = "fsl,b4860-clockgen", },
+       { .compatible = "fsl,t2080-clockgen", },
+       { .compatible = "fsl,t4240-clockgen", },
        {}
 };
 
-static int __init qoriq_cpufreq_init(void)
+static int qoriq_cpufreq_probe(struct platform_device *pdev)
 {
        int ret;
-       struct device_node  *np;
-       const struct of_device_id *match;
-       const struct soc_data *data;
-
-       np = of_find_matching_node(NULL, node_matches);
-       if (!np)
-               return -ENODEV;
-
-       match = of_match_node(node_matches, np);
-       data = match->data;
-
-       of_node_put(np);
+       struct device_node *np;
 
-       if (data && data->flags & SOC_BLACKLIST)
+       np = of_find_matching_node(NULL, qoriq_cpufreq_blacklist);
+       if (np) {
+               dev_info(&pdev->dev, "Disabling due to erratum A-008083");
                return -ENODEV;
+       }
 
        ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
-       if (!ret)
-               pr_info("Freescale QorIQ CPU frequency scaling driver\n");
+       if (ret)
+               return ret;
 
-       return ret;
+       dev_info(&pdev->dev, "Freescale QorIQ CPU frequency scaling driver\n");
+       return 0;
 }
-module_init(qoriq_cpufreq_init);
 
-static void __exit qoriq_cpufreq_exit(void)
+static int qoriq_cpufreq_remove(struct platform_device *pdev)
 {
        cpufreq_unregister_driver(&qoriq_cpufreq_driver);
+
+       return 0;
 }
-module_exit(qoriq_cpufreq_exit);
 
+static struct platform_driver qoriq_cpufreq_platform_driver = {
+       .driver = {
+               .name = "qoriq-cpufreq",
+       },
+       .probe = qoriq_cpufreq_probe,
+       .remove = qoriq_cpufreq_remove,
+};
+module_platform_driver(qoriq_cpufreq_platform_driver);
+
+MODULE_ALIAS("platform:qoriq-cpufreq");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
 MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");