mirror of
https://github.com/torvalds/linux.git
synced 2024-11-18 10:01:43 +00:00
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
This commit is contained in:
commit
3f8ffb14ea
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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", },
|
||||
|
@ -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,8 +14,11 @@
|
||||
#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)
|
||||
@ -22,20 +27,92 @@
|
||||
#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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
struct device_node *np;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
module_exit(qoriq_cpufreq_exit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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");
|
||||
|
Loading…
Reference in New Issue
Block a user