123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- Content-Type: text/plain; charset="utf-8"
- MIME-Version: 1.0
- Content-Transfer-Encoding: 7bit
- Subject: [v3,06/13] clk: qcom: Add HFPLL driver
- From: Stephen Boyd <sboyd@codeaurora.org>
- X-Patchwork-Id: 6063231
- Message-Id: <1426920332-9340-7-git-send-email-sboyd@codeaurora.org>
- To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
- Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
- linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
- Viresh Kumar <viresh.kumar@linaro.org>, <devicetree@vger.kernel.org>
- Date: Fri, 20 Mar 2015 23:45:25 -0700
- 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 | 109 +++++++++++++++++++++
- 4 files changed, 158 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
- @@ -70,3 +70,11 @@ config MSM_MMCC_8974
- 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 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
- @@ -17,3 +17,4 @@ obj-$(CONFIG_MSM_GCC_8960) += gcc-msm896
- 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_QCOM_HFPLL) += hfpll.o
- --- /dev/null
- +++ b/drivers/clk/qcom/hfpll.c
- @@ -0,0 +1,109 @@
- +/*
- + * 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 clk *clk;
- + 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);
- +
- + clk = devm_clk_register_regmap(&pdev->dev, &h->clkr);
- +
- + return PTR_ERR_OR_ZERO(clk);
- +}
- +
- +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");
|