devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Lechner <david@lechnology.com>
To: linux-clk@vger.kernel.org, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Cc: Mark Rutland <mark.rutland@arm.com>,
	David Lechner <david@lechnology.com>,
	Kevin Hilman <khilman@kernel.org>,
	Stephen Boyd <sboyd@codeaurora.org>,
	Michael Turquette <mturquette@baylibre.com>,
	Sekhar Nori <nsekhar@ti.com>,
	linux-kernel@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
	Adam Ford <aford173@gmail.com>
Subject: [PATCH v5 02/44] clk: davinci: New driver for davinci PLL clocks
Date: Sun,  7 Jan 2018 20:17:01 -0600	[thread overview]
Message-ID: <1515377863-20358-3-git-send-email-david@lechnology.com> (raw)
In-Reply-To: <1515377863-20358-1-git-send-email-david@lechnology.com>

This adds a new driver for mach-davinci PLL clocks. This is porting the
code from arch/arm/mach-davinci/clock.c to the common clock framework.
Additionally, it adds device tree support for these clocks.

The ifeq ($(CONFIG_COMMON_CLK), y) in the Makefile is needed to prevent
compile errors until the clock code in arch/arm/mach-davinci is removed.

Note: although there are similar clocks for TI Keystone we are not able
to share the code for a few reasons. The keystone clocks are device tree
only and use legacy one-node-per-clock bindings. Also the register
layouts are a bit different, which would add even more if/else mess
to the keystone clocks. And the keystone PLL driver doesn't support
setting clock rates.

Signed-off-by: David Lechner <david@lechnology.com>
---
 MAINTAINERS                  |   6 +
 drivers/clk/Makefile         |   1 +
 drivers/clk/davinci/Makefile |   5 +
 drivers/clk/davinci/pll.c    | 564 +++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/davinci/pll.h    |  61 +++++
 5 files changed, 637 insertions(+)
 create mode 100644 drivers/clk/davinci/Makefile
 create mode 100644 drivers/clk/davinci/pll.c
 create mode 100644 drivers/clk/davinci/pll.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a6e86e2..1db0cf0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13554,6 +13554,12 @@ F:	arch/arm/mach-davinci/
 F:	drivers/i2c/busses/i2c-davinci.c
 F:	arch/arm/boot/dts/da850*
 
+TI DAVINCI SERIES CLOCK DRIVER
+M:	David Lechner <david@lechnology.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/clock/ti/davinci/
+F:	drivers/clk/davinci/
+
 TI DAVINCI SERIES GPIO DRIVER
 M:	Keerthy <j-keerthy@ti.com>
 L:	linux-gpio@vger.kernel.org
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f7f761b..c865fd0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_ARCH_ARTPEC)		+= axis/
 obj-$(CONFIG_ARC_PLAT_AXS10X)		+= axs10x/
 obj-y					+= bcm/
 obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
+obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
 obj-$(CONFIG_H8300)			+= h8300/
 obj-$(CONFIG_ARCH_HISI)			+= hisilicon/
 obj-y					+= imgtec/
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
new file mode 100644
index 0000000..d9673bd
--- /dev/null
+++ b/drivers/clk/davinci/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+ifeq ($(CONFIG_COMMON_CLK), y)
+obj-y += pll.o
+endif
diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c
new file mode 100644
index 0000000..46f9c18
--- /dev/null
+++ b/drivers/clk/davinci/pll.c
@@ -0,0 +1,564 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock driver for TI Davinci SoCs
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ *
+ * Based on drivers/clk/keystone/pll.c
+ * Copyright (C) 2013 Texas Instruments Inc.
+ *	Murali Karicheri <m-karicheri2@ti.com>
+ *	Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * And on arch/arm/mach-davinci/clock.c
+ * Copyright (C) 2006-2007 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include "pll.h"
+
+#define REVID		0x000
+#define PLLCTL		0x100
+#define OCSEL		0x104
+#define PLLSECCTL	0x108
+#define PLLM		0x110
+#define PREDIV		0x114
+#define PLLDIV1		0x118
+#define PLLDIV2		0x11c
+#define PLLDIV3		0x120
+#define OSCDIV		0x124
+#define POSTDIV		0x128
+#define BPDIV		0x12c
+#define PLLCMD		0x138
+#define PLLSTAT		0x13c
+#define ALNCTL		0x140
+#define DCHANGE		0x144
+#define CKEN		0x148
+#define CKSTAT		0x14c
+#define SYSTAT		0x150
+#define PLLDIV4		0x160
+#define PLLDIV5		0x164
+#define PLLDIV6		0x168
+#define PLLDIV7		0x16c
+#define PLLDIV8		0x170
+#define PLLDIV9		0x174
+
+#define PLLCTL_PLLEN	BIT(0)
+#define PLLCTL_PLLPWRDN	BIT(1)
+#define PLLCTL_PLLRST	BIT(3)
+#define PLLCTL_PLLDIS	BIT(4)
+#define PLLCTL_PLLENSRC	BIT(5)
+#define PLLCTL_CLKMODE	BIT(8)
+
+#define PLLM_MASK		0x1f
+#define PREDIV_RATIO_MASK	0x1f
+#define PREDIV_PREDEN		BIT(15)
+#define PLLDIV_RATIO_WIDTH	5
+#define PLLDIV_ENABLE_SHIFT	15
+#define OSCDIV_RATIO_WIDTH	5
+#define POSTDIV_RATIO_MASK	0x1f
+#define POSTDIV_POSTDEN		BIT(15)
+#define BPDIV_RATIO_SHIFT	0
+#define BPDIV_RATIO_WIDTH	5
+#define CKEN_OBSCLK_SHIFT	1
+#define CKEN_AUXEN_SHIFT	0
+
+/*
+ * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN
+ * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us
+ * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input
+ * is ~25MHz. Units are micro seconds.
+ */
+#define PLL_BYPASS_TIME		1
+/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */
+#define PLL_RESET_TIME		1
+/*
+ * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4
+ * Units are micro seconds.
+ */
+#define PLL_LOCK_TIME		20
+
+/**
+ * struct davinci_pll_clk - Main PLL clock
+ * @hw: clk_hw for the pll
+ * @base: Base memory address
+ * @parent_rate: Saved parent rate used by some child clocks
+ */
+struct davinci_pll_clk {
+	struct clk_hw hw;
+	void __iomem *base;
+};
+
+#define to_davinci_pll_clk(_hw) container_of((_hw), struct davinci_pll_clk, hw)
+
+static unsigned long davinci_pll_clk_recalc(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+	unsigned long rate = parent_rate;
+	u32 prediv, mult, postdiv;
+
+	prediv = readl(pll->base + PREDIV) & PREDIV_RATIO_MASK;
+	mult = readl(pll->base + PLLM) & PLLM_MASK;
+	postdiv = readl(pll->base + POSTDIV) & POSTDIV_RATIO_MASK;
+
+	rate /= prediv + 1;
+	rate *= mult + 1;
+	rate /= postdiv + 1;
+
+	return rate;
+}
+
+/**
+ * davinci_pll_get_best_rate - Calculate PLL output closest to a given rate
+ * @rate: The target rate
+ * @parent_rate: The PLL input clock rate
+ * @mult: Pointer to hold the multiplier value (optional)
+ * @postdiv: Pointer to hold the postdiv value (optional)
+ *
+ * Returns: The closest rate less than or equal to @rate that the PLL can
+ * generate. @mult and @postdiv will contain the values required to generate
+ * that rate.
+ */
+static long davinci_pll_get_best_rate(u32 rate, u32 parent_rate, u32 *mult,
+				      u32 *postdiv)
+{
+	u32 r, m, d;
+	u32 best_rate = 0;
+	u32 best_mult = 0;
+	u32 best_postdiv = 0;
+
+	for (d = 1; d <= 4; d++) {
+		for (m = min(32U, rate * d / parent_rate); m > 0; m--) {
+			r = parent_rate * m / d;
+
+			if (r < best_rate)
+				break;
+
+			if (r > best_rate && r <= rate) {
+				best_rate = r;
+				best_mult = m;
+				best_postdiv = d;
+			}
+
+			if (best_rate == rate)
+				goto out;
+		}
+	}
+
+out:
+	if (mult)
+		*mult = best_mult;
+	if (postdiv)
+		*postdiv = best_postdiv;
+
+	return best_rate;
+}
+
+static long davinci_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long *parent_rate)
+{
+	return davinci_pll_get_best_rate(rate, *parent_rate, NULL, NULL);
+}
+
+/**
+ * __davinci_pll_set_rate - set the output rate of a given PLL.
+ *
+ * Note: Currently tested to work with OMAP-L138 only.
+ *
+ * @pll: pll whose rate needs to be changed.
+ * @prediv: The pre divider value. Passing 0 disables the pre-divider.
+ * @pllm: The multiplier value. Passing 0 leads to multiply-by-one.
+ * @postdiv: The post divider value. Passing 0 disables the post-divider.
+ */
+static void __davinci_pll_set_rate(struct davinci_pll_clk *pll, u32 prediv,
+				   u32 mult, u32 postdiv)
+{
+	u32 ctrl, locktime;
+
+	/*
+	 * PLL lock time required per OMAP-L138 datasheet is
+	 * (2000 * prediv)/sqrt(pllm) OSCIN cycles. We approximate sqrt(pllm)
+	 * as 4 and OSCIN cycle as 25 MHz.
+	 */
+	if (prediv) {
+		locktime = ((2000 * prediv) / 100);
+		prediv = (prediv - 1) | PREDIV_PREDEN;
+	} else {
+		locktime = PLL_LOCK_TIME;
+	}
+	if (postdiv)
+		postdiv = (postdiv - 1) | POSTDIV_POSTDEN;
+	if (mult)
+		mult = mult - 1;
+
+	ctrl = readl(pll->base + PLLCTL);
+
+	/* Switch the PLL to bypass mode */
+	ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
+	writel(ctrl, pll->base + PLLCTL);
+
+	udelay(PLL_BYPASS_TIME);
+
+	/* Reset and enable PLL */
+	ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
+	writel(ctrl, pll->base + PLLCTL);
+
+	writel(prediv, pll->base + PREDIV);
+	writel(mult, pll->base + PLLM);
+	writel(postdiv, pll->base + POSTDIV);
+
+	udelay(PLL_RESET_TIME);
+
+	/* Bring PLL out of reset */
+	ctrl |= PLLCTL_PLLRST;
+	writel(ctrl, pll->base + PLLCTL);
+
+	udelay(locktime);
+
+	/* Remove PLL from bypass mode */
+	ctrl |= PLLCTL_PLLEN;
+	writel(ctrl, pll->base + PLLCTL);
+}
+
+static int davinci_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+	u32 mult, postdiv;
+
+	davinci_pll_get_best_rate(rate, parent_rate, &mult, &postdiv);
+	__davinci_pll_set_rate(pll, 1, mult, postdiv);
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+
+#define DEBUG_REG(n)	\
+{			\
+	.name	= #n,	\
+	.offset	= n,	\
+}
+
+static const struct debugfs_reg32 davinci_pll_regs[] = {
+	DEBUG_REG(REVID),
+	DEBUG_REG(PLLCTL),
+	DEBUG_REG(OCSEL),
+	DEBUG_REG(PLLSECCTL),
+	DEBUG_REG(PLLM),
+	DEBUG_REG(PREDIV),
+	DEBUG_REG(PLLDIV1),
+	DEBUG_REG(PLLDIV2),
+	DEBUG_REG(PLLDIV3),
+	DEBUG_REG(OSCDIV),
+	DEBUG_REG(POSTDIV),
+	DEBUG_REG(BPDIV),
+	DEBUG_REG(PLLCMD),
+	DEBUG_REG(PLLSTAT),
+	DEBUG_REG(ALNCTL),
+	DEBUG_REG(DCHANGE),
+	DEBUG_REG(CKEN),
+	DEBUG_REG(CKSTAT),
+	DEBUG_REG(SYSTAT),
+	DEBUG_REG(PLLDIV4),
+	DEBUG_REG(PLLDIV5),
+	DEBUG_REG(PLLDIV6),
+	DEBUG_REG(PLLDIV7),
+	DEBUG_REG(PLLDIV8),
+	DEBUG_REG(PLLDIV9),
+};
+
+static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+	struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+	struct debugfs_regset32 *regset;
+	struct dentry *d;
+
+	regset = kzalloc(sizeof(regset), GFP_KERNEL);
+	if (!regset)
+		return -ENOMEM;
+
+	regset->regs = davinci_pll_regs;
+	regset->nregs = ARRAY_SIZE(davinci_pll_regs);
+	regset->base = pll->base;
+
+	d = debugfs_create_regset32("registers", 0400, dentry, regset);
+	if (IS_ERR(d)) {
+		kfree(regset);
+		return PTR_ERR(d);
+	}
+
+	return 0;
+}
+#else
+#define davinci_pll_debug_init NULL
+#endif
+
+static const struct clk_ops davinci_pll_clk_ops = {
+	.recalc_rate	= davinci_pll_clk_recalc,
+	.round_rate	= davinci_pll_round_rate,
+	.set_rate	= davinci_pll_set_rate,
+	.debug_init	= davinci_pll_debug_init,
+};
+
+/**
+ * davinci_pll_clk_register - Register a PLL clock
+ * @name: The clock name
+ * @parent_name: The parent clock name
+ * @base: The PLL's memory region
+ */
+struct clk *davinci_pll_clk_register(const char *name,
+				     const char *parent_name,
+				     void __iomem *base)
+{
+	struct clk_init_data init;
+	struct davinci_pll_clk *pll;
+	struct clk *clk;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &davinci_pll_clk_ops;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+	init.flags = 0;
+
+	pll->base = base;
+	pll->hw.init = &init;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+struct davinci_pll_aux_clk {
+	struct clk_hw hw;
+	struct davinci_pll_clk *pll;
+};
+
+/**
+ * davinci_pll_aux_clk_register - Register bypass clock (AUXCLK)
+ * @name: The clock name
+ * @parent_name: The parent clock name (usually "ref_clk" since this bypasses
+ *               the PLL)
+ * @base: The PLL memory region
+ */
+struct clk *davinci_pll_aux_clk_register(const char *name,
+					 const char *parent_name,
+					 void __iomem *base)
+{
+	return clk_register_gate(NULL, name, parent_name, 0, base + CKEN,
+				 CKEN_AUXEN_SHIFT, 0, NULL);
+}
+
+/**
+ * davinci_pll_bpdiv_clk_register - Register bypass divider clock (SYSCLKBP)
+ * @name: The clock name
+ * @parent_name: The parent clock name (usually "ref_clk" since this bypasses
+ *               the PLL)
+ * @base: The PLL memory region
+ */
+struct clk *davinci_pll_bpdiv_clk_register(const char *name,
+					   const char *parent_name,
+					   void __iomem *base)
+{
+	return clk_register_divider(NULL, name, parent_name, 0, base + BPDIV,
+				    BPDIV_RATIO_SHIFT, BPDIV_RATIO_WIDTH,
+				    CLK_DIVIDER_READ_ONLY, NULL);
+}
+
+/**
+ * davinci_pll_obs_clk_register - Register oscillator divider clock (OBSCLK)
+ * @name: The clock name
+ * @parent_names: The parent clock names
+ * @num_parents: The number of paren clocks
+ * @base: The PLL memory region
+ * @table: A table of values cooresponding to the parent clocks (see OCSEL
+ *         register in SRM for values)
+ */
+struct clk *davinci_pll_obs_clk_register(const char *name,
+					 const char * const *parent_names,
+					 u8 num_parents,
+					 void __iomem *base,
+					 u32 *table)
+{
+	struct clk_mux *mux;
+	struct clk_gate *gate;
+	struct clk_divider *divider;
+	struct clk *clk;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	mux->reg = base + OCSEL;
+	mux->table = table;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate) {
+		kfree(mux);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	gate->reg = base + CKEN;
+	gate->bit_idx = CKEN_OBSCLK_SHIFT;
+
+	divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+	if (!divider) {
+		kfree(gate);
+		kfree(mux);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	divider->reg = base + OSCDIV;
+	divider->width = OSCDIV_RATIO_WIDTH;
+
+	clk = clk_register_composite(NULL, name, parent_names, num_parents,
+				     &mux->hw, &clk_mux_ops,
+				     &divider->hw, &clk_divider_ops,
+				     &gate->hw, &clk_gate_ops, 0);
+	if (IS_ERR(clk)) {
+		kfree(divider);
+		kfree(gate);
+		kfree(mux);
+	}
+
+	return clk;
+}
+
+struct clk *
+davinci_pll_divclk_register(const struct davinci_pll_divclk_info *info,
+			    void __iomem *base)
+{
+	const struct clk_ops *divider_ops = &clk_divider_ops;
+	struct clk_gate *gate;
+	struct clk_divider *divider;
+	struct clk *clk;
+	u32 reg;
+	u32 flags = 0;
+
+	/* PLLDIVn registers are not entirely consecutive */
+	if (info->id < 4)
+		reg = PLLDIV1 + 4 * (info->id - 1);
+	else
+		reg = PLLDIV4 + 4 * (info->id - 4);
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->reg = base + reg;
+	gate->bit_idx = PLLDIV_ENABLE_SHIFT;
+
+	divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+	if (!divider) {
+		kfree(gate);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	divider->reg = base + reg;
+	divider->width = PLLDIV_RATIO_WIDTH;
+	divider->flags = 0;
+
+	if (info->flags & DIVCLK_FIXED_DIV) {
+		flags |= CLK_DIVIDER_READ_ONLY;
+		divider_ops = &clk_divider_ro_ops;
+	}
+
+	/* Only the ARM clock can change the parent PLL rate */
+	if (info->flags & DIVCLK_ARM_RATE)
+		flags |= CLK_SET_RATE_PARENT;
+
+	if (info->flags & DIVCLK_ALWAYS_ENABLED)
+		flags |= CLK_IS_CRITICAL;
+
+	clk = clk_register_composite(NULL, info->name, &info->parent_name, 1,
+				     NULL, NULL, &divider->hw, divider_ops,
+				     &gate->hw, &clk_gate_ops, flags);
+	if (IS_ERR(clk)) {
+		kfree(divider);
+		kfree(gate);
+	}
+
+	return clk;
+}
+
+#ifdef CONFIG_OF
+#define MAX_NAME_SIZE 20
+
+void of_davinci_pll_init(struct device_node *node, const char *name,
+			 const struct davinci_pll_divclk_info *info,
+			 u8 max_divclk_id)
+{
+	struct device_node *child;
+	const char *parent_name;
+	void __iomem *base;
+	struct clk *clk;
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("%s: ioremap failed\n", __func__);
+		return;
+	}
+
+	parent_name = of_clk_get_parent_name(node, 0);
+
+	clk = davinci_pll_clk_register(name, parent_name, base);
+	if (IS_ERR(clk)) {
+		pr_err("%s: failed to register %s (%ld)\n", __func__, name,
+		       PTR_ERR(clk));
+		return;
+	}
+
+	child = of_get_child_by_name(node, "sysclk");
+	if (child && of_device_is_available(child)) {
+		struct clk_onecell_data *clk_data;
+
+		clk_data = clk_alloc_onecell_data(max_divclk_id + 1);
+		if (!clk_data) {
+			pr_err("%s: out of memory\n", __func__);
+			return;
+		}
+
+		for (; info->name; info++) {
+			clk = davinci_pll_divclk_register(info, base);
+			if (IS_ERR(clk))
+				pr_warn("%s: failed to register %s (%ld)\n",
+					__func__, info->name, PTR_ERR(clk));
+			else
+				clk_data->clks[info->id] = clk;
+		}
+		of_clk_add_provider(child, of_clk_src_onecell_get, clk_data);
+	}
+	of_node_put(child);
+
+	child = of_get_child_by_name(node, "auxclk");
+	if (child && of_device_is_available(child)) {
+		char child_name[MAX_NAME_SIZE];
+
+		snprintf(child_name, MAX_NAME_SIZE, "%s_aux_clk", name);
+
+		clk = davinci_pll_aux_clk_register(child_name, parent_name, base);
+		if (IS_ERR(clk))
+			pr_warn("%s: failed to register %s (%ld)\n", __func__,
+				child_name, PTR_ERR(clk));
+		else
+			of_clk_add_provider(child, of_clk_src_simple_get, clk);
+	}
+	of_node_put(child);
+}
+#endif
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
new file mode 100644
index 0000000..259678b
--- /dev/null
+++ b/drivers/clk/davinci/pll.h
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for TI Davinci PSC controllers
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#ifndef __CLK_DAVINCI_PLL_H___
+#define __CLK_DAVINCI_PLL_H___
+
+#include <linux/bitops.h>
+#include <linux/types.h>
+
+#define DIVCLK_ARM_RATE		BIT(0) /* Controls ARM rate */
+#define DIVCLK_FIXED_DIV	BIT(1) /* Fixed divider */
+#define DIVCLK_ALWAYS_ENABLED	BIT(2) /* Or bad things happen */
+
+struct davinci_pll_divclk_info {
+	const char *name;
+	const char *parent_name;
+	u32 id;
+	u32 flags;
+};
+
+#define DIVCLK(i, n, p, f)	\
+{				\
+	.name		= #n,	\
+	.parent_name	= #p,	\
+	.id		= (i),	\
+	.flags		= (f),	\
+}
+
+struct clk;
+
+struct clk *davinci_pll_clk_register(const char *name,
+				     const char *parent_name,
+				     void __iomem *base);
+struct clk *davinci_pll_aux_clk_register(const char *name,
+					 const char *parent_name,
+					 void __iomem *base);
+struct clk *davinci_pll_bpdiv_clk_register(const char *name,
+					   const char *parent_name,
+					   void __iomem *base);
+struct clk *davinci_pll_obs_clk_register(const char *name,
+					 const char * const *parent_names,
+					 u8 num_parents,
+					 void __iomem *base,
+					 u32 *table);
+struct clk *
+davinci_pll_divclk_register(const struct davinci_pll_divclk_info *info,
+			    void __iomem *base);
+
+#ifdef CONFIG_OF
+struct device_node;
+
+void of_davinci_pll_init(struct device_node *node, const char *name,
+			 const struct davinci_pll_divclk_info *info,
+			 u8 max_divclk_id);
+#endif
+
+#endif /* __CLK_DAVINCI_PLL_H___ */
-- 
2.7.4

  parent reply	other threads:[~2018-01-08  2:17 UTC|newest]

Thread overview: 121+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-08  2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework​ David Lechner
2018-01-08  2:17 ` [PATCH v5 01/44] dt-bindings: clock: Add new bindings for TI Davinci PLL clocks David Lechner
     [not found]   ` <1515377863-20358-2-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-08 14:00     ` Sekhar Nori
2018-01-08 16:29       ` David Lechner
2018-01-09 12:35         ` Sekhar Nori
     [not found]           ` <0f90b5f7-f21e-5f81-1154-9a815bbb786d-l0cyMroinI0@public.gmane.org>
2018-01-10  3:01             ` David Lechner
2018-01-10 18:52               ` Sekhar Nori
2018-01-10 22:24                 ` Adam Ford
     [not found]                   ` <CAHCN7x+ZYezmEU_0mF=6_gF14DZxKnuDp1Cx=aC2=eN_QLNdJQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-01-11  2:50                     ` David Lechner
2018-01-11 12:45                       ` Adam Ford
2018-01-11 15:47                         ` Sekhar Nori
     [not found]                           ` <14320e05-c6f7-fa2d-35cd-c01414c59f2f-l0cyMroinI0@public.gmane.org>
2018-01-11 16:14                             ` Adam Ford
2018-01-11 17:22                         ` David Lechner
2018-01-11 18:09                           ` Adam Ford
2018-01-11 18:29                             ` David Lechner
2018-01-11 18:50                               ` Adam Ford
     [not found]                                 ` <CAHCN7x+G5pxOeD7TahqiQUePEu1Z4Hyinkjq_bcSM+Hz36xoSg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-01-11 20:04                                   ` David Lechner
2018-01-11 20:58                                     ` Adam Ford
     [not found]                                       ` <CAHCN7x+EtQs6NHAYbVga7vU1U+qQLqOxdf+1MW6HewaT+ZF_Xg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-01-11 21:04                                         ` David Lechner
     [not found]                                           ` <5832fd62-16aa-e167-7e52-2ce493e33cdc-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-11 21:34                                             ` Adam Ford
2018-01-11 21:46                                               ` David Lechner
     [not found]                                                 ` <c1e27013-cbad-3b09-0e0d-f68d75162c1f-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-12  6:03                                                   ` Sekhar Nori
2018-01-16 11:22                                               ` Sekhar Nori
2018-01-16 12:21                                                 ` Adam Ford
2018-01-16 16:41                                                   ` David Lechner
2018-01-11 23:20                             ` David Lechner
2018-01-11  2:54                 ` David Lechner
2018-01-08  2:17 ` David Lechner [this message]
2018-01-12  9:21   ` [PATCH v5 02/44] clk: davinci: New driver for davinci " Sekhar Nori
2018-01-12 15:25     ` David Lechner
     [not found]       ` <01fbde0e-36a0-2b19-e385-e63bc4a3ae4a-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-12 15:30         ` Adam Ford
     [not found]           ` <CAHCN7xK44_zv27xe5yxL8Efey=VC-nypK6hY6VWqsoLqnKe04g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-01-12 15:48             ` David Lechner
2018-01-12 16:18       ` Sekhar Nori
     [not found]         ` <eb2b1a63-9c7c-aeca-170f-d38642442438-l0cyMroinI0@public.gmane.org>
2018-01-13  1:11           ` David Lechner
2018-01-16  6:48             ` Sekhar Nori
2018-01-13  2:13     ` David Lechner
2018-01-16  6:32       ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 03/44] clk: davinci: Add platform information for TI DA830 PLL David Lechner
     [not found]   ` <1515377863-20358-4-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-12  9:41     ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 04/44] clk: davinci: Add platform information for TI DA850 PLL David Lechner
2018-01-16  8:37   ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 05/44] clk: davinci: Add platform information for TI DM355 PLL David Lechner
2018-01-16  8:38   ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 06/44] clk: davinci: Add platform information for TI DM365 PLL David Lechner
     [not found]   ` <1515377863-20358-7-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-16  8:48     ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 07/44] clk: davinci: Add platform information for TI DM644x PLL David Lechner
     [not found]   ` <1515377863-20358-8-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-16  8:56     ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 08/44] clk: davinci: Add platform information for TI DM646x PLL David Lechner
2018-01-16  9:01   ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 09/44] dt-bindings: clock: New bindings for TI Davinci PSC David Lechner
     [not found]   ` <1515377863-20358-10-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-11 21:22     ` Rob Herring
2018-01-08  2:17 ` [PATCH v5 10/44] clk: davinci: New driver for davinci PSC clocks David Lechner
2018-01-16 11:03   ` Sekhar Nori
2018-01-16 16:51     ` David Lechner
     [not found]       ` <83f3d207-9645-cbdf-d6cf-b6e6a8458abe-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-17 12:25         ` Sekhar Nori
2018-01-17 17:28           ` David Lechner
2018-01-08  2:17 ` [PATCH v5 11/44] clk: davinci: Add platform information for TI DA830 PSC David Lechner
     [not found]   ` <1515377863-20358-12-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-16 13:38     ` Sekhar Nori
     [not found]       ` <91fe16dc-907e-6dbb-c8db-c27561132093-l0cyMroinI0@public.gmane.org>
2018-01-16 17:16         ` David Lechner
     [not found]           ` <4dd36ca7-e41d-58d8-ec8c-787978307943-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-17 12:18             ` Sekhar Nori
     [not found]               ` <86581de6-a982-7a7b-9a83-22c869417211-l0cyMroinI0@public.gmane.org>
2018-01-17 17:32                 ` David Lechner
2018-01-18  7:53                   ` Sekhar Nori
     [not found] ` <1515377863-20358-1-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-08  2:17   ` [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC David Lechner
     [not found]     ` <1515377863-20358-13-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-16 14:00       ` Sekhar Nori
2018-01-16 17:21         ` David Lechner
2018-01-17 11:57           ` Sekhar Nori
2018-01-17 17:33             ` David Lechner
2018-01-17 19:08             ` David Lechner
2018-01-18  6:37               ` Sekhar Nori
2018-02-09 16:22     ` Bartosz Golaszewski
2018-02-09 16:48       ` Michael Turquette
2018-02-12  3:03         ` David Lechner
2018-04-05 13:09         ` Sekhar Nori
2018-04-05 13:44           ` Bartosz Golaszewski
2018-04-05 14:36             ` Sekhar Nori
2018-04-05 15:37               ` David Lechner
2018-04-05 15:51               ` Bartosz Golaszewski
2018-04-06  9:37                 ` Sekhar Nori
2018-04-06 16:46                   ` Stephen Boyd
2018-04-23 14:59                     ` David Lechner
2018-04-24  8:28                       ` Sekhar Nori
2018-04-24 16:11                         ` David Lechner
2018-04-25  6:07                           ` Sekhar Nori
2018-04-25 10:09                             ` Bartosz Golaszewski
2018-04-25 10:26                               ` Bartosz Golaszewski
2018-01-08  2:17   ` [PATCH v5 13/44] clk: davinci: Add platform information for TI DM355 PSC David Lechner
     [not found]     ` <1515377863-20358-14-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-16 14:15       ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 14/44] clk: davinci: Add platform information for TI DM365 PSC David Lechner
2018-01-16 14:16   ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 15/44] clk: davinci: Add platform information for TI DM644x PSC David Lechner
2018-01-17 13:57   ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 16/44] clk: davinci: Add platform information for TI DM646x PSC David Lechner
2018-01-17 14:59   ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 17/44] dt-bindings: clock: Add bindings for DA8XX CFGCHIP gate clocks David Lechner
     [not found]   ` <1515377863-20358-18-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-11 21:45     ` Rob Herring
2018-01-11 21:51       ` David Lechner
2018-01-08  2:17 ` [PATCH v5 18/44] dt-bindings: clock: Add binding for TI DA8XX CFGCHIP mux clocks David Lechner
2018-01-08  2:17 ` [PATCH v5 19/44] clk: davinci: New driver for TI DA8XX CFGCHIP clocks David Lechner
2018-01-17 15:31   ` Sekhar Nori
2018-01-17 17:35     ` David Lechner
2018-01-08  2:17 ` [PATCH v5 20/44] dt-bindings: clock: Add bindings for TI DA8XX USB PHY clocks David Lechner
2018-01-18 12:10   ` Sekhar Nori
     [not found]     ` <33f0feba-adee-e365-54d5-16fe3d49302d-l0cyMroinI0@public.gmane.org>
2018-01-18 19:00       ` David Lechner
2018-01-19  6:17         ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 21/44] clk: davinci: New driver " David Lechner
2018-01-18 13:05   ` Sekhar Nori
     [not found]     ` <493e4809-6b77-7772-70c7-ad0fa04e9033-l0cyMroinI0@public.gmane.org>
2018-01-18 18:49       ` David Lechner
2018-01-19  5:04         ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 22/44] ARM: davinci: move davinci_clk_init() to init_time David Lechner
2018-01-08  2:17 ` [PATCH v5 23/44] ARM: da830: add new clock init using common clock framework David Lechner
2018-01-08  2:17 ` [PATCH v5 24/44] ARM: da850: " David Lechner
     [not found]   ` <1515377863-20358-25-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-18 15:24     ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 25/44] ARM: dm355: " David Lechner
2018-01-08  2:17 ` [PATCH v5 26/44] ARM: dm365: " David Lechner
2018-01-08  2:17 ` [PATCH v5 27/44] ARM: dm644x: " David Lechner
2018-01-08  2:17 ` [PATCH v5 28/44] ARM: dm646x: " David Lechner
2018-01-08  2:17 ` [PATCH v5 29/44] ARM: da8xx: add new USB PHY " David Lechner
2018-01-18 15:14   ` Sekhar Nori
     [not found]     ` <83dfab9a-be30-6313-d756-50fa018e757e-l0cyMroinI0@public.gmane.org>
2018-01-18 18:43       ` David Lechner
2018-01-19  5:08         ` Sekhar Nori
2018-01-08  2:17 ` [PATCH v5 35/44] ARM: da850: Remove legacy clock init David Lechner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1515377863-20358-3-git-send-email-david@lechnology.com \
    --to=david@lechnology.com \
    --cc=aford173@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=khilman@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mturquette@baylibre.com \
    --cc=nsekhar@ti.com \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@codeaurora.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).