Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4920353 authored by Stephen Boyd's avatar Stephen Boyd Committed by Kyle Yan
Browse files

clk: qcom: Add KPSS ACC/GCC driver



The ACC and GCC regions present in KPSSv1 contain registers to
control clocks and power to each Krait CPU and L2. For CPUfreq
purposes probe these devices and expose a mux clock that chooses
between PXO and PLL8.

Change-Id: Icaa1b68652eb4c836e8aacad80ff6cebe34cad4f
Cc: <devicetree@vger.kernel.org>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Signed-off-by: default avatarTaniya Das <tdas@codeaurora.org>
parent d0c3d215
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -21,10 +21,17 @@ PROPERTIES
		    the register region. An optional second element specifies
		    the base address and size of the alias register region.

- clock-output-names:
	Usage: optional
	Value type: <string>
	Definition: Name of the output clock. Typically acpuX_aux where X is a
		    CPU number starting at 0.

Example:

	clock-controller@2088000 {
		compatible = "qcom,kpss-acc-v2";
		reg = <0x02088000 0x1000>,
		      <0x02008000 0x1000>;
		clock-output-names = "acpu0_aux";
	};
+28 −0
Original line number Diff line number Diff line
Krait Processor Sub-system (KPSS) Global Clock Controller (GCC)

PROPERTIES

- compatible:
	Usage: required
	Value type: <string>
	Definition: should be one of:
			"qcom,kpss-gcc"

- reg:
	Usage: required
	Value type: <prop-encoded-array>
	Definition: base address and size of the register region

- clock-output-names:
	Usage: required
	Value type: <string>
	Definition: Name of the output clock. Typically acpu_l2_aux indicating
		    an L2 cache auxiliary clock.

Example:

	l2cc: clock-controller@2011000 {
		compatible = "qcom,kpss-gcc";
		reg = <0x2011000 0x1000>;
		clock-output-names = "acpu_l2_aux";
	};
+8 −0
Original line number Diff line number Diff line
@@ -132,6 +132,14 @@ config QCOM_HFPLL
	  Say Y if you want to support CPU frequency scaling on devices
	  such as MSM8974, APQ8084, etc.

config KPSS_XCC
	tristate "KPSS Clock Controller"
	depends on COMMON_CLK_QCOM
	help
	  Support for the Krait ACC and GCC clock controllers. Say Y
	  if you want to support CPU frequency scaling on devices such
	  as MSM8960, APQ8064, etc.

config KRAIT_CLOCKS
	bool
	select KRAIT_L2_ACCESSORS
+1 −0
Original line number Diff line number Diff line
@@ -26,4 +26,5 @@ obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
+95 −0
Original line number Diff line number Diff line
/* Copyright (c) 2014-2015, 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/err.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>

static const char *aux_parents[] = {
	"pll8_vote",
	"pxo",
};

static unsigned int aux_parent_map[] = {
	3,
	0,
};

static const struct of_device_id kpss_xcc_match_table[] = {
	{ .compatible = "qcom,kpss-acc-v1", .data = (void *)1UL },
	{ .compatible = "qcom,kpss-gcc" },
	{}
};
MODULE_DEVICE_TABLE(of, kpss_xcc_match_table);

static int kpss_xcc_driver_probe(struct platform_device *pdev)
{
	const struct of_device_id *id;
	struct clk *clk;
	struct resource *res;
	void __iomem *base;
	const char *name;

	id = of_match_device(kpss_xcc_match_table, &pdev->dev);
	if (!id)
		return -ENODEV;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	if (id->data) {
		if (of_property_read_string_index(pdev->dev.of_node,
					"clock-output-names", 0, &name))
			return -ENODEV;
		base += 0x14;
	} else {
		name = "acpu_l2_aux";
		base += 0x28;
	}

	clk = clk_register_mux_table(&pdev->dev, name, aux_parents,
				     ARRAY_SIZE(aux_parents), 0, base, 0, 0x3,
				     0, aux_parent_map, NULL);

	platform_set_drvdata(pdev, clk);

	return PTR_ERR_OR_ZERO(clk);
}

static int kpss_xcc_driver_remove(struct platform_device *pdev)
{
	clk_unregister_mux(platform_get_drvdata(pdev));
	return 0;
}

static struct platform_driver kpss_xcc_driver = {
	.probe = kpss_xcc_driver_probe,
	.remove = kpss_xcc_driver_remove,
	.driver = {
		.name = "kpss-xcc",
		.of_match_table = kpss_xcc_match_table,
	},
};
module_platform_driver(kpss_xcc_driver);

MODULE_DESCRIPTION("Krait Processor Sub System (KPSS) Clock Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:kpss-xcc");