Commit 3f8ffb14 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm

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
parents 9795a0dd 1f1755af
...@@ -95,6 +95,7 @@ struct clockgen { ...@@ -95,6 +95,7 @@ struct clockgen {
}; };
static struct clockgen clockgen; static struct clockgen clockgen;
static bool add_cpufreq_dev __initdata;
static void cg_out(struct clockgen *cg, u32 val, u32 __iomem *reg) static void cg_out(struct clockgen *cg, u32 val, u32 __iomem *reg)
{ {
...@@ -1019,7 +1020,7 @@ static void __init create_muxes(struct clockgen *cg) ...@@ -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. * Legacy nodes may get probed before the parent clockgen node.
...@@ -1030,7 +1031,7 @@ static void __init clockgen_init(struct device_node *np); ...@@ -1030,7 +1031,7 @@ static void __init clockgen_init(struct device_node *np);
static void __init legacy_init_clockgen(struct device_node *np) static void __init legacy_init_clockgen(struct device_node *np)
{ {
if (!clockgen.node) if (!clockgen.node)
clockgen_init(of_get_parent(np)); _clockgen_init(of_get_parent(np), true);
} }
/* Legacy node */ /* Legacy node */
...@@ -1447,7 +1448,7 @@ static bool __init has_erratum_a4510(void) ...@@ -1447,7 +1448,7 @@ static bool __init has_erratum_a4510(void)
} }
#endif #endif
static void __init clockgen_init(struct device_node *np) static void __init _clockgen_init(struct device_node *np, bool legacy)
{ {
int i, ret; int i, ret;
bool is_old_ls1021a = false; bool is_old_ls1021a = false;
...@@ -1516,12 +1517,35 @@ static void __init clockgen_init(struct device_node *np) ...@@ -1516,12 +1517,35 @@ static void __init clockgen_init(struct device_node *np)
__func__, np, ret); __func__, np, ret);
} }
/* Don't create cpufreq device for legacy clockgen blocks */
add_cpufreq_dev = !legacy;
return; return;
err: err:
iounmap(clockgen.regs); iounmap(clockgen.regs);
clockgen.regs = NULL; 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_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_2, "fsl,qoriq-clockgen-2.0", clockgen_init);
CLK_OF_DECLARE(qoriq_clockgen_b4420, "fsl,b4420-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_b4420, "fsl,b4420-clockgen", clockgen_init);
......
...@@ -323,7 +323,8 @@ endif ...@@ -323,7 +323,8 @@ endif
config QORIQ_CPUFREQ config QORIQ_CPUFREQ
tristate "CPU frequency scaling driver for Freescale QorIQ SoCs" 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 select CLK_QORIQ
help help
This adds the CPUFreq driver support for Freescale QorIQ SoCs This adds the CPUFreq driver support for Freescale QorIQ SoCs
......
...@@ -317,6 +317,7 @@ config ARM_TEGRA186_CPUFREQ ...@@ -317,6 +317,7 @@ config ARM_TEGRA186_CPUFREQ
config ARM_TI_CPUFREQ config ARM_TI_CPUFREQ
bool "Texas Instruments CPUFreq support" bool "Texas Instruments CPUFreq support"
depends on ARCH_OMAP2PLUS depends on ARCH_OMAP2PLUS
default ARCH_OMAP2PLUS
help help
This driver enables valid OPPs on the running platform based on This driver enables valid OPPs on the running platform based on
values contained within the SoC in use. Enable this in order to values contained within the SoC in use. Enable this in order to
......
...@@ -53,6 +53,7 @@ static const struct of_device_id whitelist[] __initconst = { ...@@ -53,6 +53,7 @@ static const struct of_device_id whitelist[] __initconst = {
{ .compatible = "renesas,r7s72100", }, { .compatible = "renesas,r7s72100", },
{ .compatible = "renesas,r8a73a4", }, { .compatible = "renesas,r8a73a4", },
{ .compatible = "renesas,r8a7740", }, { .compatible = "renesas,r8a7740", },
{ .compatible = "renesas,r8a7742", },
{ .compatible = "renesas,r8a7743", }, { .compatible = "renesas,r8a7743", },
{ .compatible = "renesas,r8a7744", }, { .compatible = "renesas,r8a7744", },
{ .compatible = "renesas,r8a7745", }, { .compatible = "renesas,r8a7745", },
...@@ -105,6 +106,7 @@ static const struct of_device_id blacklist[] __initconst = { ...@@ -105,6 +106,7 @@ static const struct of_device_id blacklist[] __initconst = {
{ .compatible = "calxeda,highbank", }, { .compatible = "calxeda,highbank", },
{ .compatible = "calxeda,ecx-2000", }, { .compatible = "calxeda,ecx-2000", },
{ .compatible = "fsl,imx7ulp", },
{ .compatible = "fsl,imx7d", }, { .compatible = "fsl,imx7d", },
{ .compatible = "fsl,imx8mq", }, { .compatible = "fsl,imx8mq", },
{ .compatible = "fsl,imx8mm", }, { .compatible = "fsl,imx8mm", },
......
...@@ -3,7 +3,9 @@ ...@@ -3,7 +3,9 @@
* Copyright 2019 NXP * Copyright 2019 NXP
*/ */
#include <linux/clk.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -12,8 +14,11 @@ ...@@ -12,8 +14,11 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_opp.h> #include <linux/pm_opp.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "cpufreq-dt.h"
#define OCOTP_CFG3_SPEED_GRADE_SHIFT 8 #define OCOTP_CFG3_SPEED_GRADE_SHIFT 8
#define OCOTP_CFG3_SPEED_GRADE_MASK (0x3 << 8) #define OCOTP_CFG3_SPEED_GRADE_MASK (0x3 << 8)
#define IMX8MN_OCOTP_CFG3_SPEED_GRADE_MASK (0xf << 8) #define IMX8MN_OCOTP_CFG3_SPEED_GRADE_MASK (0xf << 8)
...@@ -22,20 +27,92 @@ ...@@ -22,20 +27,92 @@
#define IMX8MP_OCOTP_CFG3_MKT_SEGMENT_SHIFT 5 #define IMX8MP_OCOTP_CFG3_MKT_SEGMENT_SHIFT 5
#define IMX8MP_OCOTP_CFG3_MKT_SEGMENT_MASK (0x3 << 5) #define IMX8MP_OCOTP_CFG3_MKT_SEGMENT_MASK (0x3 << 5)
#define IMX7ULP_MAX_RUN_FREQ 528000
/* cpufreq-dt device registered by imx-cpufreq-dt */ /* cpufreq-dt device registered by imx-cpufreq-dt */
static struct platform_device *cpufreq_dt_pdev; static struct platform_device *cpufreq_dt_pdev;
static struct opp_table *cpufreq_opp_table; 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) 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]; u32 cell_value, supported_hw[2];
int speed_grade, mkt_segment; int speed_grade, mkt_segment;
int ret; int ret;
cpu_dev = get_cpu_device(0);
if (!of_find_property(cpu_dev->of_node, "cpu-supply", NULL)) if (!of_find_property(cpu_dev->of_node, "cpu-supply", NULL))
return -ENODEV; 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); ret = nvmem_cell_read_u32(cpu_dev, "speed_grade", &cell_value);
if (ret) if (ret)
return ret; return ret;
...@@ -98,7 +175,10 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev) ...@@ -98,7 +175,10 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev)
static int imx_cpufreq_dt_remove(struct platform_device *pdev) static int imx_cpufreq_dt_remove(struct platform_device *pdev)
{ {
platform_device_unregister(cpufreq_dt_pdev); platform_device_unregister(cpufreq_dt_pdev);
if (!of_machine_is_compatible("fsl,imx7ulp"))
dev_pm_opp_put_supported_hw(cpufreq_opp_table); dev_pm_opp_put_supported_hw(cpufreq_opp_table);
else
clk_bulk_put(ARRAY_SIZE(imx7ulp_clks), imx7ulp_clks);
return 0; return 0;
} }
......
...@@ -277,7 +277,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) ...@@ -277,7 +277,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
if (!np) if (!np)
return -ENOENT; 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) { if (!ret) {
of_node_put(np); of_node_put(np);
return -ENOENT; return -ENOENT;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/platform_device.h>
/** /**
* struct cpu_data * struct cpu_data
...@@ -29,12 +30,6 @@ struct cpu_data { ...@@ -29,12 +30,6 @@ struct cpu_data {
struct cpufreq_frequency_table *table; 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 * struct soc_data - SoC specific data
* @flags: SOC_xxx * @flags: SOC_xxx
...@@ -264,64 +259,51 @@ static struct cpufreq_driver qoriq_cpufreq_driver = { ...@@ -264,64 +259,51 @@ static struct cpufreq_driver qoriq_cpufreq_driver = {
.attr = cpufreq_generic_attr, .attr = cpufreq_generic_attr,
}; };
static const struct soc_data blacklist = { static const struct of_device_id qoriq_cpufreq_blacklist[] = {
.flags = SOC_BLACKLIST,
};
static const struct of_device_id node_matches[] __initconst = {
/* e6500 cannot use cpufreq due to erratum A-008083 */ /* e6500 cannot use cpufreq due to erratum A-008083 */
{ .compatible = "fsl,b4420-clockgen", &blacklist }, { .compatible = "fsl,b4420-clockgen", },
{ .compatible = "fsl,b4860-clockgen", &blacklist }, { .compatible = "fsl,b4860-clockgen", },
{ .compatible = "fsl,t2080-clockgen", &blacklist }, { .compatible = "fsl,t2080-clockgen", },
{ .compatible = "fsl,t4240-clockgen", &blacklist }, { .compatible = "fsl,t4240-clockgen", },
{ .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", },
{} {}
}; };
static int __init qoriq_cpufreq_init(void) static int qoriq_cpufreq_probe(struct platform_device *pdev)
{ {
int ret; int ret;
struct device_node *np; 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);
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; return -ENODEV;
}
ret = cpufreq_register_driver(&qoriq_cpufreq_driver); ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
if (!ret) if (ret)
pr_info("Freescale QorIQ CPU frequency scaling driver\n");
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); 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_LICENSE("GPL");
MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>"); MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs"); MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment