forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm…
…/linux/kernel/git/vireshk/pm Pull ARM cpufreq changes for v5.3 from Viresh Kumar: "This pull request contains: - Minor fixes for brcmstb driver (Florian). - New imx-cpufreq driver, its bindings and code around it (Leonard). - New Raspberry Pi driver (Nicolas). - Minor fix for s5pv210 driver (Pawel). - Minor cleanup for armada driver (YueHaibing)." * 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: cpufreq: s5pv210: Don't flood kernel log after cpufreq change cpufreq: add driver for Raspberry Pi cpufreq: Switch imx7d to imx-cpufreq-dt for speed grading cpufreq: imx-cpufreq-dt: Remove global platform match list cpufreq: brcmstb-avs-cpufreq: Fix types for voltage/frequency cpufreq: brcmstb-avs-cpufreq: Fix initial command check cpufreq: armada-37xx: Remove set but not used variable 'freq' cpufreq: imx-cpufreq-dt: Fix no OPPs available on unfused parts dt-bindings: imx-cpufreq-dt: Document opp-supported-hw usage cpufreq: Add imx-cpufreq-dt driver
- Loading branch information
Showing
10 changed files
with
265 additions
and
11 deletions.
There are no files selected for viewing
37 changes: 37 additions & 0 deletions
37
Documentation/devicetree/bindings/cpufreq/imx-cpufreq-dt.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
i.MX CPUFreq-DT OPP bindings | ||
================================ | ||
|
||
Certain i.MX SoCs support different OPPs depending on the "market segment" and | ||
"speed grading" value which are written in fuses. These bits are combined with | ||
the opp-supported-hw values for each OPP to check if the OPP is allowed. | ||
|
||
Required properties: | ||
-------------------- | ||
|
||
For each opp entry in 'operating-points-v2' table: | ||
- opp-supported-hw: Two bitmaps indicating: | ||
- Supported speed grade mask | ||
- Supported market segment mask | ||
0: Consumer | ||
1: Extended Consumer | ||
2: Industrial | ||
3: Automotive | ||
|
||
Example: | ||
-------- | ||
|
||
opp_table { | ||
compatible = "operating-points-v2"; | ||
opp-1000000000 { | ||
opp-hz = /bits/ 64 <1000000000>; | ||
/* grade >= 0, consumer only */ | ||
opp-supported-hw = <0xf>, <0x3>; | ||
}; | ||
|
||
opp-1300000000 { | ||
opp-hz = /bits/ 64 <1300000000>; | ||
opp-microvolt = <1000000>; | ||
/* grade >= 1, all segments */ | ||
opp-supported-hw = <0xe>, <0x7>; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright 2019 NXP | ||
*/ | ||
|
||
#include <linux/cpu.h> | ||
#include <linux/err.h> | ||
#include <linux/init.h> | ||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
#include <linux/nvmem-consumer.h> | ||
#include <linux/of.h> | ||
#include <linux/platform_device.h> | ||
#include <linux/pm_opp.h> | ||
#include <linux/slab.h> | ||
|
||
#define OCOTP_CFG3_SPEED_GRADE_SHIFT 8 | ||
#define OCOTP_CFG3_SPEED_GRADE_MASK (0x3 << 8) | ||
#define OCOTP_CFG3_MKT_SEGMENT_SHIFT 6 | ||
#define OCOTP_CFG3_MKT_SEGMENT_MASK (0x3 << 6) | ||
|
||
/* cpufreq-dt device registered by imx-cpufreq-dt */ | ||
static struct platform_device *cpufreq_dt_pdev; | ||
static struct opp_table *cpufreq_opp_table; | ||
|
||
static int imx_cpufreq_dt_probe(struct platform_device *pdev) | ||
{ | ||
struct device *cpu_dev = get_cpu_device(0); | ||
u32 cell_value, supported_hw[2]; | ||
int speed_grade, mkt_segment; | ||
int ret; | ||
|
||
ret = nvmem_cell_read_u32(cpu_dev, "speed_grade", &cell_value); | ||
if (ret) | ||
return ret; | ||
|
||
speed_grade = (cell_value & OCOTP_CFG3_SPEED_GRADE_MASK) >> OCOTP_CFG3_SPEED_GRADE_SHIFT; | ||
mkt_segment = (cell_value & OCOTP_CFG3_MKT_SEGMENT_MASK) >> OCOTP_CFG3_MKT_SEGMENT_SHIFT; | ||
|
||
/* | ||
* Early samples without fuses written report "0 0" which means | ||
* consumer segment and minimum speed grading. | ||
* | ||
* According to datasheet minimum speed grading is not supported for | ||
* consumer parts so clamp to 1 to avoid warning for "no OPPs" | ||
* | ||
* Applies to 8mq and 8mm. | ||
*/ | ||
if (mkt_segment == 0 && speed_grade == 0 && ( | ||
of_machine_is_compatible("fsl,imx8mm") || | ||
of_machine_is_compatible("fsl,imx8mq"))) | ||
speed_grade = 1; | ||
|
||
supported_hw[0] = BIT(speed_grade); | ||
supported_hw[1] = BIT(mkt_segment); | ||
dev_info(&pdev->dev, "cpu speed grade %d mkt segment %d supported-hw %#x %#x\n", | ||
speed_grade, mkt_segment, supported_hw[0], supported_hw[1]); | ||
|
||
cpufreq_opp_table = dev_pm_opp_set_supported_hw(cpu_dev, supported_hw, 2); | ||
if (IS_ERR(cpufreq_opp_table)) { | ||
ret = PTR_ERR(cpufreq_opp_table); | ||
dev_err(&pdev->dev, "Failed to set supported opp: %d\n", ret); | ||
return ret; | ||
} | ||
|
||
cpufreq_dt_pdev = platform_device_register_data( | ||
&pdev->dev, "cpufreq-dt", -1, NULL, 0); | ||
if (IS_ERR(cpufreq_dt_pdev)) { | ||
dev_pm_opp_put_supported_hw(cpufreq_opp_table); | ||
ret = PTR_ERR(cpufreq_dt_pdev); | ||
dev_err(&pdev->dev, "Failed to register cpufreq-dt: %d\n", ret); | ||
return ret; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
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); | ||
|
||
return 0; | ||
} | ||
|
||
static struct platform_driver imx_cpufreq_dt_driver = { | ||
.probe = imx_cpufreq_dt_probe, | ||
.remove = imx_cpufreq_dt_remove, | ||
.driver = { | ||
.name = "imx-cpufreq-dt", | ||
}, | ||
}; | ||
module_platform_driver(imx_cpufreq_dt_driver); | ||
|
||
MODULE_ALIAS("platform:imx-cpufreq-dt"); | ||
MODULE_DESCRIPTION("Freescale i.MX cpufreq speed grading driver"); | ||
MODULE_LICENSE("GPL v2"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Raspberry Pi cpufreq driver | ||
* | ||
* Copyright (C) 2019, Nicolas Saenz Julienne <[email protected]> | ||
*/ | ||
|
||
#include <linux/clk.h> | ||
#include <linux/cpu.h> | ||
#include <linux/cpufreq.h> | ||
#include <linux/module.h> | ||
#include <linux/platform_device.h> | ||
#include <linux/pm_opp.h> | ||
|
||
#define RASPBERRYPI_FREQ_INTERVAL 100000000 | ||
|
||
static struct platform_device *cpufreq_dt; | ||
|
||
static int raspberrypi_cpufreq_probe(struct platform_device *pdev) | ||
{ | ||
struct device *cpu_dev; | ||
unsigned long min, max; | ||
unsigned long rate; | ||
struct clk *clk; | ||
int ret; | ||
|
||
cpu_dev = get_cpu_device(0); | ||
if (!cpu_dev) { | ||
pr_err("Cannot get CPU for cpufreq driver\n"); | ||
return -ENODEV; | ||
} | ||
|
||
clk = clk_get(cpu_dev, NULL); | ||
if (IS_ERR(clk)) { | ||
dev_err(cpu_dev, "Cannot get clock for CPU0\n"); | ||
return PTR_ERR(clk); | ||
} | ||
|
||
/* | ||
* The max and min frequencies are configurable in the Raspberry Pi | ||
* firmware, so we query them at runtime. | ||
*/ | ||
min = roundup(clk_round_rate(clk, 0), RASPBERRYPI_FREQ_INTERVAL); | ||
max = roundup(clk_round_rate(clk, ULONG_MAX), RASPBERRYPI_FREQ_INTERVAL); | ||
clk_put(clk); | ||
|
||
for (rate = min; rate <= max; rate += RASPBERRYPI_FREQ_INTERVAL) { | ||
ret = dev_pm_opp_add(cpu_dev, rate, 0); | ||
if (ret) | ||
goto remove_opp; | ||
} | ||
|
||
cpufreq_dt = platform_device_register_simple("cpufreq-dt", -1, NULL, 0); | ||
ret = PTR_ERR_OR_ZERO(cpufreq_dt); | ||
if (ret) { | ||
dev_err(cpu_dev, "Failed to create platform device, %d\n", ret); | ||
goto remove_opp; | ||
} | ||
|
||
return 0; | ||
|
||
remove_opp: | ||
dev_pm_opp_remove_all_dynamic(cpu_dev); | ||
|
||
return ret; | ||
} | ||
|
||
static int raspberrypi_cpufreq_remove(struct platform_device *pdev) | ||
{ | ||
struct device *cpu_dev; | ||
|
||
cpu_dev = get_cpu_device(0); | ||
if (cpu_dev) | ||
dev_pm_opp_remove_all_dynamic(cpu_dev); | ||
|
||
platform_device_unregister(cpufreq_dt); | ||
|
||
return 0; | ||
} | ||
|
||
/* | ||
* Since the driver depends on clk-raspberrypi, which may return EPROBE_DEFER, | ||
* all the activity is performed in the probe, which may be defered as well. | ||
*/ | ||
static struct platform_driver raspberrypi_cpufreq_driver = { | ||
.driver = { | ||
.name = "raspberrypi-cpufreq", | ||
}, | ||
.probe = raspberrypi_cpufreq_probe, | ||
.remove = raspberrypi_cpufreq_remove, | ||
}; | ||
module_platform_driver(raspberrypi_cpufreq_driver); | ||
|
||
MODULE_AUTHOR("Nicolas Saenz Julienne <[email protected]"); | ||
MODULE_DESCRIPTION("Raspberry Pi cpufreq driver"); | ||
MODULE_LICENSE("GPL"); | ||
MODULE_ALIAS("platform:raspberrypi-cpufreq"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters