1 From 7d12709544b8b3fb9727a34a664b8380e1e3493a Mon Sep 17 00:00:00 2001
2 From: Sricharan R <sricharan@codeaurora.org>
3 Date: Thu, 25 Jul 2019 12:41:31 +0200
4 Subject: [PATCH] cpufreq: qcom: Re-organise kryo cpufreq to use it for other
7 The kryo cpufreq driver reads the nvmem cell and uses that data to
8 populate the opps. There are other qcom cpufreq socs like krait which
9 does similar thing. Except for the interpretation of the read data,
10 rest of the driver is same for both the cases. So pull the common things
13 Signed-off-by: Sricharan R <sricharan@codeaurora.org>
14 [niklas.cassel@linaro.org: split dt-binding into a separate patch and
15 do not rename the compatible string. Update MAINTAINERS file.]
16 Signed-off-by: Niklas Cassel <niklas.cassel@linaro.org>
17 Reviewed-by: Ilia Lin <ilia.lin@kernel.org>
18 Reviewed-by: Stephen Boyd <sboyd@kernel.org>
19 Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
22 drivers/cpufreq/Kconfig.arm | 4 +-
23 drivers/cpufreq/Makefile | 2 +-
24 ...om-cpufreq-kryo.c => qcom-cpufreq-nvmem.c} | 122 +++++++++++-------
25 4 files changed, 78 insertions(+), 54 deletions(-)
26 rename drivers/cpufreq/{qcom-cpufreq-kryo.c => qcom-cpufreq-nvmem.c} (69%)
28 diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
29 index 56c31a78c6920..b1aa485a28dde 100644
30 --- a/drivers/cpufreq/Kconfig.arm
31 +++ b/drivers/cpufreq/Kconfig.arm
32 @@ -120,8 +120,8 @@ config ARM_OMAP2PLUS_CPUFREQ
33 depends on ARCH_OMAP2PLUS
34 default ARCH_OMAP2PLUS
36 -config ARM_QCOM_CPUFREQ_KRYO
37 - tristate "Qualcomm Kryo based CPUFreq"
38 +config ARM_QCOM_CPUFREQ_NVMEM
39 + tristate "Qualcomm nvmem based CPUFreq"
41 depends on QCOM_QFPROM
43 diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
44 index 5a6c70d26c985..8572a918aa755 100644
45 --- a/drivers/cpufreq/Makefile
46 +++ b/drivers/cpufreq/Makefile
47 @@ -64,7 +64,7 @@ obj-$(CONFIG_MACH_MVEBU_V7) += mvebu-cpufreq.o
48 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
49 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
50 obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
51 -obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO) += qcom-cpufreq-kryo.o
52 +obj-$(CONFIG_ARM_QCOM_CPUFREQ_NVMEM) += qcom-cpufreq-nvmem.o
53 obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o
54 obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o
55 obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o
56 diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c
58 rename from drivers/cpufreq/qcom-cpufreq-kryo.c
59 rename to drivers/cpufreq/qcom-cpufreq-nvmem.c
60 index dd64dcf89c74c..fd08120768af2 100644
61 --- a/drivers/cpufreq/qcom-cpufreq-kryo.c
62 +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
64 * based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
65 * defines the voltage and frequency value based on the msm-id in SMEM
66 * and speedbin blown in the efuse combination.
67 - * The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
68 + * The qcom-cpufreq-nvmem driver reads the msm-id and efuse value from the SoC
69 * to provide the OPP framework with required information.
70 * This is used to determine the voltage and frequency value for each OPP of
71 * operating-points-v2 table when it is parsed by the OPP framework.
73 #include <linux/module.h>
74 #include <linux/nvmem-consumer.h>
76 +#include <linux/of_device.h>
77 #include <linux/platform_device.h>
78 #include <linux/pm_opp.h>
79 #include <linux/slab.h>
80 @@ -42,9 +43,9 @@ enum _msm8996_version {
81 NUM_OF_MSM8996_VERSIONS,
84 -static struct platform_device *cpufreq_dt_pdev, *kryo_cpufreq_pdev;
85 +static struct platform_device *cpufreq_dt_pdev, *cpufreq_pdev;
87 -static enum _msm8996_version qcom_cpufreq_kryo_get_msm_id(void)
88 +static enum _msm8996_version qcom_cpufreq_get_msm_id(void)
92 @@ -73,28 +74,62 @@ static enum _msm8996_version qcom_cpufreq_kryo_get_msm_id(void)
96 -static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
97 +static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev,
98 + struct nvmem_cell *speedbin_nvmem,
101 - struct opp_table **opp_tables;
104 enum _msm8996_version msm8996_version;
106 + msm8996_version = qcom_cpufreq_get_msm_id();
107 + if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
108 + dev_err(cpu_dev, "Not Snapdragon 820/821!");
112 + speedbin = nvmem_cell_read(speedbin_nvmem, &len);
113 + if (IS_ERR(speedbin))
114 + return PTR_ERR(speedbin);
116 + switch (msm8996_version) {
118 + *versions = 1 << (unsigned int)(*speedbin);
121 + *versions = 1 << ((unsigned int)(*speedbin) + 4);
132 +static int qcom_cpufreq_probe(struct platform_device *pdev)
134 + struct opp_table **opp_tables;
135 + int (*get_version)(struct device *cpu_dev,
136 + struct nvmem_cell *speedbin_nvmem,
138 struct nvmem_cell *speedbin_nvmem;
139 struct device_node *np;
140 struct device *cpu_dev;
145 + const struct of_device_id *match;
148 cpu_dev = get_cpu_device(0);
152 - msm8996_version = qcom_cpufreq_kryo_get_msm_id();
153 - if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
154 - dev_err(cpu_dev, "Not Snapdragon 820/821!");
155 + match = pdev->dev.platform_data;
156 + get_version = match->data;
161 np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
163 @@ -115,23 +150,10 @@ static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
164 return PTR_ERR(speedbin_nvmem);
167 - speedbin = nvmem_cell_read(speedbin_nvmem, &len);
168 + ret = get_version(cpu_dev, speedbin_nvmem, &versions);
169 nvmem_cell_put(speedbin_nvmem);
170 - if (IS_ERR(speedbin))
171 - return PTR_ERR(speedbin);
173 - switch (msm8996_version) {
175 - versions = 1 << (unsigned int)(*speedbin);
178 - versions = 1 << ((unsigned int)(*speedbin) + 4);
188 opp_tables = kcalloc(num_possible_cpus(), sizeof(*opp_tables), GFP_KERNEL);
190 @@ -174,7 +196,7 @@ static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
194 -static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
195 +static int qcom_cpufreq_remove(struct platform_device *pdev)
197 struct opp_table **opp_tables = platform_get_drvdata(pdev);
199 @@ -189,18 +211,20 @@ static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
203 -static struct platform_driver qcom_cpufreq_kryo_driver = {
204 - .probe = qcom_cpufreq_kryo_probe,
205 - .remove = qcom_cpufreq_kryo_remove,
206 +static struct platform_driver qcom_cpufreq_driver = {
207 + .probe = qcom_cpufreq_probe,
208 + .remove = qcom_cpufreq_remove,
210 - .name = "qcom-cpufreq-kryo",
211 + .name = "qcom-cpufreq-nvmem",
215 -static const struct of_device_id qcom_cpufreq_kryo_match_list[] __initconst = {
216 - { .compatible = "qcom,apq8096", },
217 - { .compatible = "qcom,msm8996", },
219 +static const struct of_device_id qcom_cpufreq_match_list[] __initconst = {
220 + { .compatible = "qcom,apq8096",
221 + .data = qcom_cpufreq_kryo_name_version },
222 + { .compatible = "qcom,msm8996",
223 + .data = qcom_cpufreq_kryo_name_version },
228 @@ -209,7 +233,7 @@ static const struct of_device_id qcom_cpufreq_kryo_match_list[] __initconst = {
229 * which may be defered as well. The init here is only registering
230 * the driver and the platform device.
232 -static int __init qcom_cpufreq_kryo_init(void)
233 +static int __init qcom_cpufreq_init(void)
235 struct device_node *np = of_find_node_by_path("/");
236 const struct of_device_id *match;
237 @@ -218,32 +242,32 @@ static int __init qcom_cpufreq_kryo_init(void)
241 - match = of_match_node(qcom_cpufreq_kryo_match_list, np);
242 + match = of_match_node(qcom_cpufreq_match_list, np);
247 - ret = platform_driver_register(&qcom_cpufreq_kryo_driver);
248 + ret = platform_driver_register(&qcom_cpufreq_driver);
249 if (unlikely(ret < 0))
252 - kryo_cpufreq_pdev = platform_device_register_simple(
253 - "qcom-cpufreq-kryo", -1, NULL, 0);
254 - ret = PTR_ERR_OR_ZERO(kryo_cpufreq_pdev);
255 + cpufreq_pdev = platform_device_register_data(NULL, "qcom-cpufreq-nvmem",
256 + -1, match, sizeof(*match));
257 + ret = PTR_ERR_OR_ZERO(cpufreq_pdev);
261 - platform_driver_unregister(&qcom_cpufreq_kryo_driver);
262 + platform_driver_unregister(&qcom_cpufreq_driver);
265 -module_init(qcom_cpufreq_kryo_init);
266 +module_init(qcom_cpufreq_init);
268 -static void __exit qcom_cpufreq_kryo_exit(void)
269 +static void __exit qcom_cpufreq_exit(void)
271 - platform_device_unregister(kryo_cpufreq_pdev);
272 - platform_driver_unregister(&qcom_cpufreq_kryo_driver);
273 + platform_device_unregister(cpufreq_pdev);
274 + platform_driver_unregister(&qcom_cpufreq_driver);
276 -module_exit(qcom_cpufreq_kryo_exit);
277 +module_exit(qcom_cpufreq_exit);
279 -MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
280 +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. CPUfreq driver");
281 MODULE_LICENSE("GPL v2");