]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
cpufreq: imx6q: Move speed grading check to cpufreq driver
authorFabio Estevam <fabio.estevam@nxp.com>
Sat, 30 Sep 2017 15:16:46 +0000 (12:16 -0300)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 10 Oct 2017 23:56:25 +0000 (01:56 +0200)
On some i.MX6 SoCs (like i.MX6SL, i.MX6SX and i.MX6UL) that do not have
speed grading check, opp table will not be created in platform code,
so cpufreq driver prints the following error message:

cpu cpu0: dev_pm_opp_get_opp_count: OPP table not found (-19)

However, this is not really an error in this case because the
imx6q-cpufreq driver first calls dev_pm_opp_get_opp_count()
and if it fails, it means that platform code does not provide
OPP and then dev_pm_opp_of_add_table() will be called.

In order to avoid such confusing error message, move the speed grading
check from platform code to the imx6q-cpufreq driver.

This way the imx6q-cpufreq no longer has to check whether OPP table
is supplied by platform code.

Tested on a i.MX6Q and i.MX6UL based boards.

Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
arch/arm/mach-imx/mach-imx6q.c
drivers/cpufreq/imx6q-cpufreq.c

index 45801b27ee5ced633fae6a7c6ca238cf203f0056..b5f89fdbbb4b9d1cfa16864be13e1cb4f93b156e 100644 (file)
@@ -286,88 +286,6 @@ static void __init imx6q_init_machine(void)
        imx6q_axi_init();
 }
 
-#define OCOTP_CFG3                     0x440
-#define OCOTP_CFG3_SPEED_SHIFT         16
-#define OCOTP_CFG3_SPEED_1P2GHZ                0x3
-#define OCOTP_CFG3_SPEED_996MHZ                0x2
-#define OCOTP_CFG3_SPEED_852MHZ                0x1
-
-static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
-{
-       struct device_node *np;
-       void __iomem *base;
-       u32 val;
-
-       np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
-       if (!np) {
-               pr_warn("failed to find ocotp node\n");
-               return;
-       }
-
-       base = of_iomap(np, 0);
-       if (!base) {
-               pr_warn("failed to map ocotp\n");
-               goto put_node;
-       }
-
-       /*
-        * SPEED_GRADING[1:0] defines the max speed of ARM:
-        * 2b'11: 1200000000Hz;
-        * 2b'10: 996000000Hz;
-        * 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
-        * 2b'00: 792000000Hz;
-        * We need to set the max speed of ARM according to fuse map.
-        */
-       val = readl_relaxed(base + OCOTP_CFG3);
-       val >>= OCOTP_CFG3_SPEED_SHIFT;
-       val &= 0x3;
-
-       if ((val != OCOTP_CFG3_SPEED_1P2GHZ) && cpu_is_imx6q())
-               if (dev_pm_opp_disable(cpu_dev, 1200000000))
-                       pr_warn("failed to disable 1.2 GHz OPP\n");
-       if (val < OCOTP_CFG3_SPEED_996MHZ)
-               if (dev_pm_opp_disable(cpu_dev, 996000000))
-                       pr_warn("failed to disable 996 MHz OPP\n");
-       if (cpu_is_imx6q()) {
-               if (val != OCOTP_CFG3_SPEED_852MHZ)
-                       if (dev_pm_opp_disable(cpu_dev, 852000000))
-                               pr_warn("failed to disable 852 MHz OPP\n");
-       }
-       iounmap(base);
-put_node:
-       of_node_put(np);
-}
-
-static void __init imx6q_opp_init(void)
-{
-       struct device_node *np;
-       struct device *cpu_dev = get_cpu_device(0);
-
-       if (!cpu_dev) {
-               pr_warn("failed to get cpu0 device\n");
-               return;
-       }
-       np = of_node_get(cpu_dev->of_node);
-       if (!np) {
-               pr_warn("failed to find cpu0 node\n");
-               return;
-       }
-
-       if (dev_pm_opp_of_add_table(cpu_dev)) {
-               pr_warn("failed to init OPP table\n");
-               goto put_node;
-       }
-
-       imx6q_opp_check_speed_grading(cpu_dev);
-
-put_node:
-       of_node_put(np);
-}
-
-static struct platform_device imx6q_cpufreq_pdev = {
-       .name = "imx6q-cpufreq",
-};
-
 static void __init imx6q_init_late(void)
 {
        /*
@@ -377,10 +295,8 @@ static void __init imx6q_init_late(void)
        if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
                imx6q_cpuidle_init();
 
-       if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
-               imx6q_opp_init();
-               platform_device_register(&imx6q_cpufreq_pdev);
-       }
+       if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
+               platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
 }
 
 static void __init imx6q_map_io(void)
index 14466a9b01c0b42b4eaa10fc946e1c5ad70f0d82..628fe899cb483da9dbf0f7661b537734bc82f784 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/pm_opp.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
@@ -191,6 +192,57 @@ static struct cpufreq_driver imx6q_cpufreq_driver = {
        .suspend = cpufreq_generic_suspend,
 };
 
+#define OCOTP_CFG3                     0x440
+#define OCOTP_CFG3_SPEED_SHIFT         16
+#define OCOTP_CFG3_SPEED_1P2GHZ                0x3
+#define OCOTP_CFG3_SPEED_996MHZ                0x2
+#define OCOTP_CFG3_SPEED_852MHZ                0x1
+
+static void imx6q_opp_check_speed_grading(struct device *dev)
+{
+       struct device_node *np;
+       void __iomem *base;
+       u32 val;
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
+       if (!np)
+               return;
+
+       base = of_iomap(np, 0);
+       if (!base) {
+               dev_err(dev, "failed to map ocotp\n");
+               goto put_node;
+       }
+
+       /*
+        * SPEED_GRADING[1:0] defines the max speed of ARM:
+        * 2b'11: 1200000000Hz;
+        * 2b'10: 996000000Hz;
+        * 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
+        * 2b'00: 792000000Hz;
+        * We need to set the max speed of ARM according to fuse map.
+        */
+       val = readl_relaxed(base + OCOTP_CFG3);
+       val >>= OCOTP_CFG3_SPEED_SHIFT;
+       val &= 0x3;
+
+       if ((val != OCOTP_CFG3_SPEED_1P2GHZ) &&
+            of_machine_is_compatible("fsl,imx6q"))
+               if (dev_pm_opp_disable(dev, 1200000000))
+                       dev_warn(dev, "failed to disable 1.2GHz OPP\n");
+       if (val < OCOTP_CFG3_SPEED_996MHZ)
+               if (dev_pm_opp_disable(dev, 996000000))
+                       dev_warn(dev, "failed to disable 996MHz OPP\n");
+       if (of_machine_is_compatible("fsl,imx6q")) {
+               if (val != OCOTP_CFG3_SPEED_852MHZ)
+                       if (dev_pm_opp_disable(dev, 852000000))
+                               dev_warn(dev, "failed to disable 852MHz OPP\n");
+       }
+       iounmap(base);
+put_node:
+       of_node_put(np);
+}
+
 static int imx6q_cpufreq_probe(struct platform_device *pdev)
 {
        struct device_node *np;
@@ -252,28 +304,21 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
                goto put_reg;
        }
 
-       /*
-        * We expect an OPP table supplied by platform.
-        * Just, incase the platform did not supply the OPP
-        * table, it will try to get it.
-        */
-       num = dev_pm_opp_get_opp_count(cpu_dev);
-       if (num < 0) {
-               ret = dev_pm_opp_of_add_table(cpu_dev);
-               if (ret < 0) {
-                       dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
-                       goto put_reg;
-               }
+       ret = dev_pm_opp_of_add_table(cpu_dev);
+       if (ret < 0) {
+               dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
+               goto put_reg;
+       }
 
-               /* Because we have added the OPPs here, we must free them */
-               free_opp = true;
+       imx6q_opp_check_speed_grading(cpu_dev);
 
-               num = dev_pm_opp_get_opp_count(cpu_dev);
-               if (num < 0) {
-                       ret = num;
-                       dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
-                       goto out_free_opp;
-               }
+       /* Because we have added the OPPs here, we must free them */
+       free_opp = true;
+       num = dev_pm_opp_get_opp_count(cpu_dev);
+       if (num < 0) {
+               ret = num;
+               dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
+               goto out_free_opp;
        }
 
        ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);