/branches/gl-inet/target/linux/ipq806x/patches-4.14/0039-clk-qcom-Add-HFPLL-driver.patch |
@@ -0,0 +1,206 @@ |
From patchwork Fri Dec 8 09:42:22 2017 |
Content-Type: text/plain; charset="utf-8" |
MIME-Version: 1.0 |
Content-Transfer-Encoding: 7bit |
Subject: [v4,04/12] clk: qcom: Add HFPLL driver |
From: Sricharan R <sricharan@codeaurora.org> |
X-Patchwork-Id: 10102079 |
Message-Id: <1512726150-7204-5-git-send-email-sricharan@codeaurora.org> |
To: mturquette@baylibre.com, sboyd@codeaurora.org, |
devicetree@vger.kernel.org, linux-pm@vger.kernel.org, |
linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, |
viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org |
Cc: sricharan@codeaurora.org |
Date: Fri, 8 Dec 2017 15:12:22 +0530 |
|
From: Stephen Boyd <sboyd@codeaurora.org> |
|
On some devices (MSM8974 for example), the HFPLLs are |
instantiated within the Krait processor subsystem as separate |
register regions. Add a driver for these PLLs so that we can |
provide HFPLL clocks for use by the system. |
|
Cc: <devicetree@vger.kernel.org> |
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> |
--- |
.../devicetree/bindings/clock/qcom,hfpll.txt | 40 ++++++++ |
drivers/clk/qcom/Kconfig | 8 ++ |
drivers/clk/qcom/Makefile | 1 + |
drivers/clk/qcom/hfpll.c | 106 +++++++++++++++++++++ |
4 files changed, 155 insertions(+) |
create mode 100644 Documentation/devicetree/bindings/clock/qcom,hfpll.txt |
create mode 100644 drivers/clk/qcom/hfpll.c |
|
--- /dev/null |
+++ b/Documentation/devicetree/bindings/clock/qcom,hfpll.txt |
@@ -0,0 +1,40 @@ |
+High-Frequency PLL (HFPLL) |
+ |
+PROPERTIES |
+ |
+- compatible: |
+ Usage: required |
+ Value type: <string> |
+ Definition: must be "qcom,hfpll" |
+ |
+- reg: |
+ Usage: required |
+ Value type: <prop-encoded-array> |
+ Definition: address and size of HPLL registers. An optional second |
+ element specifies the address and size of the alias |
+ register region. |
+ |
+- clock-output-names: |
+ Usage: required |
+ Value type: <string> |
+ Definition: Name of the PLL. Typically hfpllX where X is a CPU number |
+ starting at 0. Otherwise hfpll_Y where Y is more specific |
+ such as "l2". |
+ |
+Example: |
+ |
+1) An HFPLL for the L2 cache. |
+ |
+ clock-controller@f9016000 { |
+ compatible = "qcom,hfpll"; |
+ reg = <0xf9016000 0x30>; |
+ clock-output-names = "hfpll_l2"; |
+ }; |
+ |
+2) An HFPLL for CPU0. This HFPLL has the alias register region. |
+ |
+ clock-controller@f908a000 { |
+ compatible = "qcom,hfpll"; |
+ reg = <0xf908a000 0x30>, <0xf900a000 0x30>; |
+ clock-output-names = "hfpll0"; |
+ }; |
--- a/drivers/clk/qcom/Kconfig |
+++ b/drivers/clk/qcom/Kconfig |
@@ -196,3 +196,11 @@ config MSM_MMCC_8996 |
Support for the multimedia clock controller on msm8996 devices. |
Say Y if you want to support multimedia devices such as display, |
graphics, video encode/decode, camera, etc. |
+ |
+config QCOM_HFPLL |
+ tristate "High-Frequency PLL (HFPLL) Clock Controller" |
+ depends on COMMON_CLK_QCOM |
+ help |
+ Support for the high-frequency PLLs present on Qualcomm devices. |
+ Say Y if you want to support CPU frequency scaling on devices |
+ such as MSM8974, APQ8084, etc. |
--- a/drivers/clk/qcom/Makefile |
+++ b/drivers/clk/qcom/Makefile |
@@ -35,3 +35,4 @@ obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8 |
obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o |
obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o |
obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o |
+obj-$(CONFIG_QCOM_HFPLL) += hfpll.o |
--- /dev/null |
+++ b/drivers/clk/qcom/hfpll.c |
@@ -0,0 +1,106 @@ |
+/* |
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. |
+ * |
+ * This program is free software; you can redistribute it and/or modify |
+ * it under the terms of the GNU General Public License version 2 and |
+ * only version 2 as published by the Free Software Foundation. |
+ * |
+ * This program is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ */ |
+ |
+#include <linux/kernel.h> |
+#include <linux/init.h> |
+#include <linux/module.h> |
+#include <linux/platform_device.h> |
+#include <linux/of.h> |
+#include <linux/clk.h> |
+#include <linux/clk-provider.h> |
+#include <linux/regmap.h> |
+ |
+#include "clk-regmap.h" |
+#include "clk-hfpll.h" |
+ |
+static const struct hfpll_data hdata = { |
+ .mode_reg = 0x00, |
+ .l_reg = 0x04, |
+ .m_reg = 0x08, |
+ .n_reg = 0x0c, |
+ .user_reg = 0x10, |
+ .config_reg = 0x14, |
+ .config_val = 0x430405d, |
+ .status_reg = 0x1c, |
+ .lock_bit = 16, |
+ |
+ .user_val = 0x8, |
+ .user_vco_mask = 0x100000, |
+ .low_vco_max_rate = 1248000000, |
+ .min_rate = 537600000UL, |
+ .max_rate = 2900000000UL, |
+}; |
+ |
+static const struct of_device_id qcom_hfpll_match_table[] = { |
+ { .compatible = "qcom,hfpll" }, |
+ { } |
+}; |
+MODULE_DEVICE_TABLE(of, qcom_hfpll_match_table); |
+ |
+static const struct regmap_config hfpll_regmap_config = { |
+ .reg_bits = 32, |
+ .reg_stride = 4, |
+ .val_bits = 32, |
+ .max_register = 0x30, |
+ .fast_io = true, |
+}; |
+ |
+static int qcom_hfpll_probe(struct platform_device *pdev) |
+{ |
+ struct resource *res; |
+ struct device *dev = &pdev->dev; |
+ void __iomem *base; |
+ struct regmap *regmap; |
+ struct clk_hfpll *h; |
+ struct clk_init_data init = { |
+ .parent_names = (const char *[]){ "xo" }, |
+ .num_parents = 1, |
+ .ops = &clk_ops_hfpll, |
+ }; |
+ |
+ h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL); |
+ if (!h) |
+ return -ENOMEM; |
+ |
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
+ base = devm_ioremap_resource(dev, res); |
+ if (IS_ERR(base)) |
+ return PTR_ERR(base); |
+ |
+ regmap = devm_regmap_init_mmio(&pdev->dev, base, &hfpll_regmap_config); |
+ if (IS_ERR(regmap)) |
+ return PTR_ERR(regmap); |
+ |
+ if (of_property_read_string_index(dev->of_node, "clock-output-names", |
+ 0, &init.name)) |
+ return -ENODEV; |
+ |
+ h->d = &hdata; |
+ h->clkr.hw.init = &init; |
+ spin_lock_init(&h->lock); |
+ |
+ return devm_clk_register_regmap(&pdev->dev, &h->clkr); |
+} |
+ |
+static struct platform_driver qcom_hfpll_driver = { |
+ .probe = qcom_hfpll_probe, |
+ .driver = { |
+ .name = "qcom-hfpll", |
+ .of_match_table = qcom_hfpll_match_table, |
+ }, |
+}; |
+module_platform_driver(qcom_hfpll_driver); |
+ |
+MODULE_DESCRIPTION("QCOM HFPLL Clock Driver"); |
+MODULE_LICENSE("GPL v2"); |
+MODULE_ALIAS("platform:qcom-hfpll"); |