From patchwork Sat Sep 30 12:13:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabio Estevam X-Patchwork-Id: 9979489 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id EDE5A60375 for ; Sat, 30 Sep 2017 12:13:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5E922965A for ; Sat, 30 Sep 2017 12:13:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BAB832965C; Sat, 30 Sep 2017 12:13:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0900F2965A for ; Sat, 30 Sep 2017 12:13:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752902AbdI3MNb (ORCPT ); Sat, 30 Sep 2017 08:13:31 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:50014 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752896AbdI3MN2 (ORCPT ); Sat, 30 Sep 2017 08:13:28 -0400 Received: by mail-qt0-f194.google.com with SMTP id o3so2534107qte.6 for ; Sat, 30 Sep 2017 05:13:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=gyKqflSzB+J0Uqbl1VwC0z231TwVs9+H70PzZEdnv4k=; b=V/cXeXcJA/xbjQc1wR7YA8zcQlvJpPFsXt58O8p0ADDoz7GAu4JI9plO+826IIQa5V VcdM6/8TOu/QDdeeJgg5rIxuWSmd6znvU++Nxtmas4ukLmavNV3FY6zTsChjAvEcziA2 b/IGgp9fEIbBxVxywj4j/mQCxPmg+6DuBDGooc7772pTvuTBCU94N4vjDCa8MeL9Hz5d 2LYbEoHaI6s1Dwd3ppNs44HwSIPYxOor/Yjk/1pneKzERrLgm7wlPtQvvB6sY5udli5U KSqC679ZUHjtsNPDowvmA0Q3QUFGGzN/Ys8807S91ZdE6tjIWN8Ew2Und8NXzhrHHHr9 w2yA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=gyKqflSzB+J0Uqbl1VwC0z231TwVs9+H70PzZEdnv4k=; b=pUbXUX+1d+PXEcg2059uD2PRh8bcq2wrUEoxH6Xpm4Dn/wQCJmjPCV82MAROxpp5ya DgQEGkd5IeUEe+grKIahN3fOCxRtA6D4Qdnkhc6AJrbl76VaQ/OotzxmQhd8BLbvK9Ad 1dMVr1oCSpL/Q5XNQuIaWbZ/jXCmNu6oJHei4d86PI4DWa8p2Fgrjd6aBaliHkBmTK6Q jK0YLR3w46mDm1J3oOJ8ZbleLSzckQmffNXPgtdU+w5VWQrZpLW+94Q/HuoJb9+JD9gk haClX5smaLJJenhOawzK/pGFr1sPuXS/qYBIzSfQuEfNuiWCxGduYbX95X1pANX3RN/9 DxIQ== X-Gm-Message-State: AMCzsaVglSB2wyHFTngCyznpRbRFEBoNcYI24mo2jgOhJpYhiEJFKCNI 1cEKxUCJXUwM6xD/bdfnEhU= X-Google-Smtp-Source: AOwi7QB78ID1am4kN9283tGFu0QHGDZcKagsdy93Af9o2LMFnoaoXu2Q+C7OyMuUDBkPqYWRNzHfBg== X-Received: by 10.237.37.231 with SMTP id y36mr10429353qtc.199.1506773607540; Sat, 30 Sep 2017 05:13:27 -0700 (PDT) Received: from localhost.localdomain ([187.180.181.115]) by smtp.gmail.com with ESMTPSA id 16sm3954766qkd.30.2017.09.30.05.13.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 30 Sep 2017 05:13:27 -0700 (PDT) From: Fabio Estevam To: vireshk@kernel.org Cc: nm@ti.com, sboyd@codeaurora.org, rjw@rjwysocki.net, linux-pm@vger.kernel.org, kernel@pengutronix.de, shawnguo@kernel.org, anson.huang@nxp.com, linux-arm-kernel@lists.infradead.org, Fabio Estevam Subject: [PATCH v2] cpufreq: imx6q: Move speed grading check to cpufreq driver Date: Sat, 30 Sep 2017 09:13:01 -0300 Message-Id: <1506773581-1226-1-git-send-email-festevam@gmail.com> X-Mailer: git-send-email 2.7.4 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Fabio Estevam On some i.MX6 SoCs (like i.MX6UL, 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 --- Previous discussion on this topic: https://patchwork.kernel.org/patch/9295059/ Changes since v1: - Remove unneeded has_speed_grading() function. arch/arm/mach-imx/mach-imx6q.c | 88 +---------------------------------------- drivers/cpufreq/imx6q-cpufreq.c | 85 +++++++++++++++++++++++++++++---------- 2 files changed, 67 insertions(+), 106 deletions(-) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 45801b2..b5f89fd 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -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) diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index 14466a9..45d90e6 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -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 __init 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);