cpufreq: ipq40xx: add cpufreq driver [chromiumos/third_party/kernel : chromeos-3.18]

28 views
Skip to first unread message

Matthew McClintock (Gerrit)

unread,
Feb 16, 2016, 4:10:23 PM2/16/16
to Olof Johansson
Matthew McClintock has uploaded a new change for review.

https://chromium-review.googlesource.com/327791

Change subject: cpufreq: ipq40xx: add cpufreq driver
......................................................................

cpufreq: ipq40xx: add cpufreq driver

added support for ipq40xx in the cpufreq framework

Change-Id: I94f3d63d1b1ffc564c60e9fa21f25d5cf58146ea
Signed-off-by: Pradeep Banavathi <prad...@codeaurora.org>
Signed-off-by: Senthilkumar N L <snla...@codeaurora.org>
---
M Documentation/devicetree/bindings/clock/qcom,gcc.txt
A Documentation/devicetree/bindings/cpufreq/cpufreq-qca.txt
M drivers/clk/qcom/Kconfig
M drivers/clk/qcom/Makefile
M drivers/cpufreq/Kconfig
M drivers/cpufreq/Makefile
A drivers/cpufreq/qca-ipq40xx-cpufreq.c
7 files changed, 286 insertions(+), 0 deletions(-)



diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index edfdc5b..b2e50f4 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -13,6 +13,7 @@
"qcom,gcc-msm8974pro"
"qcom,gcc-msm8974pro-ac"
"qcom,gcc-dummy"
+ "qcom,gcc-ipq40xx"

- reg : shall contain base register location and length
- #clock-cells : shall contain 1
diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qca.txt
b/Documentation/devicetree/bindings/cpufreq/cpufreq-qca.txt
new file mode 100644
index 0000000..d222e64
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qca.txt
@@ -0,0 +1,22 @@
+
+qca,ipq40xx cpufreq driver
+-------------------
+
+IPQ40xx SoC cpufreq driver for CPU frequency scaling.
+
+Required properties:
+- operating-points: Table of frequencies and voltage CPU could be
transitioned into,
+ in the decreasing order. Frequency should be in KHz units and voltage
+ should be in microvolts.
+
+Optional properties:
+- clock-latency: Clock monitor latency in microsecond. Example: 200usec
+
+All the required listed above must be defined under node cpufreq.
+
+Example:
+--------
+ cpu_freq_ipq40xx {
+ compatible = "qca,ipq40xx_freq";
+ clock-latency = <0x100>;
+ };
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 1107351..2e7957e 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -70,3 +70,21 @@
Support for the multimedia clock controller on msm8974 devices.
Say Y if you want to support multimedia devices such as display,
graphics, video encode/decode, camera, etc.
+
+config IPQ_GCC_40XX
+ tristate "IPQ40XX Global Clock Controller"
+ depends on COMMON_CLK_QCOM
+ help
+ Support for the global clock controller on IPQ40xx devices.
+ Say Y if you want to use peripheral devices
+ such as UART, SPI,
+ i2c, USB, SD/eMMC, SATA, PCIe, etc.
+
+config IPQ_ADCC_40XX
+ tristate "IPQ40XX Audio Clock Controller"
+ depends on COMMON_CLK_QCOM
+ help
+ Support for the audio clock controller on IPQ40xx devices.
+ Say Y if you want to use Audio Clocks
+ these are used for clks like TXM,RXM, TXB, and RXB
+ Also, this is used for selecting the pads as the sources.
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 783cfb2..51a3cff 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -16,3 +16,4 @@
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
+obj-$(CONFIG_IPQ_GCC_40XX) += gcc-ipq40xx.o
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 00e75a9..6bb3a68 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -223,6 +223,17 @@

If in doubt, say N.

+config QCA_IPQ40XX_CPUFREQ
+ tristate "QCA IPQ40XX driver"
+ depends on HAVE_CLK && OF
+ select PM_OPP
+ help
+ This adds a QCA IPQ40XX cpufreq driver for CPUsfrequency management.
+ It supports frequency scaling of all CPUs together as the clock
+ is shared across CPU and it does not support voltage scaling.
+
+ If in doubt, say N.
+
menu "x86 CPU frequency scaling drivers"
depends on X86
source "drivers/cpufreq/Kconfig.x86"
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 548d650..fa6c6fc 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -81,6 +81,7 @@
obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o
obj-$(CONFIG_ARM_TEGRA210_CPUFREQ) += tegra210-cpufreq.o
obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o
+obj-$(CONFIG_QCA_IPQ40XX_CPUFREQ) += qca-ipq40xx-cpufreq.o


##################################################################################
# PowerPC platform drivers
diff --git a/drivers/cpufreq/qca-ipq40xx-cpufreq.c
b/drivers/cpufreq/qca-ipq40xx-cpufreq.c
new file mode 100644
index 0000000..9ac0616
--- /dev/null
+++ b/drivers/cpufreq/qca-ipq40xx-cpufreq.c
@@ -0,0 +1,232 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/cpumask.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_opp.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+enum efreq_lvl {
+ L0, L1, L2, L3, L_INVALID
+};
+
+#define freq_entry(a, b, c) \
+ { .flags = a, .driver_data = b, .frequency = c, }
+
+static unsigned int transition_latency;
+static DEFINE_PER_CPU(struct clk *, cpu_clks);
+struct cpufreq_frequency_table *ftbl;
+
+
+static struct cpufreq_frequency_table *cpufreq_parse_dt(struct device *dev,
+ char *tbl_name, int cpu)
+{
+ u32 ret, nf, i;
+ u32 *data;
+
+ /* Parse list of usable CPU frequencies. */
+ if (!of_find_property(dev->of_node, tbl_name, &nf))
+ return ERR_PTR(-EINVAL);
+ nf /= sizeof(*data);
+
+ if (nf == 0)
+ return ERR_PTR(-EINVAL);
+
+ data = devm_kzalloc(dev, nf * sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return ERR_PTR(-ENOMEM);
+
+ ret = of_property_read_u32_array(dev->of_node, tbl_name, data, nf);
+ if (ret)
+ return ERR_PTR(ret);
+
+ ftbl = devm_kzalloc(dev, (nf + 1) * sizeof(*ftbl), GFP_KERNEL);
+ if (!ftbl)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0; i < nf; i++) {
+ unsigned long f;
+ struct clk *cpu_clk;
+
+ cpu_clk = per_cpu(cpu_clks, cpu);
+
+ f = clk_round_rate(cpu_clk, data[i] * 1000);
+ if (IS_ERR_VALUE(f))
+ break;
+ f /= 1000;
+
+ /*
+ * Check if this is the last feasible frequency in the table.
+ *
+ * The table listing frequencies higher than what the HW can
+ * support is not an error since the table might be shared
+ * across CPUs in different speed bins. It's also not
+ * sufficient to check if the rounded rate is lower than the
+ * requested rate as it doesn't cover the following example:
+ *
+ * Table lists: 2.2 GHz and 2.5 GHz.
+ * Rounded rate returns: 2.2 GHz and 2.3 GHz.
+ *
+ * In this case, we can CPUfreq to use 2.2 GHz and 2.3 GHz
+ * instead of rejecting the 2.5 GHz table entry.
+ */
+ if (i > 0 && f <= ftbl[i-1].frequency)
+ break;
+
+ ftbl[i].driver_data = i;
+ ftbl[i].frequency = f;
+ }
+
+ ftbl[i].driver_data = i;
+ ftbl[i].frequency = CPUFREQ_TABLE_END;
+
+ devm_kfree(dev, data);
+
+ return ftbl;
+}
+
+static int ipq40xx_set_target(struct cpufreq_policy *policy, unsigned int
index)
+{
+ int ret;
+ unsigned int old_freq, new_freq;
+ long freq_Hz, freq_exact;
+ struct clk *cpu_clk;
+
+ cpu_clk = per_cpu(cpu_clks, policy->cpu);
+ freq_Hz = clk_round_rate(cpu_clk, ftbl[index].frequency * 1000);
+ if (freq_Hz <= 0)
+ freq_Hz = ftbl[index].frequency * 1000;
+
+ freq_exact = freq_Hz;
+ new_freq = freq_Hz;
+ old_freq = clk_get_rate(cpu_clk);
+
+ ret = clk_set_rate(cpu_clk, freq_exact);
+ if (ret)
+ pr_err("failed to set clock rate: %d\n", ret);
+
+ return ret;
+}
+
+static unsigned int ipq40xx_get_target(unsigned int cpu)
+{
+ struct clk *cpu_clk;
+
+ cpu_clk = per_cpu(cpu_clks, cpu);
+ if (cpu_clk)
+ return clk_get_rate(cpu_clk) / 1000;
+
+ return 0;
+}
+
+static int ipq40xx_cpufreq_init(struct cpufreq_policy *policy)
+{
+ policy->clk = per_cpu(cpu_clks, policy->cpu);
+
+ if (!ftbl) {
+ pr_err("Freq table not initialized.\n");
+ return -ENODEV;
+ }
+ cpufreq_table_validate_and_show(policy, ftbl);
+ return cpufreq_generic_init(policy, ftbl, transition_latency);
+}
+
+static struct cpufreq_driver qca_ipq40xx_cpufreq_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = cpufreq_generic_frequency_table_verify,
+ .target_index = ipq40xx_set_target,
+ .get = ipq40xx_get_target,
+ .init = ipq40xx_cpufreq_init,
+ .name = "ipq40xx_freq",
+ .attr = cpufreq_generic_attr,
+};
+
+static int __init ipq40xx_cpufreq_probe(struct platform_device *pdev)
+{
+ struct device_node *np = NULL;
+ struct device *dev;
+ struct clk *clk;
+ unsigned int cpu;
+ int ret;
+
+ for_each_possible_cpu(cpu) {
+ dev = get_cpu_device(cpu);
+ if (!dev) {
+ pr_err("failed to get A7 device\n");
+ ret = -ENOENT;
+ goto out_put_node;
+ }
+ per_cpu(cpu_clks, cpu) = clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(clk)) {
+ pr_err("failed to get clk device\n");
+ ret = PTR_ERR(clk);
+ goto out_put_node;
+ }
+ }
+
+ ftbl = cpufreq_parse_dt(&pdev->dev, "qcom,cpufreq-table", 0);
+
+ np = of_node_get(pdev->dev.of_node);
+ of_property_read_u32(np, "clock-latency", &transition_latency);
+
+ if (!transition_latency) {
+ pr_info("%s: Clock latency not found. Defaults...\n"
+ , __func__);
+ transition_latency = CPUFREQ_ETERNAL;
+ }
+
+ ret = cpufreq_register_driver(&qca_ipq40xx_cpufreq_driver);
+ if (ret) {
+ pr_err("failed register driver: %d\n", ret);
+ goto out_put_node;
+ }
+ return 0;
+
+out_put_node:
+ of_node_put(np);
+ return ret;
+}
+
+static int __exit ipq40xx_cpufreq_remove(struct platform_device *pdev)
+{
+ cpufreq_unregister_driver(&qca_ipq40xx_cpufreq_driver);
+ return 0;
+}
+
+static struct of_device_id ipq40xx_match_table[] = {
+ {.compatible = "qca,ipq40xx_freq"},
+ {},
+};
+
+static struct platform_driver qca_ipq40xx_cpufreq_platdrv = {
+ .probe = ipq40xx_cpufreq_probe,
+ .remove = ipq40xx_cpufreq_remove,
+ .driver = {
+ .name = "cpufreq-ipq40xx",
+ .owner = THIS_MODULE,
+ .of_match_table = ipq40xx_match_table,
+ },
+};
+
+module_platform_driver(qca_ipq40xx_cpufreq_platdrv);
+
+MODULE_DESCRIPTION("QCA IPQ40XX CPUfreq driver");

--
To view, visit https://chromium-review.googlesource.com/327791
To unsubscribe, visit https://chromium-review.googlesource.com/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I94f3d63d1b1ffc564c60e9fa21f25d5cf58146ea
Gerrit-PatchSet: 1
Gerrit-Project: chromiumos/third_party/kernel
Gerrit-Branch: chromeos-3.18
Gerrit-Owner: Matthew McClintock <mmcc...@qca.qualcomm.com>

Cristian Prundeanu (Gerrit)

unread,
Feb 25, 2016, 12:58:29 PM2/25/16
to Matthew McClintock, Dmitry Torokhov, Sreedhar Sambangi, Grant Grundler
Cristian Prundeanu has uploaded a new patch set (#2).

Change subject: cpufreq: ipq40xx: add cpufreq driver
......................................................................

cpufreq: ipq40xx: add cpufreq driver

added support for ipq40xx in the cpufreq framework

BUG=chromium-os:49255
TEST=Passed QCA non-ChromiumOS test suite

Change-Id: I94f3d63d1b1ffc564c60e9fa21f25d5cf58146ea
Reviewed-on: https://chromium-review.googlesource.com/327791
Signed-off-by: Pradeep Banavathi <prad...@codeaurora.org>
Signed-off-by: Senthilkumar N L <snla...@codeaurora.org>
Signed-off-by: Cristian Prundeanu <cpru...@codeaurora.org>
---
M Documentation/devicetree/bindings/clock/qcom,gcc.txt
A Documentation/devicetree/bindings/cpufreq/cpufreq-qca.txt
M drivers/clk/qcom/Kconfig
M drivers/clk/qcom/Makefile
M drivers/cpufreq/Kconfig
M drivers/cpufreq/Makefile
A drivers/cpufreq/qca-ipq40xx-cpufreq.c
7 files changed, 286 insertions(+), 0 deletions(-)


Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I94f3d63d1b1ffc564c60e9fa21f25d5cf58146ea
Gerrit-PatchSet: 2
Gerrit-Project: chromiumos/third_party/kernel
Gerrit-Branch: chromeos-3.18
Gerrit-Owner: Matthew McClintock <mmcc...@qca.qualcomm.com>
Gerrit-Reviewer: Cristian Prundeanu <cpru...@qca.qualcomm.com>
Gerrit-Reviewer: Dmitry Torokhov <dt...@chromium.org>
Gerrit-Reviewer: Grant Grundler <grun...@chromium.org>
Gerrit-Reviewer: Sreedhar Sambangi <ssam...@codeaurora.org>

Cristian Prundeanu (Gerrit)

unread,
Feb 25, 2016, 2:56:41 PM2/25/16
to Matthew McClintock, Dmitry Torokhov, Sreedhar Sambangi, Grant Grundler
Cristian Prundeanu has uploaded a new patch set (#3).

Change subject: cpufreq: ipq40xx: add cpufreq driver
......................................................................

cpufreq: ipq40xx: add cpufreq driver

added support for ipq40xx in the cpufreq framework

BUG=chrome-os-partner:49255
TEST=Passed QCA non-ChromiumOS test suite

Change-Id: I94f3d63d1b1ffc564c60e9fa21f25d5cf58146ea
Reviewed-on: https://chromium-review.googlesource.com/327791
Signed-off-by: Pradeep Banavathi <prad...@codeaurora.org>
Signed-off-by: Senthilkumar N L <snla...@codeaurora.org>
Signed-off-by: Cristian Prundeanu <cpru...@codeaurora.org>
---
M Documentation/devicetree/bindings/clock/qcom,gcc.txt
A Documentation/devicetree/bindings/cpufreq/cpufreq-qca.txt
M drivers/clk/qcom/Kconfig
M drivers/clk/qcom/Makefile
M drivers/cpufreq/Kconfig
M drivers/cpufreq/Makefile
A drivers/cpufreq/qca-ipq40xx-cpufreq.c
7 files changed, 286 insertions(+), 0 deletions(-)


Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I94f3d63d1b1ffc564c60e9fa21f25d5cf58146ea
Gerrit-PatchSet: 3
Gerrit-Project: chromiumos/third_party/kernel
Gerrit-Branch: chromeos-3.18
Gerrit-Owner: Matthew McClintock <mmcc...@qca.qualcomm.com>

Matthew McClintock (Gerrit)

unread,
Mar 7, 2016, 2:06:32 PM3/7/16
to Cristian Prundeanu, Grant Grundler, Dmitry Torokhov, Sreedhar Sambangi
Matthew McClintock has abandoned this change.

Change subject: cpufreq: ipq40xx: add cpufreq driver
......................................................................


Abandoned
Gerrit-MessageType: abandon
Gerrit-Change-Id: I94f3d63d1b1ffc564c60e9fa21f25d5cf58146ea
Gerrit-PatchSet: 3
Gerrit-Project: chromiumos/third_party/kernel
Gerrit-Branch: chromeos-3.18
Gerrit-Owner: Matthew McClintock <mmcc...@qca.qualcomm.com>
Reply all
Reply to author
Forward
0 new messages