From: peng.fan@nxp.com To: shawnguo@kernel.org, s.hauer@pengutronix.de, sboyd@kernel.org, robh+dt@kernel.org, viresh.kumar@linaro.org, rjw@rjwysocki.net Cc: kernel@pengutronix.de, festevam@gmail.com, linux-imx@nxp.com, Anson.Huang@nxp.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, abel.vesa@nxp.com, Peng Fan <peng.fan@nxp.com> Subject: [PATCH v2 12/14] cpufreq: imx-cpufreq-dt: support i.MX7ULP Date: Wed, 19 Feb 2020 15:59:55 +0800 [thread overview] Message-ID: <1582099197-20327-13-git-send-email-peng.fan@nxp.com> (raw) In-Reply-To: <1582099197-20327-1-git-send-email-peng.fan@nxp.com> From: Peng Fan <peng.fan@nxp.com> i.MX7ULP's ARM core clock design is totally different compared with i.MX7D/8M SoCs which supported by imx-cpufreq-dt. It needs get_intermediate and target_intermedate to configure clk MUX ready, before let OPP configure ARM core clk. |---FIRC |------RUN---...---SCS(MUX2) --------| ARM --(MUX1) |---SPLL_PFD0(CLK_SET_RATE_GATE) |------HSRUN--...--HSRUN_SCS(MUX3)---| |---SRIC FIRC is step clk, SPLL_PFD0 is the normal clk driving ARM core. MUX2 and MUX3 share same inputs. So if MUX2/MUX3 both sources from SPLL_PFD0, both MUXes will lose input when configure SPLL_PFD0. So the target_intermediate will configure MUX2/MUX3 to FIRC, to avoid ARM core lose clk when configure SPLL_PFD0. Signed-off-by: Peng Fan <peng.fan@nxp.com> --- drivers/cpufreq/imx-cpufreq-dt.c | 83 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/imx-cpufreq-dt.c b/drivers/cpufreq/imx-cpufreq-dt.c index 6cb8193421ea..504dd3ac1170 100644 --- a/drivers/cpufreq/imx-cpufreq-dt.c +++ b/drivers/cpufreq/imx-cpufreq-dt.c @@ -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> @@ -12,25 +14,100 @@ #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 OCOTP_CFG3_MKT_SEGMENT_SHIFT 6 #define OCOTP_CFG3_MKT_SEGMENT_MASK (0x3 << 6) +#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_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; @@ -87,7 +164,9 @@ 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); + } return 0; } -- 2.16.4
WARNING: multiple messages have this Message-ID (diff)
From: peng.fan@nxp.com To: shawnguo@kernel.org, s.hauer@pengutronix.de, sboyd@kernel.org, robh+dt@kernel.org, viresh.kumar@linaro.org, rjw@rjwysocki.net Cc: Peng Fan <peng.fan@nxp.com>, abel.vesa@nxp.com, Anson.Huang@nxp.com, linux-kernel@vger.kernel.org, linux-imx@nxp.com, kernel@pengutronix.de, festevam@gmail.com, linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 12/14] cpufreq: imx-cpufreq-dt: support i.MX7ULP Date: Wed, 19 Feb 2020 15:59:55 +0800 [thread overview] Message-ID: <1582099197-20327-13-git-send-email-peng.fan@nxp.com> (raw) In-Reply-To: <1582099197-20327-1-git-send-email-peng.fan@nxp.com> From: Peng Fan <peng.fan@nxp.com> i.MX7ULP's ARM core clock design is totally different compared with i.MX7D/8M SoCs which supported by imx-cpufreq-dt. It needs get_intermediate and target_intermedate to configure clk MUX ready, before let OPP configure ARM core clk. |---FIRC |------RUN---...---SCS(MUX2) --------| ARM --(MUX1) |---SPLL_PFD0(CLK_SET_RATE_GATE) |------HSRUN--...--HSRUN_SCS(MUX3)---| |---SRIC FIRC is step clk, SPLL_PFD0 is the normal clk driving ARM core. MUX2 and MUX3 share same inputs. So if MUX2/MUX3 both sources from SPLL_PFD0, both MUXes will lose input when configure SPLL_PFD0. So the target_intermediate will configure MUX2/MUX3 to FIRC, to avoid ARM core lose clk when configure SPLL_PFD0. Signed-off-by: Peng Fan <peng.fan@nxp.com> --- drivers/cpufreq/imx-cpufreq-dt.c | 83 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/imx-cpufreq-dt.c b/drivers/cpufreq/imx-cpufreq-dt.c index 6cb8193421ea..504dd3ac1170 100644 --- a/drivers/cpufreq/imx-cpufreq-dt.c +++ b/drivers/cpufreq/imx-cpufreq-dt.c @@ -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> @@ -12,25 +14,100 @@ #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 OCOTP_CFG3_MKT_SEGMENT_SHIFT 6 #define OCOTP_CFG3_MKT_SEGMENT_MASK (0x3 << 6) +#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_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; @@ -87,7 +164,9 @@ 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); + } return 0; } -- 2.16.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-02-19 8:07 UTC|newest] Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-02-19 7:59 [PATCH v2 00/14] ARM: imx7ulp: add cpufreq using cpufreq-dt peng.fan 2020-02-19 7:59 ` peng.fan 2020-02-19 7:59 ` [PATCH v2 01/14] dt-bindings: fsl: add i.MX7ULP PMC binding doc peng.fan 2020-02-19 7:59 ` peng.fan 2020-03-10 5:49 ` Shawn Guo 2020-03-10 5:49 ` Shawn Guo 2020-03-10 5:56 ` Peng Fan 2020-03-10 5:56 ` Peng Fan 2020-03-11 7:39 ` Peng Fan 2020-03-11 7:39 ` Peng Fan 2020-03-11 7:39 ` Peng Fan 2020-02-19 7:59 ` [PATCH v2 02/14] ARM: dts: imx7ulp: add pmc node peng.fan 2020-02-19 7:59 ` peng.fan 2020-02-19 7:59 ` [PATCH v2 03/14] clk: imx: Fix division by zero warning on pfdv2 peng.fan 2020-02-19 7:59 ` peng.fan 2020-03-10 5:53 ` Shawn Guo 2020-03-10 5:53 ` Shawn Guo 2020-02-19 7:59 ` [PATCH v2 04/14] clk: imx: pfdv2: switch to use determine_rate peng.fan 2020-02-19 7:59 ` peng.fan 2020-03-10 6:02 ` Shawn Guo 2020-03-10 6:02 ` Shawn Guo 2020-02-19 7:59 ` [PATCH v2 05/14] clk: imx: pfdv2: determine best parent rate peng.fan 2020-02-19 7:59 ` peng.fan 2020-03-10 6:04 ` Shawn Guo 2020-03-10 6:04 ` Shawn Guo 2020-02-19 7:59 ` [PATCH v2 06/14] clk: imx: pllv4: use prepare/unprepare peng.fan 2020-02-19 7:59 ` peng.fan 2020-03-10 6:04 ` Shawn Guo 2020-03-10 6:04 ` Shawn Guo 2020-02-19 7:59 ` [PATCH v2 07/14] clk: imx7ulp: make it easy to change ARM core clk peng.fan 2020-02-19 7:59 ` peng.fan 2020-03-10 6:09 ` Shawn Guo 2020-03-10 6:09 ` Shawn Guo 2020-03-10 6:19 ` Peng Fan 2020-03-10 6:19 ` Peng Fan 2020-02-19 7:59 ` [PATCH v2 08/14] ARM: imx: imx7ulp: support HSRUN mode peng.fan 2020-02-19 7:59 ` peng.fan 2020-02-19 7:59 ` [PATCH v2 09/14] ARM: imx: cpuidle-imx7ulp: Stop mode disallowed when HSRUN peng.fan 2020-02-19 7:59 ` peng.fan 2020-03-10 6:13 ` Shawn Guo 2020-03-10 6:13 ` Shawn Guo 2020-03-10 7:35 ` Peng Fan 2020-03-10 7:35 ` Peng Fan 2020-02-19 7:59 ` [PATCH v2 10/14] cpufreq: dt: Allow platform specific intermediate callbacks peng.fan 2020-02-19 7:59 ` peng.fan 2020-02-19 9:35 ` Viresh Kumar 2020-02-19 9:35 ` Viresh Kumar 2020-02-19 9:41 ` Peng Fan 2020-02-19 9:41 ` Peng Fan 2020-02-19 9:45 ` Viresh Kumar 2020-02-19 9:45 ` Viresh Kumar 2020-02-19 9:46 ` Viresh Kumar 2020-02-19 9:46 ` Viresh Kumar 2020-02-19 9:55 ` Peng Fan 2020-02-19 9:55 ` Peng Fan 2020-03-12 10:15 ` Viresh Kumar 2020-03-12 10:15 ` Viresh Kumar 2020-02-19 7:59 ` [PATCH v2 11/14] cpufreq: Add i.MX7ULP to cpufreq-dt-platdev blacklist peng.fan 2020-02-19 7:59 ` peng.fan 2020-02-19 7:59 ` peng.fan [this message] 2020-02-19 7:59 ` [PATCH v2 12/14] cpufreq: imx-cpufreq-dt: support i.MX7ULP peng.fan 2020-02-19 7:59 ` [PATCH v2 13/14] ARM: imx7ulp: enable cpufreq peng.fan 2020-02-19 7:59 ` peng.fan 2020-02-19 7:59 ` [PATCH v2 14/14] [Do not Apply] ARM: dts: imx7ulp: add cpu OPP points peng.fan 2020-02-19 7:59 ` peng.fan 2020-03-02 1:40 ` [PATCH v2 00/14] ARM: imx7ulp: add cpufreq using cpufreq-dt Peng Fan 2020-03-02 1:40 ` Peng Fan 2020-03-02 17:48 ` Fabio Estevam 2020-03-02 17:48 ` Fabio Estevam 2020-03-03 1:08 ` Peng Fan 2020-03-03 1:08 ` Peng Fan
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1582099197-20327-13-git-send-email-peng.fan@nxp.com \ --to=peng.fan@nxp.com \ --cc=Anson.Huang@nxp.com \ --cc=abel.vesa@nxp.com \ --cc=festevam@gmail.com \ --cc=kernel@pengutronix.de \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-imx@nxp.com \ --cc=linux-kernel@vger.kernel.org \ --cc=rjw@rjwysocki.net \ --cc=robh+dt@kernel.org \ --cc=s.hauer@pengutronix.de \ --cc=sboyd@kernel.org \ --cc=shawnguo@kernel.org \ --cc=viresh.kumar@linaro.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.