* [PATCH v5 01/44] dt-bindings: clock: Add new bindings for TI Davinci PLL clocks
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
@ 2018-01-08 2:17 ` David Lechner
[not found] ` <1515377863-20358-2-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-08 2:17 ` [PATCH v5 02/44] clk: davinci: New driver for davinci " David Lechner
` (27 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, David Lechner, Kevin Hilman, Stephen Boyd,
Michael Turquette, Sekhar Nori, linux-kernel, Rob Herring,
Adam Ford
This adds a new binding for the PLL IP blocks in the mach-davinci family
of processors. Currently, only the SYSCLKn and AUXCLK outputs are needed,
but in the future additional child nodes could be added for OBSCLK and
BPDIV.
Note: Although these PLL controllers are very similar to the TI Keystone
SoCs, we are not re-using those bindings. The Keystone bindings use a
legacy one-node-per-clock binding. Furthermore, the mach-davinici SoCs
have a slightly different PLL register layout and a number of quirks that
can't be handled by the existing bindings, so the keystone bindings could
not be used as-is anyway.
Signed-off-by: David Lechner <david@lechnology.com>
---
.../devicetree/bindings/clock/ti/davinci/pll.txt | 47 ++++++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
diff --git a/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
new file mode 100644
index 0000000..99bf5da
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
@@ -0,0 +1,47 @@
+Binding for TI DaVinci PLL Controllers
+
+The PLL provides clocks to most of the components on the SoC. In addition
+to the PLL itself, this controller also contains bypasses, gates, dividers,
+an multiplexers for various clock signals.
+
+Required properties:
+- compatible: shall be one of:
+ - "ti,da850-pll0" for PLL0 on DA850/OMAP-L138/AM18XX
+ - "ti,da850-pll1" for PLL1 on DA850/OMAP-L138/AM18XX
+- reg: physical base address and size of the controller's register area.
+- clocks: phandle to the PLL input clock source
+
+Optional child nodes:
+
+sysclk
+ Describes the PLLDIVn divider clocks that provide the SYSCLKn clock
+ domains. The node name must be "sysclk". Consumers of this node should
+ use "n" in "SYSCLKn" as the parameter for the clock cell.
+
+ Required properties:
+ - #clock-cells: must be 1
+
+auxclk
+ Describes the AUXCLK output of the PLL. The node name must be "auxclk".
+
+ Required properties:
+ - #clock-cells: must be 0
+
+Examples:
+
+ pll0: clock-controller@11000 {
+ compatible = "ti,da850-pll0";
+ reg = <0x11000 0x1000>;
+ clocks = <&ref_clk>;
+
+ pll0_sysclk: sysclk {
+ #clock-cells = <1>;
+ };
+
+ pll0_aux_clk: auxclk {
+ #clock-cells = <0>;
+ };
+ };
+
+Also see:
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 02/44] clk: davinci: New driver for davinci PLL clocks
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
@ 2018-01-08 2:17 ` David Lechner
2018-01-12 9:21 ` Sekhar Nori
2018-01-08 2:17 ` [PATCH v5 03/44] clk: davinci: Add platform information for TI DA830 PLL David Lechner
` (26 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, David Lechner, Kevin Hilman, Stephen Boyd,
Michael Turquette, Sekhar Nori, linux-kernel, Rob Herring,
Adam Ford
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,
+ ÷r->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, ÷r->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
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 02/44] clk: davinci: New driver for davinci PLL clocks
2018-01-08 2:17 ` [PATCH v5 02/44] clk: davinci: New driver for davinci " David Lechner
@ 2018-01-12 9:21 ` Sekhar Nori
2018-01-12 15:25 ` David Lechner
2018-01-13 2:13 ` David Lechner
0 siblings, 2 replies; 121+ messages in thread
From: Sekhar Nori @ 2018-01-12 9:21 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, Kevin Hilman, Michael Turquette, Stephen Boyd,
linux-kernel, Rob Herring, Adam Ford
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> 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>
Please also add:
R: Sekhar Nori <nsekhar@ti.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
May be use the mode modern GENMASK()?
> +#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 */
An empty line before the comment make it easier to read.
> +#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
You don't have parent_rate in the structure below.
> + */
> +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;
Shouldn't we check if the pre and post dividers are enabled before using
them?
> +
> + 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;
> +}
PLL output on DA850 must never be below 300MHz or above 600MHz (see
datasheet table "Allowed PLL Operating Conditions"). Does this take care
of that? Thats one of the main reasons I recall I went with some
specific values of prediv, pllm and post div in
arch/arm/mach-davinci/da850.c
> +
> +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;
> + }
Empty line here will be nice.
> + 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);
> +}
[...]
> +/**
> + * 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;
can you write OD1EN of OSCDIV here? I guess the reset default is 1 so
you didnt need to do that. But not doing exposes us to settings that
bootloader left us in.
> +
> + clk = clk_register_composite(NULL, name, parent_names, num_parents,
> + &mux->hw, &clk_mux_ops,
> + ÷r->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;
setting the sysclk divider requires GOSTAT handling apart from setting
the divider value. So I think .set_rate ops above wont work. Other ops
can be used, I guess. So we need a private structure here.
Can you port over davinci_set_sysclk_rate() too? I understand you cannot
test it due to lack of cpufreq support in DT, but I can help testing there.
Or leave .set_rate NULL and it can be added later.
> + 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, ÷r->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));
You can probably avoid these line breaks by adding on top of the file
#define pr_fmt(fmt) "%s: " fmt "\n", __func__
> + 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);
> + }
davinci_pll_obs_clk_register() should also be handled here?
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 02/44] clk: davinci: New driver for davinci PLL clocks
2018-01-12 9:21 ` 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 16:18 ` Sekhar Nori
2018-01-13 2:13 ` David Lechner
1 sibling, 2 replies; 121+ messages in thread
From: David Lechner @ 2018-01-12 15:25 UTC (permalink / raw)
To: Sekhar Nori, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On 01/12/2018 03:21 AM, Sekhar Nori wrote:
> On Monday 08 January 2018 07:47 AM, David Lechner wrote:
>> 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>
>> ---
>> +
>> +#define PLLM_MASK 0x1f
>> +#define PREDIV_RATIO_MASK 0x1f
>
> May be use the mode modern GENMASK()?
I haven't seen that one before. Thanks.
...
>> +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;
>
> Shouldn't we check if the pre and post dividers are enabled before using
> them?
Indeed.
>
>> +
>> + rate /= prediv + 1;
>> + rate *= mult + 1;
>> + rate /= postdiv + 1;
>> +
>> + return rate;
>> +}
>> +
...
>
> PLL output on DA850 must never be below 300MHz or above 600MHz (see
> datasheet table "Allowed PLL Operating Conditions"). Does this take care
> of that? Thats one of the main reasons I recall I went with some
> specific values of prediv, pllm and post div in
> arch/arm/mach-davinci/da850.c
Apparently, I missed this requirement. It looks like I am going to have to
rework things so that there is some coordination between the PLL and the
PLLDIV clocks in order to get the < 300MHz operating points.
...
>> +
>> + divider->reg = base + OSCDIV;
>> + divider->width = OSCDIV_RATIO_WIDTH;
>
> can you write OD1EN of OSCDIV here? I guess the reset default is 1 so
> you didnt need to do that. But not doing exposes us to settings that
> bootloader left us in.
>
It looks like I am going to have to make a custom implementation for parts
of this clock anyway, so I will probably just make new enable/disable
callbacks that set both OSCDIV_OD1EN and CKEN_OBSCLK.
>> +
>> + clk = clk_register_composite(NULL, name, parent_names, num_parents,
>> + &mux->hw, &clk_mux_ops,
>> + ÷r->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;
>
> setting the sysclk divider requires GOSTAT handling apart from setting
> the divider value. So I think .set_rate ops above wont work. Other ops
> can be used, I guess. So we need a private structure here.
>
> Can you port over davinci_set_sysclk_rate() too? I understand you cannot
> test it due to lack of cpufreq support in DT, but I can help testing there.
>
> Or leave .set_rate NULL and it can be added later.
Yes, I noticed that I missed this after I submitted this series. And I
will have to rework things to coordinate with the PLL as mentioned above.
FYI, I do have cpufreq-dt working, although the LEGO EV3 has a fixed 1.2V
regulator, so I am limited in what I can test. Basically, I can only switch
between 300MHz and 375MHz according to the datasheets. The chip is technically
the 456MHz version. What would happen if I ran it faster or slower with the
wrong voltage?
...
>> +
>> + 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);
>> + }
>
> davinci_pll_obs_clk_register() should also be handled here?
I omitted it because no one is using it (same reason I left it out of the
device tree bindings). We can certainly add it, though.
^ permalink raw reply [flat|nested] 121+ messages in thread
[parent not found: <01fbde0e-36a0-2b19-e385-e63bc4a3ae4a-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>]
* Re: [PATCH v5 02/44] clk: davinci: New driver for davinci PLL clocks
[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>
0 siblings, 1 reply; 121+ messages in thread
From: Adam Ford @ 2018-01-12 15:30 UTC (permalink / raw)
To: David Lechner
Cc: Sekhar Nori, linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, linux-kernel-u79uwXL29TY76Z2rM5mHXA
On Fri, Jan 12, 2018 at 9:25 AM, David Lechner <david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org> wrote:
> On 01/12/2018 03:21 AM, Sekhar Nori wrote:
>>
>> On Monday 08 January 2018 07:47 AM, David Lechner wrote:
>>>
>>> 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-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
>>> ---
>
>
>>> +
>>> +#define PLLM_MASK 0x1f
>>> +#define PREDIV_RATIO_MASK 0x1f
>>
>>
>> May be use the mode modern GENMASK()?
>
>
> I haven't seen that one before. Thanks.
>
> ...
>
>>> +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;
>>
>>
>> Shouldn't we check if the pre and post dividers are enabled before using
>> them?
>
>
> Indeed.
>
>>
>>> +
>>> + rate /= prediv + 1;
>>> + rate *= mult + 1;
>>> + rate /= postdiv + 1;
>>> +
>>> + return rate;
>>> +}
>>> +
>
>
> ...
>
>>
>> PLL output on DA850 must never be below 300MHz or above 600MHz (see
>> datasheet table "Allowed PLL Operating Conditions"). Does this take care
>> of that? Thats one of the main reasons I recall I went with some
>> specific values of prediv, pllm and post div in
>> arch/arm/mach-davinci/da850.c
>
>
> Apparently, I missed this requirement. It looks like I am going to have to
> rework things so that there is some coordination between the PLL and the
> PLLDIV clocks in order to get the < 300MHz operating points.
>
> ...
>
>>> +
>>> + divider->reg = base + OSCDIV;
>>> + divider->width = OSCDIV_RATIO_WIDTH;
>>
>>
>> can you write OD1EN of OSCDIV here? I guess the reset default is 1 so
>> you didnt need to do that. But not doing exposes us to settings that
>> bootloader left us in.
>>
>
> It looks like I am going to have to make a custom implementation for parts
> of this clock anyway, so I will probably just make new enable/disable
> callbacks that set both OSCDIV_OD1EN and CKEN_OBSCLK.
>
>
>>> +
>>> + clk = clk_register_composite(NULL, name, parent_names,
>>> num_parents,
>>> + &mux->hw, &clk_mux_ops,
>>> + ÷r->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;
>>
>>
>> setting the sysclk divider requires GOSTAT handling apart from setting
>> the divider value. So I think .set_rate ops above wont work. Other ops
>> can be used, I guess. So we need a private structure here.
>>
>> Can you port over davinci_set_sysclk_rate() too? I understand you cannot
>> test it due to lack of cpufreq support in DT, but I can help testing
>> there.
>>
>> Or leave .set_rate NULL and it can be added later.
>
>
> Yes, I noticed that I missed this after I submitted this series. And I
> will have to rework things to coordinate with the PLL as mentioned above.
>
> FYI, I do have cpufreq-dt working, although the LEGO EV3 has a fixed 1.2V
> regulator, so I am limited in what I can test. Basically, I can only switch
I can test the cpufreq-dt. Are there additional patches or are they
part of the same git repo I have been testing?
The DA850 I have may not run all the way to highest speed, but I'll
see what I can find. I think I had a few at one point, but I don't
think it was part of Logic PD's standard product lineup.
adam
> between 300MHz and 375MHz according to the datasheets. The chip is
> technically
> the 456MHz version. What would happen if I ran it faster or slower with the
> wrong voltage?
>
> ...
>
>>> +
>>> + 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);
>>> + }
>>
>>
>> davinci_pll_obs_clk_register() should also be handled here?
>
>
> I omitted it because no one is using it (same reason I left it out of the
> device tree bindings). We can certainly add it, though.
>
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 02/44] clk: davinci: New driver for davinci PLL clocks
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 16:18 ` Sekhar Nori
[not found] ` <eb2b1a63-9c7c-aeca-170f-d38642442438-l0cyMroinI0@public.gmane.org>
1 sibling, 1 reply; 121+ messages in thread
From: Sekhar Nori @ 2018-01-12 16:18 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, Kevin Hilman, Michael Turquette, Stephen Boyd,
linux-kernel, Rob Herring, Adam Ford
On Friday 12 January 2018 08:55 PM, David Lechner wrote:
>>
>> PLL output on DA850 must never be below 300MHz or above 600MHz (see
>> datasheet table "Allowed PLL Operating Conditions"). Does this take care
>> of that? Thats one of the main reasons I recall I went with some
>> specific values of prediv, pllm and post div in
>> arch/arm/mach-davinci/da850.c
>
> Apparently, I missed this requirement. It looks like I am going to have to
> rework things so that there is some coordination between the PLL and the
> PLLDIV clocks in order to get the < 300MHz operating points.
Just to make sure we are on the same page. The datasheet
constraint is 600 >= PLLOUT >= 300. PLLOUT is output of POSTDIV.
The operating points are defined in terms of ARM frequency (and
voltage). The OPPs defined in kernel today are here:
https://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci.git/tree/arch/arm/mach-davinci/da850.c#n1092
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 02/44] clk: davinci: New driver for davinci PLL clocks
2018-01-12 9:21 ` Sekhar Nori
2018-01-12 15:25 ` David Lechner
@ 2018-01-13 2:13 ` David Lechner
2018-01-16 6:32 ` Sekhar Nori
1 sibling, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-13 2:13 UTC (permalink / raw)
To: Sekhar Nori, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On 01/12/2018 03:21 AM, Sekhar Nori wrote:
> On Monday 08 January 2018 07:47 AM, David Lechner wrote:
>> +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;
>
> Shouldn't we check if the pre and post dividers are enabled before using
> them?
I dug into this and the answer is no. The enable bit acts like a gate, not
a bypass, so it does not affect the rate calculation.
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 02/44] clk: davinci: New driver for davinci PLL clocks
2018-01-13 2:13 ` David Lechner
@ 2018-01-16 6:32 ` Sekhar Nori
0 siblings, 0 replies; 121+ messages in thread
From: Sekhar Nori @ 2018-01-16 6:32 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On Saturday 13 January 2018 07:43 AM, David Lechner wrote:
> On 01/12/2018 03:21 AM, Sekhar Nori wrote:
>> On Monday 08 January 2018 07:47 AM, David Lechner wrote:
>>> +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;
>>
>> Shouldn't we check if the pre and post dividers are enabled before using
>> them?
>
> I dug into this and the answer is no. The enable bit acts like a gate, not
> a bypass, so it does not affect the rate calculation.
Alright, thanks for checking this.
Regards,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 03/44] clk: davinci: Add platform information for TI DA830 PLL
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
2018-01-08 2:17 ` [PATCH v5 02/44] clk: davinci: New driver for davinci " David Lechner
@ 2018-01-08 2:17 ` David Lechner
[not found] ` <1515377863-20358-4-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-08 2:17 ` [PATCH v5 04/44] clk: davinci: Add platform information for TI DA850 PLL David Lechner
` (25 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, David Lechner, Kevin Hilman, Stephen Boyd,
Michael Turquette, Sekhar Nori, linux-kernel, Rob Herring,
Adam Ford
This adds platform-specific declarations for the PLL clocks on TI DA830/
OMAP-L137/AM17XX SoCs.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-da830.c | 38 ++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 14 ++++++++++++++
3 files changed, 53 insertions(+)
create mode 100644 drivers/clk/davinci/pll-da830.c
create mode 100644 include/linux/clk/davinci.h
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index d9673bd..9061e19 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -2,4 +2,5 @@
ifeq ($(CONFIG_COMMON_CLK), y)
obj-y += pll.o
+obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
endif
diff --git a/drivers/clk/davinci/pll-da830.c b/drivers/clk/davinci/pll-da830.c
new file mode 100644
index 0000000..369db59
--- /dev/null
+++ b/drivers/clk/davinci/pll-da830.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DA830/OMAP-L137/AM17XX
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+/*
+ * NB: Technically, the clocks flagged as DIVCLK_FIXED_DIV are "fixed ratio",
+ * meaning that we could change the divider as long as we keep the correct
+ * ratio between all of the clocks, but we don't support that because there is
+ * currently not a need for it.
+ */
+
+static const struct davinci_pll_divclk_info da830_pll_divclk_info[] __initconst = {
+ DIVCLK(2, pll0_sysclk2, pll0, DIVCLK_FIXED_DIV),
+ DIVCLK(3, pll0_sysclk3, pll0, 0),
+ DIVCLK(4, pll0_sysclk4, pll0, DIVCLK_FIXED_DIV),
+ DIVCLK(5, pll0_sysclk5, pll0, 0),
+ DIVCLK(6, pll0_sysclk6, pll0, DIVCLK_FIXED_DIV),
+ DIVCLK(7, pll0_sysclk7, pll0, 0),
+ { }
+};
+
+void __init da830_pll_clk_init(void __iomem *pll)
+{
+ const struct davinci_pll_divclk_info *info;
+
+ davinci_pll_clk_register("pll0", "ref_clk", pll);
+ davinci_pll_aux_clk_register("pll0_aux_clk", "ref_clk", pll);
+ for (info = da830_pll_divclk_info; info->name; info++)
+ davinci_pll_divclk_register(info, pll);
+}
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
new file mode 100644
index 0000000..4f4d60d
--- /dev/null
+++ b/include/linux/clk/davinci.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI Davinci clocks
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+#ifndef __LINUX_CLK_DAVINCI_H__
+#define __LINUX_CLK_DAVINCI_H__
+
+#include <linux/types.h>
+
+void da830_pll_clk_init(void __iomem *pll);
+
+#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 04/44] clk: davinci: Add platform information for TI DA850 PLL
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (2 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 03/44] clk: davinci: Add platform information for TI DA830 PLL David Lechner
@ 2018-01-08 2:17 ` 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
` (24 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, David Lechner, Kevin Hilman, Stephen Boyd,
Michael Turquette, Sekhar Nori, linux-kernel, Rob Herring,
Adam Ford
This adds platform-specific declarations for the PLL clocks on TI DA850/
OMAP-L138/AM18XX SoCs.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-da850.c | 67 +++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 69 insertions(+)
create mode 100644 drivers/clk/davinci/pll-da850.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 9061e19..13049d4 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -3,4 +3,5 @@
ifeq ($(CONFIG_COMMON_CLK), y)
obj-y += pll.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
+obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
endif
diff --git a/drivers/clk/davinci/pll-da850.c b/drivers/clk/davinci/pll-da850.c
new file mode 100644
index 0000000..2f00f3d
--- /dev/null
+++ b/drivers/clk/davinci/pll-da850.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DA850/OMAP-L138/AM18XX
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+/*
+ * NB: Technically, the clocks flagged as DIVCLK_FIXED_DIV are "fixed ratio",
+ * meaning that we could change the divider as long as we keep the correct
+ * ratio between all of the clocks, but we don't support that because there is
+ * currently not a need for it.
+ */
+
+static const struct davinci_pll_divclk_info da850_pll0_divclk_info[] __initconst = {
+ DIVCLK(1, pll0_sysclk1, pll0, DIVCLK_FIXED_DIV),
+ DIVCLK(2, pll0_sysclk2, pll0, DIVCLK_FIXED_DIV),
+ DIVCLK(3, pll0_sysclk3, pll0, 0),
+ DIVCLK(4, pll0_sysclk4, pll0, DIVCLK_FIXED_DIV),
+ DIVCLK(5, pll0_sysclk5, pll0, 0),
+ DIVCLK(6, pll0_sysclk6, pll0, DIVCLK_ARM_RATE | DIVCLK_FIXED_DIV),
+ DIVCLK(7, pll0_sysclk7, pll0, 0),
+ { }
+};
+
+static const struct davinci_pll_divclk_info da850_pll1_divclk_info[] __initconst = {
+ DIVCLK(1, pll1_sysclk1, pll1, DIVCLK_ALWAYS_ENABLED),
+ DIVCLK(2, pll1_sysclk2, pll1, 0),
+ DIVCLK(3, pll1_sysclk3, pll1, 0),
+ { }
+};
+
+void __init da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1)
+{
+ const struct davinci_pll_divclk_info *info;
+
+ davinci_pll_clk_register("pll0", "ref_clk", pll0);
+ davinci_pll_aux_clk_register("pll0_aux_clk", "ref_clk", pll0);
+ for (info = da850_pll0_divclk_info; info->name; info++)
+ davinci_pll_divclk_register(info, pll0);
+
+ davinci_pll_clk_register("pll1", "ref_clk", pll1);
+ for (info = da850_pll1_divclk_info; info->name; info++)
+ davinci_pll_divclk_register(info, pll1);
+}
+
+#ifdef CONFIG_OF
+static void __init of_da850_pll0_auxclk_init(struct device_node *node)
+{
+ of_davinci_pll_init(node, "pll0", da850_pll0_divclk_info, 7);
+}
+CLK_OF_DECLARE(da850_pll0_auxclk, "ti,da850-pll0", of_da850_pll0_auxclk_init);
+
+static void __init of_da850_pll1_auxclk_init(struct device_node *node)
+{
+ of_davinci_pll_init(node, "pll1", da850_pll1_divclk_info, 3);
+}
+CLK_OF_DECLARE(da850_pll1_auxclk, "ti,da850-pll1", of_da850_pll1_auxclk_init);
+#endif
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index 4f4d60d..7b08fe0 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -10,5 +10,6 @@
#include <linux/types.h>
void da830_pll_clk_init(void __iomem *pll);
+void da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1);
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 04/44] clk: davinci: Add platform information for TI DA850 PLL
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
0 siblings, 0 replies; 121+ messages in thread
From: Sekhar Nori @ 2018-01-16 8:37 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> +void __init da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1)
> +{
> + const struct davinci_pll_divclk_info *info;
> +
> + davinci_pll_clk_register("pll0", "ref_clk", pll0);
I think this will be more readable with empty lines between these
function calls. So here ..
> + davinci_pll_aux_clk_register("pll0_aux_clk", "ref_clk", pll0);
.. here
> + for (info = da850_pll0_divclk_info; info->name; info++)
> + davinci_pll_divclk_register(info, pll0);
> +
> + davinci_pll_clk_register("pll1", "ref_clk", pll1);
.. and here.
> + for (info = da850_pll1_divclk_info; info->name; info++)
> + davinci_pll_divclk_register(info, pll1);
I see that you have included empty line only when changing the PLL, but
I feel its more readable with the additional spacing suggested.
Same comment for other patches too with similar function implemented.
With that minor comment:
Reviewed-by: Sekhar Nori <nsekhar@ti.com>
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 05/44] clk: davinci: Add platform information for TI DM355 PLL
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (3 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 04/44] clk: davinci: Add platform information for TI DA850 PLL David Lechner
@ 2018-01-08 2:17 ` 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
` (23 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds platform-specific declarations for the PLL clocks on TI
DaVinci 355 based systems.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm355.c | 40 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 42 insertions(+)
create mode 100644 drivers/clk/davinci/pll-dm355.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 13049d4..6720bd0 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -4,4 +4,5 @@ ifeq ($(CONFIG_COMMON_CLK), y)
obj-y += pll.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
+obj-$(CONFIG_ARCH_DAVINCI_DM355) += pll-dm355.o
endif
diff --git a/drivers/clk/davinci/pll-dm355.c b/drivers/clk/davinci/pll-dm355.c
new file mode 100644
index 0000000..972fd2b
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm355.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM355
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const struct davinci_pll_divclk_info dm355_pll1_divclk_info[] __initconst = {
+ DIVCLK(1, pll1_sysclk1, pll1, DIVCLK_FIXED_DIV),
+ DIVCLK(2, pll1_sysclk2, pll1, DIVCLK_FIXED_DIV),
+ DIVCLK(3, pll1_sysclk3, pll1, 0),
+ DIVCLK(4, pll1_sysclk4, pll1, 0),
+ { }
+};
+
+static const struct davinci_pll_divclk_info dm355_pll2_divclk_info[] __initconst = {
+ DIVCLK(1, pll2_sysclk1, pll2, DIVCLK_FIXED_DIV),
+ { }
+};
+
+void __init dm355_pll_clk_init(void __iomem *pll1, void __iomem *pll2)
+{
+ const struct davinci_pll_divclk_info *info;
+
+ davinci_pll_clk_register("pll1", "ref_clk", pll1);
+ for (info = dm355_pll1_divclk_info; info->name; info++)
+ davinci_pll_divclk_register(info, pll1);
+ davinci_pll_aux_clk_register("pll1_aux_clk", "ref_clk", pll1);
+ davinci_pll_bpdiv_clk_register("pll1_sysclkbp", "ref_clk", pll1);
+
+ davinci_pll_clk_register("pll2", "ref_clk", pll2);
+ for (info = dm355_pll2_divclk_info; info->name; info++)
+ davinci_pll_divclk_register(info, pll2);
+ davinci_pll_bpdiv_clk_register("pll2_sysclkbp", "ref_clk", pll2);
+}
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index 7b08fe0..95333fe 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -11,5 +11,6 @@
void da830_pll_clk_init(void __iomem *pll);
void da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1);
+void dm355_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 05/44] clk: davinci: Add platform information for TI DM355 PLL
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
0 siblings, 0 replies; 121+ messages in thread
From: Sekhar Nori @ 2018-01-16 8:38 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, Kevin Hilman, Michael Turquette, Stephen Boyd,
linux-kernel, Rob Herring, Adam Ford
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> This adds platform-specific declarations for the PLL clocks on TI
> DaVinci 355 based systems.
DM355
>
> Signed-off-by: David Lechner <david@lechnology.com>
Reviewed-by: Sekhar Nori <nsekhar@ti.com>
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 06/44] clk: davinci: Add platform information for TI DM365 PLL
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (4 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 05/44] clk: davinci: Add platform information for TI DM355 PLL David Lechner
@ 2018-01-08 2:17 ` David Lechner
[not found] ` <1515377863-20358-7-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-08 2:17 ` [PATCH v5 07/44] clk: davinci: Add platform information for TI DM644x PLL David Lechner
` (22 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, David Lechner, Kevin Hilman, Stephen Boyd,
Michael Turquette, Sekhar Nori, linux-kernel, Rob Herring,
Adam Ford
This adds platform-specific declarations for the PLL clocks on TI
DaVinci 365 based systems.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm365.c | 64 +++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 66 insertions(+)
create mode 100644 drivers/clk/davinci/pll-dm365.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 6720bd0..353aa02 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -5,4 +5,5 @@ obj-y += pll.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += pll-dm355.o
+obj-$(CONFIG_ARCH_DAVINCI_DM365) += pll-dm365.o
endif
diff --git a/drivers/clk/davinci/pll-dm365.c b/drivers/clk/davinci/pll-dm365.c
new file mode 100644
index 0000000..9892b0b
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm365.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM365
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const char * const dm365_pll_obsclk_parent_names[] = {
+ "ref_clk",
+};
+
+static u32 dm365_pll_obsclk_table[] = {
+ 0x10,
+};
+
+static const struct davinci_pll_divclk_info dm365_pll1_divclk_info[] __initconst = {
+ DIVCLK(1, pll1_sysclk1, pll1, 0),
+ DIVCLK(2, pll1_sysclk2, pll1, 0),
+ DIVCLK(3, pll1_sysclk3, pll1, 0),
+ DIVCLK(4, pll1_sysclk4, pll1, 0),
+ DIVCLK(5, pll1_sysclk5, pll1, 0),
+ DIVCLK(6, pll1_sysclk6, pll1, 0),
+ DIVCLK(7, pll1_sysclk7, pll1, 0),
+ DIVCLK(8, pll1_sysclk8, pll1, 0),
+ DIVCLK(9, pll1_sysclk9, pll1, 0),
+ { }
+};
+
+static const struct davinci_pll_divclk_info dm365_pll2_divclk_info[] __initconst = {
+ DIVCLK(1, pll2_sysclk1, pll2, 0),
+ DIVCLK(2, pll2_sysclk2, pll2, 0),
+ DIVCLK(3, pll2_sysclk3, pll2, 0),
+ DIVCLK(4, pll2_sysclk4, pll2, 0),
+ DIVCLK(5, pll2_sysclk5, pll2, 0),
+ { }
+};
+
+void __init dm365_pll_clk_init(void __iomem *pll1, void __iomem *pll2)
+{
+ const struct davinci_pll_divclk_info *info;
+
+ davinci_pll_clk_register("pll1", "ref_clk", pll1);
+ davinci_pll_aux_clk_register("pll1_aux_clk", "ref_clk", pll1);
+ davinci_pll_bpdiv_clk_register("pll1_sysclkbp", "ref_clk", pll1);
+ davinci_pll_obs_clk_register("clkout0", dm365_pll_obsclk_parent_names,
+ ARRAY_SIZE(dm365_pll_obsclk_parent_names),
+ pll1, dm365_pll_obsclk_table);
+ for (info = dm365_pll1_divclk_info; info->name; info++)
+ davinci_pll_divclk_register(info, pll1);
+
+ davinci_pll_clk_register("pll2", "ref_clk", pll2);
+ davinci_pll_aux_clk_register("clkout1", "ref_clk", pll2);
+ davinci_pll_obs_clk_register("clkout1", dm365_pll_obsclk_parent_names,
+ ARRAY_SIZE(dm365_pll_obsclk_parent_names),
+ pll2, dm365_pll_obsclk_table);
+ for (info = dm365_pll2_divclk_info; info->name; info++)
+ davinci_pll_divclk_register(info, pll2);
+}
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index 95333fe..5bf60a7 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -12,5 +12,6 @@
void da830_pll_clk_init(void __iomem *pll);
void da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1);
void dm355_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
+void dm365_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 07/44] clk: davinci: Add platform information for TI DM644x PLL
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (5 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 06/44] clk: davinci: Add platform information for TI DM365 PLL David Lechner
@ 2018-01-08 2:17 ` David Lechner
[not found] ` <1515377863-20358-8-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-08 2:17 ` [PATCH v5 08/44] clk: davinci: Add platform information for TI DM646x PLL David Lechner
` (21 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds platform-specific declarations for the PLL clocks on TI
DaVinci 644x based systems.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm644x.c | 41 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 43 insertions(+)
create mode 100644 drivers/clk/davinci/pll-dm644x.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 353aa02..59d8ab6 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += pll-dm355.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += pll-dm365.o
+obj-$(CONFIG_ARCH_DAVINCI_DM644x) += pll-dm644x.o
endif
diff --git a/drivers/clk/davinci/pll-dm644x.c b/drivers/clk/davinci/pll-dm644x.c
new file mode 100644
index 0000000..b0d0373
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm644x.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM644X
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const struct davinci_pll_divclk_info dm644x_pll1_divclk_info[] __initconst = {
+ DIVCLK(1, pll1_sysclk1, pll1, DIVCLK_FIXED_DIV),
+ DIVCLK(2, pll1_sysclk2, pll1, DIVCLK_FIXED_DIV),
+ DIVCLK(3, pll1_sysclk3, pll1, DIVCLK_FIXED_DIV),
+ DIVCLK(5, pll1_sysclk5, pll1, DIVCLK_FIXED_DIV),
+ { }
+};
+
+static const struct davinci_pll_divclk_info dm644x_pll2_divclk_info[] __initconst = {
+ DIVCLK(1, pll2_sysclk1, pll2, 0),
+ DIVCLK(2, pll2_sysclk2, pll2, 0),
+ { }
+};
+
+void __init dm644x_pll_clk_init(void __iomem *pll1, void __iomem *pll2)
+{
+ const struct davinci_pll_divclk_info *info;
+
+ davinci_pll_clk_register("pll1", "ref_clk", pll1);
+ for (info = dm644x_pll1_divclk_info; info->name; info++)
+ davinci_pll_divclk_register(info, pll1);
+ davinci_pll_aux_clk_register("pll1_aux_clk", "ref_clk", pll1);
+ davinci_pll_bpdiv_clk_register("pll1_sysclkbp", "ref_clk", pll1);
+
+ davinci_pll_clk_register("pll2", "ref_clk", pll2);
+ for (info = dm644x_pll2_divclk_info; info->name; info++)
+ davinci_pll_divclk_register(info, pll2);
+ davinci_pll_bpdiv_clk_register("pll2_sysclkbp", "ref_clk", pll2);
+}
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index 5bf60a7..535990a 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -13,5 +13,6 @@ void da830_pll_clk_init(void __iomem *pll);
void da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1);
void dm355_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
void dm365_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
+void dm644x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 08/44] clk: davinci: Add platform information for TI DM646x PLL
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (6 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 07/44] clk: davinci: Add platform information for TI DM644x PLL David Lechner
@ 2018-01-08 2:17 ` 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
` (20 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, David Lechner, Kevin Hilman, Stephen Boyd,
Michael Turquette, Sekhar Nori, linux-kernel, Rob Herring,
Adam Ford
This adds platform-specific declarations for the PLL clocks on TI
DaVinci 646x based systems.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm646x.c | 44 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 46 insertions(+)
create mode 100644 drivers/clk/davinci/pll-dm646x.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 59d8ab6..d471386 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += pll-dm355.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += pll-dm365.o
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += pll-dm644x.o
+obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
endif
diff --git a/drivers/clk/davinci/pll-dm646x.c b/drivers/clk/davinci/pll-dm646x.c
new file mode 100644
index 0000000..9d5bdaf
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm646x.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM646X
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const struct davinci_pll_divclk_info dm646x_pll1_divclk_info[] __initconst = {
+ DIVCLK(1, pll1_sysclk1, pll1, DIVCLK_FIXED_DIV),
+ DIVCLK(2, pll1_sysclk2, pll1, DIVCLK_FIXED_DIV),
+ DIVCLK(3, pll1_sysclk3, pll1, DIVCLK_FIXED_DIV),
+ DIVCLK(4, pll1_sysclk4, pll1, 0),
+ DIVCLK(5, pll1_sysclk5, pll1, 0),
+ DIVCLK(6, pll1_sysclk6, pll1, 0),
+ DIVCLK(7, pll1_sysclk7, pll1, 0),
+ DIVCLK(8, pll1_sysclk8, pll1, 0),
+ DIVCLK(9, pll1_sysclk9, pll1, 0),
+ { }
+};
+
+static const struct davinci_pll_divclk_info dm646x_pll2_divclk_info[] __initconst = {
+ DIVCLK(1, pll2_sysclk1, pll2, 0),
+ { }
+};
+
+void __init dm646x_pll_clk_init(void __iomem *pll1, void __iomem *pll2)
+{
+ const struct davinci_pll_divclk_info *info;
+
+ davinci_pll_clk_register("pll1", "ref_clk", pll1);
+ for (info = dm646x_pll1_divclk_info; info->name; info++)
+ davinci_pll_divclk_register(info, pll1);
+ davinci_pll_bpdiv_clk_register("pll1_sysclkbp", "ref_clk", pll1);
+ davinci_pll_aux_clk_register("pll1_aux_clk", "ref_clk", pll1);
+
+ davinci_pll_clk_register("pll2_clk", "ref_clk", pll2);
+ for (info = dm646x_pll2_divclk_info; info->name; info++)
+ davinci_pll_divclk_register(info, pll2);
+}
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index 535990a..d495de7 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -14,5 +14,6 @@ void da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1);
void dm355_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
void dm365_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
void dm644x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
+void dm646x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 08/44] clk: davinci: Add platform information for TI DM646x PLL
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
0 siblings, 0 replies; 121+ messages in thread
From: Sekhar Nori @ 2018-01-16 9:01 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, Kevin Hilman, Michael Turquette, Stephen Boyd,
linux-kernel, Rob Herring, Adam Ford
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> This adds platform-specific declarations for the PLL clocks on TI
> DaVinci 646x based systems.
>
> Signed-off-by: David Lechner <david@lechnology.com>
Some minor comments I gave on other patches apply here too. Apart from
those:
Reviewed-by: Sekhar Nori <nsekhar@ti.com>
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 09/44] dt-bindings: clock: New bindings for TI Davinci PSC
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (7 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 08/44] clk: davinci: Add platform information for TI DM646x PLL David Lechner
@ 2018-01-08 2:17 ` David Lechner
[not found] ` <1515377863-20358-10-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-08 2:17 ` [PATCH v5 10/44] clk: davinci: New driver for davinci PSC clocks David Lechner
` (19 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, David Lechner, Kevin Hilman, Stephen Boyd,
Michael Turquette, Sekhar Nori, linux-kernel, Rob Herring,
Adam Ford
This adds a new binding for the Power Sleep Controller (PSC) for the
mach-davinci family of processors.
Note: Although TI Keystone has a very similar PSC, we are not using the
existing bindings. Keystone is using a legacy one-node-per-clock binding
(actually two nodes if you count the separate reset binding for the same
IP block). Also, some davinci LPSCs have quirks that aren't handled by
the keystone bindings, so we would be adding one compatible string per
clock with quirks instead of just a new compatible string for each
controller.
Signed-off-by: David Lechner <david@lechnology.com>
---
.../devicetree/bindings/clock/ti/davinci/psc.txt | 47 ++++++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/psc.txt
diff --git a/Documentation/devicetree/bindings/clock/ti/davinci/psc.txt b/Documentation/devicetree/bindings/clock/ti/davinci/psc.txt
new file mode 100644
index 0000000..83a9da5
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/davinci/psc.txt
@@ -0,0 +1,47 @@
+Binding for TI DaVinci Power Sleep Controller (PSC)
+
+The PSC provides power management, clock gating and reset functionality. It is
+primarily used for clocking.
+
+Required properties:
+- compatible: shall be one of:
+ - "ti,da850-psc0" for PSC0 on DA850/OMAP-L138/AM18XX
+ - "ti,da850-psc1" for PSC1 on DA850/OMAP-L138/AM18XX
+- reg: physical base address and size of the controller's register area.
+- #clock-cells: from common clock binding; shall be set to 1.
+- #reset-cells: from reset binding; shall be set to 1.
+
+Consumers:
+
+ Clock and reset consumers shall use the local power domain module ID
+ (LPSC) as the index corresponding to the clock cell. Refer to the
+ device-specific datasheet to find these numbers. NB: Most local domains
+ only provide a clock and not a reset.
+
+Examples:
+
+ psc0: clock-controller@10000 {
+ compatible = "ti,da850-psc0";
+ reg = <0x10000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ /* consumer */
+ dsp: dsp@11800000 {
+ compatible = "ti,da850-dsp";
+ reg = <0x11800000 0x40000>,
+ <0x11e00000 0x8000>,
+ <0x11f00000 0x8000>,
+ <0x01c14044 0x4>,
+ <0x01c14174 0x8>;
+ reg-names = "l2sram", "l1pram", "l1dram", "host1cfg", "chipsig";
+ interrupt-parent = <&intc>;
+ interrupts = <28>;
+ clocks = <&psc0 15>;
+ resets = <&psc0 15>;
+ };
+
+Also see:
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
+- Documentation/devicetree/bindings/reset/reset.txt
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 10/44] clk: davinci: New driver for davinci PSC clocks
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (8 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 09/44] dt-bindings: clock: New bindings for TI Davinci PSC David Lechner
@ 2018-01-08 2:17 ` David Lechner
2018-01-16 11:03 ` Sekhar Nori
2018-01-08 2:17 ` [PATCH v5 11/44] clk: davinci: Add platform information for TI DA830 PSC David Lechner
` (18 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, David Lechner, Kevin Hilman, Stephen Boyd,
Michael Turquette, Sekhar Nori, linux-kernel, Rob Herring,
Adam Ford
This adds a new driver for mach-davinci PSC clocks. This is porting the
code from arch/arm/mach-davinci/psc.c to the common clock framework and
is converting it to use regmap to simplify the code. Additionally, it adds
device tree support for these clocks.
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 keystone driver
makes the assumption that there is only one PSC per SoC and uses global
variables, but here we have two controllers per SoC.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 2 +
drivers/clk/davinci/psc.c | 282 +++++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/psc.h | 49 ++++++++
3 files changed, 333 insertions(+)
create mode 100644 drivers/clk/davinci/psc.c
create mode 100644 drivers/clk/davinci/psc.h
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index d471386..cd1bf2c 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -8,4 +8,6 @@ obj-$(CONFIG_ARCH_DAVINCI_DM355) += pll-dm355.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += pll-dm365.o
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += pll-dm644x.o
obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
+
+obj-y += psc.o
endif
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
new file mode 100644
index 0000000..a8b5f57
--- /dev/null
+++ b/drivers/clk/davinci/psc.c
@@ -0,0 +1,282 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for TI Davinci PSC controllers
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ *
+ * Based on: drivers/clk/keystone/gate.c
+ * Copyright (C) 2013 Texas Instruments.
+ * Murali Karicheri <m-karicheri2@ti.com>
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * And: arch/arm/mach-davinci/psc.c
+ * Copyright (C) 2006 Texas Instruments.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+/* PSC register offsets */
+#define EPCPR 0x070
+#define PTCMD 0x120
+#define PTSTAT 0x128
+#define PDSTAT(n) (0x200 + 4 * (n))
+#define PDCTL(n) (0x300 + 4 * (n))
+#define MDSTAT(n) (0x800 + 4 * (n))
+#define MDCTL(n) (0xa00 + 4 * (n))
+
+/* PSC module states */
+enum davinci_psc_state {
+ PSC_STATE_SWRSTDISABLE = 0,
+ PSC_STATE_SYNCRST = 1,
+ PSC_STATE_DISABLE = 2,
+ PSC_STATE_ENABLE = 3,
+};
+
+#define MDSTAT_STATE_MASK 0x3f
+#define MDSTAT_MCKOUT BIT(12)
+#define PDSTAT_STATE_MASK 0x1f
+#define MDCTL_FORCE BIT(31)
+#define MDCTL_LRESET BIT(8)
+#define PDCTL_EPCGOOD BIT(8)
+#define PDCTL_NEXT BIT(0)
+
+/**
+ * struct davinci_psc_clk - PSC clock structure
+ * @hw: clk_hw for the psc
+ * @regmap: PSC MMIO region
+ * @lpsc: Local PSC number (module id)
+ * @pd: Power domain
+ * @flags: LPSC_* quirk flags
+ */
+struct davinci_psc_clk {
+ struct clk_hw hw;
+ struct regmap *regmap;
+ u32 lpsc;
+ u32 pd;
+ u32 flags;
+};
+
+#define to_davinci_psc_clk(_hw) container_of(_hw, struct davinci_psc_clk, hw)
+
+static void psc_config(struct davinci_psc_clk *psc,
+ enum davinci_psc_state next_state)
+{
+ u32 epcpr, pdstat, mdstat, mdctl, ptstat;
+
+ mdctl = next_state;
+ if (psc->flags & LPSC_FORCE)
+ mdctl |= MDCTL_FORCE;
+ regmap_write_bits(psc->regmap, MDCTL(psc->lpsc), MDSTAT_STATE_MASK,
+ mdctl);
+
+ regmap_read(psc->regmap, PDSTAT(psc->pd), &pdstat);
+ if ((pdstat & PDSTAT_STATE_MASK) == 0) {
+ regmap_write_bits(psc->regmap, PDSTAT(psc->pd),
+ PDSTAT_STATE_MASK, PDCTL_NEXT);
+
+ regmap_write(psc->regmap, PTCMD, BIT(psc->pd));
+
+ regmap_read_poll_timeout(psc->regmap, EPCPR, epcpr,
+ epcpr & BIT(psc->pd), 0, 0);
+
+ regmap_write_bits(psc->regmap, PDCTL(psc->pd), PDCTL_EPCGOOD,
+ PDCTL_EPCGOOD);
+ } else {
+ regmap_write(psc->regmap, PTCMD, BIT(psc->pd));
+ }
+
+ regmap_read_poll_timeout(psc->regmap, PTSTAT, ptstat,
+ !(ptstat & BIT(psc->pd)), 0, 0);
+
+ regmap_read_poll_timeout(psc->regmap, MDSTAT(psc->lpsc), mdstat,
+ (mdstat & MDSTAT_STATE_MASK) == next_state,
+ 0, 0);
+}
+
+static int davinci_psc_clk_enable(struct clk_hw *hw)
+{
+ struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
+
+ psc_config(psc, PSC_STATE_ENABLE);
+
+ return 0;
+}
+
+static void davinci_psc_clk_disable(struct clk_hw *hw)
+{
+ struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
+
+ psc_config(psc, PSC_STATE_DISABLE);
+}
+
+static int davinci_psc_clk_is_enabled(struct clk_hw *hw)
+{
+ struct davinci_psc_clk *psc = to_davinci_psc_clk(hw);
+ u32 mdstat;
+
+ regmap_read(psc->regmap, MDSTAT(psc->lpsc), &mdstat);
+
+ return (mdstat & MDSTAT_MCKOUT) ? 1 : 0;
+}
+
+static const struct clk_ops davinci_psc_clk_ops = {
+ .enable = davinci_psc_clk_enable,
+ .disable = davinci_psc_clk_disable,
+ .is_enabled = davinci_psc_clk_is_enabled,
+};
+
+/**
+ * davinci_psc_clk_register - register psc clock
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @regmap: PSC MMIO region
+ * @lpsc: local PSC number
+ * @pd: power domain
+ * @flags: LPSC_* flags
+ */
+static struct clk *davinci_psc_clk_register(const char *name,
+ const char *parent_name,
+ struct regmap *regmap,
+ u32 lpsc, u32 pd, u32 flags)
+{
+ struct clk_init_data init;
+ struct davinci_psc_clk *psc;
+ struct clk *clk;
+
+ psc = kzalloc(sizeof(*psc), GFP_KERNEL);
+ if (!psc)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &davinci_psc_clk_ops;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+ init.flags = CLK_SET_RATE_PARENT;
+
+ if (flags & LPSC_ALWAYS_ENABLED)
+ init.flags |= CLK_IS_CRITICAL;
+
+ psc->regmap = regmap;
+ psc->hw.init = &init;
+ psc->lpsc = lpsc;
+ psc->pd = pd;
+ psc->flags = flags;
+
+ clk = clk_register(NULL, &psc->hw);
+ if (IS_ERR(clk))
+ kfree(psc);
+
+ return clk;
+}
+
+/*
+ * FIXME: This needs to be converted to a reset controller. But, the reset
+ * framework is currently device tree only.
+ */
+
+static int davinci_psc_clk_reset(struct davinci_psc_clk *psc, bool reset)
+{
+ u32 mdctl;
+
+ if (IS_ERR_OR_NULL(psc))
+ return -EINVAL;
+
+ mdctl = reset ? 0 : MDCTL_LRESET;
+ regmap_write_bits(psc->regmap, MDCTL(psc->lpsc), MDCTL_LRESET, mdctl);
+
+ return 0;
+}
+
+int davinci_clk_reset_assert(struct clk *clk)
+{
+ struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
+
+ return davinci_psc_clk_reset(psc, true);
+}
+EXPORT_SYMBOL(davinci_clk_reset_assert);
+
+int davinci_clk_reset_deassert(struct clk *clk)
+{
+ struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
+
+ return davinci_psc_clk_reset(psc, false);
+}
+EXPORT_SYMBOL(davinci_clk_reset_deassert);
+
+static const struct regmap_config davinci_psc_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+};
+
+struct clk_onecell_data *
+davinci_psc_register_clocks(void __iomem *base,
+ const struct davinci_psc_clk_info *info,
+ u8 num_clks)
+{
+ struct clk_onecell_data *clk_data;
+ struct regmap *regmap;
+
+ clk_data = clk_alloc_onecell_data(num_clks);
+ if (!clk_data) {
+ pr_err("%s: Out of memory\n", __func__);
+ return NULL;
+ }
+
+ regmap = regmap_init_mmio(NULL, base, &davinci_psc_regmap_config);
+ if (IS_ERR(regmap)) {
+ pr_err("%s: regmap_init_mmio failed (%ld)\n", __func__,
+ PTR_ERR(regmap));
+ clk_free_onecell_data(clk_data);
+ return NULL;
+ }
+
+ for (; info->name; info++) {
+ struct clk *clk;
+
+ clk = davinci_psc_clk_register(info->name, info->parent, regmap,
+ info->lpsc, info->pd, info->flags);
+ if (IS_ERR(clk)) {
+ pr_warn("%s: Failed to register %s (%ld)\n", __func__,
+ info->name, PTR_ERR(clk));
+ continue;
+ }
+
+ clk_data->clks[info->lpsc] = clk;
+ }
+
+ return clk_data;
+}
+
+#ifdef CONFIG_OF
+void of_davinci_psc_clk_init(struct device_node *node,
+ const struct davinci_psc_clk_info *info,
+ u8 num_clks)
+{
+ struct clk_onecell_data *clk_data;
+ void __iomem *base;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s: ioremap failed\n", __func__);
+ return;
+ }
+
+ clk_data = davinci_psc_register_clocks(base, info, num_clks);
+ if (!clk_data)
+ return;
+
+ of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+#endif
diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
new file mode 100644
index 0000000..6022f6e
--- /dev/null
+++ b/drivers/clk/davinci/psc.h
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for TI Davinci PSC controllers
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#ifndef __CLK_DAVINCI_PSC_H__
+#define __CLK_DAVINCI_PSC_H__
+
+#include <linux/types.h>
+
+/* PSC quirk flags */
+#define LPSC_ALWAYS_ENABLED BIT(1) /* never disable this clock */
+#define LPSC_FORCE BIT(2) /* requires MDCTL FORCE bit */
+#define LPSC_LOCAL_RESET BIT(3) /* acts as reset provider */
+
+struct clk_onecell_data;
+
+struct davinci_psc_clk_info {
+ const char *name;
+ const char *parent;
+ u32 lpsc;
+ u32 pd;
+ unsigned long flags;
+ bool has_reset;
+};
+
+#define LPSC(l, d, n, p, f) \
+{ \
+ .name = #n, \
+ .parent = #p, \
+ .lpsc = (l), \
+ .pd = (d), \
+ .flags = (f), \
+}
+
+struct clk_onecell_data *
+davinci_psc_register_clocks(void __iomem *base,
+ const struct davinci_psc_clk_info *info,
+ u8 num_clks);
+
+#ifdef CONFIG_OF
+void of_davinci_psc_clk_init(struct device_node *node,
+ const struct davinci_psc_clk_info *info,
+ u8 num_clks);
+#endif
+
+#endif /* __CLK_DAVINCI_PSC_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 10/44] clk: davinci: New driver for davinci PSC clocks
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
0 siblings, 1 reply; 121+ messages in thread
From: Sekhar Nori @ 2018-01-16 11:03 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> This adds a new driver for mach-davinci PSC clocks. This is porting the
> code from arch/arm/mach-davinci/psc.c to the common clock framework and
> is converting it to use regmap to simplify the code. Additionally, it adds
> device tree support for these clocks.
>
> 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 keystone driver
> makes the assumption that there is only one PSC per SoC and uses global
> variables, but here we have two controllers per SoC.
>
> Signed-off-by: David Lechner <david@lechnology.com>
> ---
> drivers/clk/davinci/Makefile | 2 +
> drivers/clk/davinci/psc.c | 282 +++++++++++++++++++++++++++++++++++++++++++
> drivers/clk/davinci/psc.h | 49 ++++++++
> 3 files changed, 333 insertions(+)
> create mode 100644 drivers/clk/davinci/psc.c
> create mode 100644 drivers/clk/davinci/psc.h
>
> diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
> index d471386..cd1bf2c 100644
> --- a/drivers/clk/davinci/Makefile
> +++ b/drivers/clk/davinci/Makefile
> @@ -8,4 +8,6 @@ obj-$(CONFIG_ARCH_DAVINCI_DM355) += pll-dm355.o
> obj-$(CONFIG_ARCH_DAVINCI_DM365) += pll-dm365.o
> obj-$(CONFIG_ARCH_DAVINCI_DM644x) += pll-dm644x.o
> obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
> +
> +obj-y += psc.o
> endif
> diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
> new file mode 100644
> index 0000000..a8b5f57
> --- /dev/null
> +++ b/drivers/clk/davinci/psc.c
> @@ -0,0 +1,282 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Clock driver for TI Davinci PSC controllers
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
2018
> + *
> + * Based on: drivers/clk/keystone/gate.c
> + * Copyright (C) 2013 Texas Instruments.
> + * Murali Karicheri <m-karicheri2@ti.com>
> + * Santosh Shilimkar <santosh.shilimkar@ti.com>
> + *
> + * And: arch/arm/mach-davinci/psc.c
> + * Copyright (C) 2006 Texas Instruments.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/clk/davinci.h>
> +#include <linux/clkdev.h>
> +#include <linux/err.h>
> +#include <linux/of_address.h>
> +#include <linux/of.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +
> +#include "psc.h"
> +
> +/* PSC register offsets */
> +#define EPCPR 0x070
> +#define PTCMD 0x120
> +#define PTSTAT 0x128
> +#define PDSTAT(n) (0x200 + 4 * (n))
> +#define PDCTL(n) (0x300 + 4 * (n))
> +#define MDSTAT(n) (0x800 + 4 * (n))
> +#define MDCTL(n) (0xa00 + 4 * (n))
> +
> +/* PSC module states */
> +enum davinci_psc_state {
> + PSC_STATE_SWRSTDISABLE = 0,
> + PSC_STATE_SYNCRST = 1,
> + PSC_STATE_DISABLE = 2,
> + PSC_STATE_ENABLE = 3,
> +};
> +
> +#define MDSTAT_STATE_MASK 0x3f> +#define MDSTAT_MCKOUT BIT(12)
> +#define PDSTAT_STATE_MASK 0x1f
GENMASK() for masks.
> +#define MDCTL_FORCE BIT(31)
> +#define MDCTL_LRESET BIT(8)
> +#define PDCTL_EPCGOOD BIT(8)
> +#define PDCTL_NEXT BIT(0)
> +
> +/**
> + * struct davinci_psc_clk - PSC clock structure
> + * @hw: clk_hw for the psc
> + * @regmap: PSC MMIO region
> + * @lpsc: Local PSC number (module id)
> + * @pd: Power domain
> + * @flags: LPSC_* quirk flags
> + */
> +struct davinci_psc_clk {
> + struct clk_hw hw;
> + struct regmap *regmap;
> + u32 lpsc;
> + u32 pd;
> + u32 flags;
> +};
> +
> +#define to_davinci_psc_clk(_hw) container_of(_hw, struct davinci_psc_clk, hw)
> +
> +static void psc_config(struct davinci_psc_clk *psc,
> + enum davinci_psc_state next_state)
> +{
> + u32 epcpr, pdstat, mdstat, mdctl, ptstat;
> +
> + mdctl = next_state;
> + if (psc->flags & LPSC_FORCE)
> + mdctl |= MDCTL_FORCE;
> + regmap_write_bits(psc->regmap, MDCTL(psc->lpsc), MDSTAT_STATE_MASK,
> + mdctl);
Wont this ignore the MDCTL_FORCE bit since MDSTAT_STATE_MASK does not
cover that?
> +
> + regmap_read(psc->regmap, PDSTAT(psc->pd), &pdstat);
> + if ((pdstat & PDSTAT_STATE_MASK) == 0) {
> + regmap_write_bits(psc->regmap, PDSTAT(psc->pd),
> + PDSTAT_STATE_MASK, PDCTL_NEXT);
Shouldn't this be a write to PDCTL register?
> +
> + regmap_write(psc->regmap, PTCMD, BIT(psc->pd));
> +
> + regmap_read_poll_timeout(psc->regmap, EPCPR, epcpr,
> + epcpr & BIT(psc->pd), 0, 0);
> +
> + regmap_write_bits(psc->regmap, PDCTL(psc->pd), PDCTL_EPCGOOD,
> + PDCTL_EPCGOOD);
> + } else {
> + regmap_write(psc->regmap, PTCMD, BIT(psc->pd));
> + }
> +
> + regmap_read_poll_timeout(psc->regmap, PTSTAT, ptstat,
> + !(ptstat & BIT(psc->pd)), 0, 0);
> +
> + regmap_read_poll_timeout(psc->regmap, MDSTAT(psc->lpsc), mdstat,
> + (mdstat & MDSTAT_STATE_MASK) == next_state,
> + 0, 0);
> +}
> +
[...]
> +
> +/**
> + * davinci_psc_clk_register - register psc clock
> + * @dev: device that is registering this clock
No dev parameter below.
> + * @name: name of this clock
> + * @parent_name: name of clock's parent
> + * @regmap: PSC MMIO region
> + * @lpsc: local PSC number
> + * @pd: power domain
> + * @flags: LPSC_* flags
> + */
> +static struct clk *davinci_psc_clk_register(const char *name,
> + const char *parent_name,
> + struct regmap *regmap,
> + u32 lpsc, u32 pd, u32 flags)
> +{
> + struct clk_init_data init;
> + struct davinci_psc_clk *psc;
> + struct clk *clk;
> +
> + psc = kzalloc(sizeof(*psc), GFP_KERNEL);
> + if (!psc)
> + return ERR_PTR(-ENOMEM);
> +
> + init.name = name;
> + init.ops = &davinci_psc_clk_ops;
> + init.parent_names = (parent_name ? &parent_name : NULL);
> + init.num_parents = (parent_name ? 1 : 0);
> + init.flags = CLK_SET_RATE_PARENT;
Is this needed since PSC does not cause any rate change?
> +
> + if (flags & LPSC_ALWAYS_ENABLED)
> + init.flags |= CLK_IS_CRITICAL;
> +
> + psc->regmap = regmap;
> + psc->hw.init = &init;
> + psc->lpsc = lpsc;
> + psc->pd = pd;
> + psc->flags = flags;
> +
> + clk = clk_register(NULL, &psc->hw);
> + if (IS_ERR(clk))
> + kfree(psc);
> +
> + return clk;
> +}
> +
> +/*
> + * FIXME: This needs to be converted to a reset controller. But, the reset
> + * framework is currently device tree only.
Yeah, I see that __reset_control_get() fails with -EINVAL if there is no
of_node.
> + */
> +
> +static int davinci_psc_clk_reset(struct davinci_psc_clk *psc, bool reset)
> +{
> + u32 mdctl;
> +
> + if (IS_ERR_OR_NULL(psc))
> + return -EINVAL;
> +
> + mdctl = reset ? 0 : MDCTL_LRESET;
> + regmap_write_bits(psc->regmap, MDCTL(psc->lpsc), MDCTL_LRESET, mdctl);
> +
> + return 0;
> +}
> +
> +int davinci_clk_reset_assert(struct clk *clk)
> +{
> + struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
> +
> + return davinci_psc_clk_reset(psc, true);
> +}
> +EXPORT_SYMBOL(davinci_clk_reset_assert);
> +
> +int davinci_clk_reset_deassert(struct clk *clk)
> +{
> + struct davinci_psc_clk *psc = to_davinci_psc_clk(__clk_get_hw(clk));
> +
> + return davinci_psc_clk_reset(psc, false);
> +}
> +EXPORT_SYMBOL(davinci_clk_reset_deassert);
> +
[...]
> diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
> new file mode 100644
> index 0000000..6022f6e
> --- /dev/null
> +++ b/drivers/clk/davinci/psc.h
> @@ -0,0 +1,49 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Clock driver for TI Davinci PSC controllers
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + */
> +
> +#ifndef __CLK_DAVINCI_PSC_H__
> +#define __CLK_DAVINCI_PSC_H__
> +
> +#include <linux/types.h>
> +
> +/* PSC quirk flags */
> +#define LPSC_ALWAYS_ENABLED BIT(1) /* never disable this clock */
> +#define LPSC_FORCE BIT(2) /* requires MDCTL FORCE bit */
> +#define LPSC_LOCAL_RESET BIT(3) /* acts as reset provider */
> +
> +struct clk_onecell_data;
Rather clk-provider.h should be included in this file?
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 10/44] clk: davinci: New driver for davinci PSC clocks
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>
0 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-16 16:51 UTC (permalink / raw)
To: Sekhar Nori, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On 01/16/2018 05:03 AM, Sekhar Nori wrote:
> On Monday 08 January 2018 07:47 AM, David Lechner wrote:
>> This adds a new driver for mach-davinci PSC clocks. This is porting the
>> code from arch/arm/mach-davinci/psc.c to the common clock framework and
>> is converting it to use regmap to simplify the code. Additionally, it adds
>> device tree support for these clocks.
>>
>> 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 keystone driver
>> makes the assumption that there is only one PSC per SoC and uses global
>> variables, but here we have two controllers per SoC.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
>> ---
>> +static void psc_config(struct davinci_psc_clk *psc,
>> + enum davinci_psc_state next_state)
>> +{
>> + u32 epcpr, pdstat, mdstat, mdctl, ptstat;
>> +
>> + mdctl = next_state;
>> + if (psc->flags & LPSC_FORCE)
>> + mdctl |= MDCTL_FORCE;
>> + regmap_write_bits(psc->regmap, MDCTL(psc->lpsc), MDSTAT_STATE_MASK,
>> + mdctl);
>
> Wont this ignore the MDCTL_FORCE bit since MDSTAT_STATE_MASK does not
> cover that?
>
>> +
>> + regmap_read(psc->regmap, PDSTAT(psc->pd), &pdstat);
>> + if ((pdstat & PDSTAT_STATE_MASK) == 0) {
>> + regmap_write_bits(psc->regmap, PDSTAT(psc->pd),
>> + PDSTAT_STATE_MASK, PDCTL_NEXT);
>
> Shouldn't this be a write to PDCTL register?
>
Looks like I have some mistakes here. Thank you.
...
>> +static struct clk *davinci_psc_clk_register(const char *name,
>> + const char *parent_name,
>> + struct regmap *regmap,
>> + u32 lpsc, u32 pd, u32 flags)
>> +{
>> + struct clk_init_data init;
>> + struct davinci_psc_clk *psc;
>> + struct clk *clk;
>> +
>> + psc = kzalloc(sizeof(*psc), GFP_KERNEL);
>> + if (!psc)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + init.name = name;
>> + init.ops = &davinci_psc_clk_ops;
>> + init.parent_names = (parent_name ? &parent_name : NULL);
>> + init.num_parents = (parent_name ? 1 : 0);
>> + init.flags = CLK_SET_RATE_PARENT;
>
> Is this needed since PSC does not cause any rate change?
Yes, because one of the PSCs is the ARM clock and for cpufreq, we
need to propagate the rate change up the chain to SYSCLK6.
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 11/44] clk: davinci: Add platform information for TI DA830 PSC
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (9 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 10/44] clk: davinci: New driver for davinci PSC clocks David Lechner
@ 2018-01-08 2:17 ` David Lechner
[not found] ` <1515377863-20358-12-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
[not found] ` <1515377863-20358-1-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
` (17 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds platform-specific declarations for the PSC clocks on TI DA830/
OMAP-L137/AM17XX SoCs.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-da830.c | 96 +++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 2 +
3 files changed, 99 insertions(+)
create mode 100644 drivers/clk/davinci/psc-da830.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index cd1bf2c..fb14c8c 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -10,4 +10,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DM644x) += pll-dm644x.o
obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
obj-y += psc.o
+obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
endif
diff --git a/drivers/clk/davinci/psc-da830.c b/drivers/clk/davinci/psc-da830.c
new file mode 100644
index 0000000..193b08f
--- /dev/null
+++ b/drivers/clk/davinci/psc-da830.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DA830/OMAP-L137/AM17XX
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+static const struct davinci_psc_clk_info da830_psc0_info[] __initconst = {
+ LPSC(0, 0, tpcc, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(1, 0, tptc0, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(2, 0, tptc1, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(3, 0, aemif, pll0_sysclk3, LPSC_ALWAYS_ENABLED),
+ LPSC(4, 0, spi0, pll0_sysclk2, 0),
+ LPSC(5, 0, mmcsd, pll0_sysclk2, 0),
+ LPSC(6, 0, aintc, pll0_sysclk4, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, arm_rom, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(8, 0, secu_mgr, pll0_sysclk4, LPSC_ALWAYS_ENABLED),
+ LPSC(9, 0, uart0, pll0_sysclk2, 0),
+ LPSC(10, 0, scr0_ss, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(11, 0, scr1_ss, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(12, 0, scr2_ss, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(13, 0, dmax, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(14, 0, arm, pll0_sysclk6, LPSC_ALWAYS_ENABLED),
+ { }
+};
+
+static const struct davinci_psc_clk_info da830_psc1_info[] __initconst = {
+ LPSC(1, 0, usb0, pll0_sysclk2, 0),
+ LPSC(2, 0, usb1, pll0_sysclk4, 0),
+ LPSC(3, 0, gpio, pll0_sysclk4, 0),
+ LPSC(5, 0, emac, pll0_sysclk4, 0),
+ LPSC(6, 0, emif3, pll0_sysclk5, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, mcasp0, pll0_sysclk2, 0),
+ LPSC(8, 0, mcasp1, pll0_sysclk2, 0),
+ LPSC(9, 0, mcasp2, pll0_sysclk2, 0),
+ LPSC(10, 0, spi1, pll0_sysclk2, 0),
+ LPSC(11, 0, i2c1, pll0_sysclk4, 0),
+ LPSC(12, 0, uart1, pll0_sysclk2, 0),
+ LPSC(13, 0, uart2, pll0_sysclk2, 0),
+ LPSC(16, 0, lcdc, pll0_sysclk2, 0),
+ LPSC(17, 0, pwm, pll0_sysclk2, 0),
+ LPSC(20, 0, ecap, pll0_sysclk2, 0),
+ LPSC(21, 0, eqep, pll0_sysclk2, 0),
+ { }
+};
+
+void __init da830_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
+{
+ struct clk_onecell_data *clk_data;
+
+ clk_data = davinci_psc_register_clocks(psc0, da830_psc0_info, 16);
+ if (!clk_data)
+ return;
+
+ clk_register_clkdev(clk_data->clks[4], NULL, "spi_davinci.0");
+ clk_register_clkdev(clk_data->clks[5], NULL, "da830-mmc.0");
+ clk_register_clkdev(clk_data->clks[9], NULL, "serial8250.0");
+ clk_register_clkdev(clk_data->clks[14], "arm", NULL);
+
+ clk_free_onecell_data(clk_data);
+
+ clk_data = davinci_psc_register_clocks(psc1, da830_psc1_info, 32);
+ if (!clk_data)
+ return;
+
+ clk_register_clkdev(clk_data->clks[1], NULL, "musb-da8xx");
+ clk_register_clkdev(clk_data->clks[1], NULL, "cppi41-dmaengine");
+ clk_register_clkdev(clk_data->clks[2], NULL, "ohci-da8xx");
+ clk_register_clkdev(clk_data->clks[3], "gpio", NULL);
+ clk_register_clkdev(clk_data->clks[5], NULL, "davinci_emac.1");
+ clk_register_clkdev(clk_data->clks[5], "fck", "davinci_mdio.0");
+ clk_register_clkdev(clk_data->clks[7], NULL, "davinci-mcasp.0");
+ clk_register_clkdev(clk_data->clks[8], NULL, "davinci-mcasp.1");
+ clk_register_clkdev(clk_data->clks[9], NULL, "davinci-mcasp.2");
+ clk_register_clkdev(clk_data->clks[10], NULL, "spi_davinci.1");
+ clk_register_clkdev(clk_data->clks[11], NULL, "i2c_davinci.2");
+ clk_register_clkdev(clk_data->clks[12], NULL, "serial8250.1");
+ clk_register_clkdev(clk_data->clks[13], NULL, "serial8250.2");
+ clk_register_clkdev(clk_data->clks[16], "fck", "da8xx_lcdc.0");
+ clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.0");
+ clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.1");
+ clk_register_clkdev(clk_data->clks[20], "fck", "ecap.0");
+ clk_register_clkdev(clk_data->clks[20], "fck", "ecap.1");
+ clk_register_clkdev(clk_data->clks[20], "fck", "ecap.2");
+ clk_register_clkdev(clk_data->clks[21], NULL, "eqep.0");
+ clk_register_clkdev(clk_data->clks[21], NULL, "eqep.1");
+
+ clk_free_onecell_data(clk_data);
+}
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index d495de7..3ec8100 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -16,4 +16,6 @@ void dm365_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
void dm644x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
void dm646x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
+void da830_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
+
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
[parent not found: <1515377863-20358-1-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>]
* [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
[not found] ` <1515377863-20358-1-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
@ 2018-01-08 2:17 ` David Lechner
[not found] ` <1515377863-20358-13-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-02-09 16:22 ` Bartosz Golaszewski
2018-01-08 2:17 ` [PATCH v5 13/44] clk: davinci: Add platform information for TI DM355 PSC David Lechner
1 sibling, 2 replies; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Lechner
This adds platform-specific declarations for the PSC clocks on TI DA850/
OMAP-L138/AM18XX SoCs.
Signed-off-by: David Lechner <david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-da850.c | 117 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 119 insertions(+)
create mode 100644 drivers/clk/davinci/psc-da850.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index fb14c8c..aef0390 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -11,4 +11,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
obj-y += psc.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
+obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
endif
diff --git a/drivers/clk/davinci/psc-da850.c b/drivers/clk/davinci/psc-da850.c
new file mode 100644
index 0000000..3b4583d
--- /dev/null
+++ b/drivers/clk/davinci/psc-da850.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DA850/OMAP-L138/AM18XX
+ *
+ * Copyright (C) 2017 David Lechner <david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+static const struct davinci_psc_clk_info da850_psc0_info[] __initconst = {
+ LPSC(0, 0, tpcc0, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(1, 0, tptc0, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(2, 0, tptc1, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(3, 0, aemif, pll0_sysclk3, 0),
+ LPSC(4, 0, spi0, pll0_sysclk2, 0),
+ LPSC(5, 0, mmcsd0, pll0_sysclk2, 0),
+ LPSC(6, 0, aintc, pll0_sysclk4, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, arm_rom, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(9, 0, uart0, pll0_sysclk2, 0),
+ LPSC(13, 0, pruss, pll0_sysclk2, 0),
+ LPSC(14, 0, arm, pll0_sysclk6, LPSC_ALWAYS_ENABLED),
+ LPSC(15, 1, dsp, pll0_sysclk1, LPSC_FORCE | LPSC_LOCAL_RESET),
+ { }
+};
+
+static const struct davinci_psc_clk_info da850_psc1_info[] __initconst = {
+ LPSC(0, 0, tpcc1, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(1, 0, usb0, pll0_sysclk2, 0),
+ LPSC(2, 0, usb1, pll0_sysclk4, 0),
+ LPSC(3, 0, gpio, pll0_sysclk4, 0),
+ LPSC(5, 0, emac, pll0_sysclk4, 0),
+ LPSC(6, 0, emif3, pll0_sysclk5, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, mcasp0, async3, 0),
+ LPSC(8, 0, sata, pll0_sysclk2, LPSC_FORCE),
+ LPSC(9, 0, vpif, pll0_sysclk2, 0),
+ LPSC(10, 0, spi1, async3, 0),
+ LPSC(11, 0, i2c1, pll0_sysclk4, 0),
+ LPSC(12, 0, uart1, async3, 0),
+ LPSC(13, 0, uart2, async3, 0),
+ LPSC(14, 0, mcbsp0, async3, 0),
+ LPSC(15, 0, mcbsp1, async3, 0),
+ LPSC(16, 0, lcdc, pll0_sysclk2, 0),
+ LPSC(17, 0, ehrpwm, async3, 0),
+ LPSC(18, 0, mmcsd1, pll0_sysclk2, 0),
+ LPSC(20, 0, ecap, async3, 0),
+ LPSC(21, 0, tptc2, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
+ { }
+};
+
+void __init da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
+{
+ struct clk_onecell_data *clk_data;
+
+ clk_data = davinci_psc_register_clocks(psc0, da850_psc0_info, 16);
+ if (!clk_data)
+ return;
+
+ clk_register_clkdev(clk_data->clks[3], NULL, "ti-aemif");
+ clk_register_clkdev(clk_data->clks[3], "aemif", "davinci-nand.0");
+ clk_register_clkdev(clk_data->clks[4], NULL, "spi_davinci.0");
+ clk_register_clkdev(clk_data->clks[5], NULL, "da830-mmc.0");
+ clk_register_clkdev(clk_data->clks[9], NULL, "serial8250.0");
+ clk_register_clkdev(clk_data->clks[14], "arm", NULL);
+ clk_register_clkdev(clk_data->clks[15], NULL, "davinci-rproc.0");
+
+ clk_free_onecell_data(clk_data);
+
+ clk_data = davinci_psc_register_clocks(psc1, da850_psc1_info, 32);
+ if (!clk_data)
+ return;
+
+ clk_register_clkdev(clk_data->clks[1], "usb20_psc_clk", NULL);
+ clk_register_clkdev(clk_data->clks[1], NULL, "musb-da8xx");
+ clk_register_clkdev(clk_data->clks[1], NULL, "cppi41-dmaengine");
+ clk_register_clkdev(clk_data->clks[2], NULL, "ohci-da8xx");
+ clk_register_clkdev(clk_data->clks[3], "gpio", NULL);
+ clk_register_clkdev(clk_data->clks[5], NULL, "davinci_emac.1");
+ clk_register_clkdev(clk_data->clks[5], "fck", "davinci_mdio.0");
+ clk_register_clkdev(clk_data->clks[7], NULL, "davinci-mcasp.0");
+ clk_register_clkdev(clk_data->clks[8], "fck", "ahci_da850");
+ clk_register_clkdev(clk_data->clks[9], NULL, "vpif");
+ clk_register_clkdev(clk_data->clks[10], NULL, "spi_davinci.1");
+ clk_register_clkdev(clk_data->clks[11], NULL, "i2c_davinci.2");
+ clk_register_clkdev(clk_data->clks[12], NULL, "serial8250.1");
+ clk_register_clkdev(clk_data->clks[13], NULL, "serial8250.2");
+ clk_register_clkdev(clk_data->clks[14], NULL, "davinci-mcbsp.0");
+ clk_register_clkdev(clk_data->clks[15], NULL, "davinci-mcbsp.1");
+ clk_register_clkdev(clk_data->clks[16], "fck", "da8xx_lcdc.0");
+ clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.0");
+ clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.1");
+ clk_register_clkdev(clk_data->clks[18], NULL, "da830-mmc.1");
+ clk_register_clkdev(clk_data->clks[20], "fck", "ecap.0");
+ clk_register_clkdev(clk_data->clks[20], "fck", "ecap.1");
+ clk_register_clkdev(clk_data->clks[20], "fck", "ecap.2");
+
+ clk_free_onecell_data(clk_data);
+}
+
+#ifdef CONFIG_OF
+static void __init of_da850_psc0_clk_init(struct device_node *node)
+{
+ of_davinci_psc_clk_init(node, da850_psc0_info, 16);
+}
+CLK_OF_DECLARE(da850_psc0_clk, "ti,da850-psc0", of_da850_psc0_clk_init);
+
+static void __init of_da850_psc1_clk_init(struct device_node *node)
+{
+ of_davinci_psc_clk_init(node, da850_psc1_info, 32);
+}
+CLK_OF_DECLARE(da850_psc1_clk, "ti,da850-psc1", of_da850_psc1_clk_init);
+#endif
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index 3ec8100..3d8bdfa 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -17,5 +17,6 @@ void dm644x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
void dm646x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
void da830_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
+void da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 121+ messages in thread
[parent not found: <1515377863-20358-13-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>]
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
[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
0 siblings, 1 reply; 121+ messages in thread
From: Sekhar Nori @ 2018-01-16 14:00 UTC (permalink / raw)
To: David Lechner, linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel-u79uwXL29TY76Z2rM5mHXA
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> +void __init da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
> +{
> + struct clk_onecell_data *clk_data;
> +
> + clk_data = davinci_psc_register_clocks(psc0, da850_psc0_info, 16);
> + if (!clk_data)
> + return;
> +
> + clk_register_clkdev(clk_data->clks[3], NULL, "ti-aemif");
> + clk_register_clkdev(clk_data->clks[3], "aemif", "davinci-nand.0");
> + clk_register_clkdev(clk_data->clks[4], NULL, "spi_davinci.0");
> + clk_register_clkdev(clk_data->clks[5], NULL, "da830-mmc.0");
> + clk_register_clkdev(clk_data->clks[9], NULL, "serial8250.0");
> + clk_register_clkdev(clk_data->clks[14], "arm", NULL);
> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-rproc.0");
> +
> + clk_free_onecell_data(clk_data);
> +
> + clk_data = davinci_psc_register_clocks(psc1, da850_psc1_info, 32);
> + if (!clk_data)
> + return;
> +
> + clk_register_clkdev(clk_data->clks[1], "usb20_psc_clk", NULL);
Is this con_id really needed now? Searching for "usb20_psc_clk" in your
tree results in only this one hit.
> + clk_register_clkdev(clk_data->clks[1], NULL, "musb-da8xx");
> + clk_register_clkdev(clk_data->clks[1], NULL, "cppi41-dmaengine");
I guess multiple dev_id matches like these are another hurdle in moving
them to davinci_psc_clk_info[] table? If its too cumbersome to keep
multiple entries in the table, they can be handled as an exception at
the end of processing the table? Still they are not the norm so I hope
the normal case will still benefit.
> + clk_register_clkdev(clk_data->clks[2], NULL, "ohci-da8xx");
> + clk_register_clkdev(clk_data->clks[3], "gpio", NULL);
> + clk_register_clkdev(clk_data->clks[5], NULL, "davinci_emac.1");
> + clk_register_clkdev(clk_data->clks[5], "fck", "davinci_mdio.0");
> + clk_register_clkdev(clk_data->clks[7], NULL, "davinci-mcasp.0");
> + clk_register_clkdev(clk_data->clks[8], "fck", "ahci_da850");
> + clk_register_clkdev(clk_data->clks[9], NULL, "vpif");
> + clk_register_clkdev(clk_data->clks[10], NULL, "spi_davinci.1");
> + clk_register_clkdev(clk_data->clks[11], NULL, "i2c_davinci.2");
> + clk_register_clkdev(clk_data->clks[12], NULL, "serial8250.1");
> + clk_register_clkdev(clk_data->clks[13], NULL, "serial8250.2");
> + clk_register_clkdev(clk_data->clks[14], NULL, "davinci-mcbsp.0");
> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-mcbsp.1");
> + clk_register_clkdev(clk_data->clks[16], "fck", "da8xx_lcdc.0");
> + clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.0");
> + clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.1");
> + clk_register_clkdev(clk_data->clks[18], NULL, "da830-mmc.1");
> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.0");
> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.1");
> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.2");
> +
> + clk_free_onecell_data(clk_data);
> +}
Thanks,
Sekhar
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-01-16 14:00 ` Sekhar Nori
@ 2018-01-16 17:21 ` David Lechner
2018-01-17 11:57 ` Sekhar Nori
0 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-16 17:21 UTC (permalink / raw)
To: Sekhar Nori, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On 01/16/2018 08:00 AM, Sekhar Nori wrote:
> On Monday 08 January 2018 07:47 AM, David Lechner wrote:
>> +void __init da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
>> +{
>> + struct clk_onecell_data *clk_data;
>> +
>> + clk_data = davinci_psc_register_clocks(psc0, da850_psc0_info, 16);
>> + if (!clk_data)
>> + return;
>> +
>> + clk_register_clkdev(clk_data->clks[3], NULL, "ti-aemif");
>> + clk_register_clkdev(clk_data->clks[3], "aemif", "davinci-nand.0");
>> + clk_register_clkdev(clk_data->clks[4], NULL, "spi_davinci.0");
>> + clk_register_clkdev(clk_data->clks[5], NULL, "da830-mmc.0");
>> + clk_register_clkdev(clk_data->clks[9], NULL, "serial8250.0");
>> + clk_register_clkdev(clk_data->clks[14], "arm", NULL);
>> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-rproc.0");
>> +
>> + clk_free_onecell_data(clk_data);
>> +
>> + clk_data = davinci_psc_register_clocks(psc1, da850_psc1_info, 32);
>> + if (!clk_data)
>> + return;
>> +
>> + clk_register_clkdev(clk_data->clks[1], "usb20_psc_clk", NULL);
>
> Is this con_id really needed now? Searching for "usb20_psc_clk" in your
> tree results in only this one hit.
Yes, this is left over from previous attempts.
>
>> + clk_register_clkdev(clk_data->clks[1], NULL, "musb-da8xx");
>> + clk_register_clkdev(clk_data->clks[1], NULL, "cppi41-dmaengine");
>
> I guess multiple dev_id matches like these are another hurdle in moving
> them to davinci_psc_clk_info[] table? If its too cumbersome to keep
> multiple entries in the table, they can be handled as an exception at
> the end of processing the table? Still they are not the norm so I hope
> the normal case will still benefit.
Right, as I mentioned in the reply to the previous patch, instead of
assigning a con_id and dev_id to each clock, we would need to assign
an array with a list of clocks. I think that would work better than
trying to handle the extras as an exception since there, on average,
about 5 per SoC.
>
>> + clk_register_clkdev(clk_data->clks[2], NULL, "ohci-da8xx");
>> + clk_register_clkdev(clk_data->clks[3], "gpio", NULL);
>> + clk_register_clkdev(clk_data->clks[5], NULL, "davinci_emac.1");
>> + clk_register_clkdev(clk_data->clks[5], "fck", "davinci_mdio.0");
>> + clk_register_clkdev(clk_data->clks[7], NULL, "davinci-mcasp.0");
>> + clk_register_clkdev(clk_data->clks[8], "fck", "ahci_da850");
>> + clk_register_clkdev(clk_data->clks[9], NULL, "vpif");
>> + clk_register_clkdev(clk_data->clks[10], NULL, "spi_davinci.1");
>> + clk_register_clkdev(clk_data->clks[11], NULL, "i2c_davinci.2");
>> + clk_register_clkdev(clk_data->clks[12], NULL, "serial8250.1");
>> + clk_register_clkdev(clk_data->clks[13], NULL, "serial8250.2");
>> + clk_register_clkdev(clk_data->clks[14], NULL, "davinci-mcbsp.0");
>> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-mcbsp.1");
>> + clk_register_clkdev(clk_data->clks[16], "fck", "da8xx_lcdc.0");
>> + clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.0");
>> + clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.1");
>> + clk_register_clkdev(clk_data->clks[18], NULL, "da830-mmc.1");
>> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.0");
>> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.1");
>> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.2");
>> +
>> + clk_free_onecell_data(clk_data);
>> +}
>
> Thanks,
> Sekhar
>
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
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
0 siblings, 2 replies; 121+ messages in thread
From: Sekhar Nori @ 2018-01-17 11:57 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On Tuesday 16 January 2018 10:51 PM, David Lechner wrote:
> On 01/16/2018 08:00 AM, Sekhar Nori wrote:
>> On Monday 08 January 2018 07:47 AM, David Lechner wrote:
>>> +void __init da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
>>> +{
>>> + struct clk_onecell_data *clk_data;
>>> +
>>> + clk_data = davinci_psc_register_clocks(psc0, da850_psc0_info, 16);
>>> + if (!clk_data)
>>> + return;
>>> +
>>> + clk_register_clkdev(clk_data->clks[3], NULL, "ti-aemif");
>>> + clk_register_clkdev(clk_data->clks[3], "aemif", "davinci-nand.0");
>>> + clk_register_clkdev(clk_data->clks[4], NULL, "spi_davinci.0");
>>> + clk_register_clkdev(clk_data->clks[5], NULL, "da830-mmc.0");
>>> + clk_register_clkdev(clk_data->clks[9], NULL, "serial8250.0");
>>> + clk_register_clkdev(clk_data->clks[14], "arm", NULL);
>>> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-rproc.0");
>>> +
>>> + clk_free_onecell_data(clk_data);
>>> +
>>> + clk_data = davinci_psc_register_clocks(psc1, da850_psc1_info, 32);
>>> + if (!clk_data)
>>> + return;
>>> +
>>> + clk_register_clkdev(clk_data->clks[1], "usb20_psc_clk", NULL);
>>
>> Is this con_id really needed now? Searching for "usb20_psc_clk" in your
>> tree results in only this one hit.
>
> Yes, this is left over from previous attempts.
>
>>
>>> + clk_register_clkdev(clk_data->clks[1], NULL, "musb-da8xx");
>>> + clk_register_clkdev(clk_data->clks[1], NULL, "cppi41-dmaengine");
>>
>> I guess multiple dev_id matches like these are another hurdle in moving
>> them to davinci_psc_clk_info[] table? If its too cumbersome to keep
>> multiple entries in the table, they can be handled as an exception at
>> the end of processing the table? Still they are not the norm so I hope
>> the normal case will still benefit.
>
> Right, as I mentioned in the reply to the previous patch, instead of
> assigning a con_id and dev_id to each clock, we would need to assign
> an array with a list of clocks. I think that would work better than
> trying to handle the extras as an exception since there, on average,
> about 5 per SoC.
Okay, are you going to try this to see how it looks? It looks like
samsung (clk-s3c2410.c) and tegra (clk-tegra20.c) use such tables
(although both use separate tables mapping just the gate number to
con_id/dev_id).
Others like u8540_clk.c and clk-mmp2.c have multiple calls in code to
clk_register_clkdev() like you have, but they keep them right after the
gate clock registration which makes it easy to see the mapping.
clk-imx35.c has multiple clk_register_clkdev() calls, but uses an enum
for the gates so its easy to see the mapping. This approach looks fine
to me as well.
So looks like there is a whole gamut of ways people have approached
this. But I do think we need to change the scheme you have currently
since it is difficult to review and audit (believe me on this one :))
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-01-17 11:57 ` Sekhar Nori
@ 2018-01-17 17:33 ` David Lechner
2018-01-17 19:08 ` David Lechner
1 sibling, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-01-17 17:33 UTC (permalink / raw)
To: Sekhar Nori, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On 01/17/2018 05:57 AM, Sekhar Nori wrote:
> On Tuesday 16 January 2018 10:51 PM, David Lechner wrote:
>> On 01/16/2018 08:00 AM, Sekhar Nori wrote:
>>> On Monday 08 January 2018 07:47 AM, David Lechner wrote:
>>>> +void __init da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
>>>> +{
>>>> + struct clk_onecell_data *clk_data;
>>>> +
>>>> + clk_data = davinci_psc_register_clocks(psc0, da850_psc0_info, 16);
>>>> + if (!clk_data)
>>>> + return;
>>>> +
>>>> + clk_register_clkdev(clk_data->clks[3], NULL, "ti-aemif");
>>>> + clk_register_clkdev(clk_data->clks[3], "aemif", "davinci-nand.0");
>>>> + clk_register_clkdev(clk_data->clks[4], NULL, "spi_davinci.0");
>>>> + clk_register_clkdev(clk_data->clks[5], NULL, "da830-mmc.0");
>>>> + clk_register_clkdev(clk_data->clks[9], NULL, "serial8250.0");
>>>> + clk_register_clkdev(clk_data->clks[14], "arm", NULL);
>>>> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-rproc.0");
>>>> +
>>>> + clk_free_onecell_data(clk_data);
>>>> +
>>>> + clk_data = davinci_psc_register_clocks(psc1, da850_psc1_info, 32);
>>>> + if (!clk_data)
>>>> + return;
>>>> +
>>>> + clk_register_clkdev(clk_data->clks[1], "usb20_psc_clk", NULL);
>>>
>>> Is this con_id really needed now? Searching for "usb20_psc_clk" in your
>>> tree results in only this one hit.
>>
>> Yes, this is left over from previous attempts.
>>
>>>
>>>> + clk_register_clkdev(clk_data->clks[1], NULL, "musb-da8xx");
>>>> + clk_register_clkdev(clk_data->clks[1], NULL, "cppi41-dmaengine");
>>>
>>> I guess multiple dev_id matches like these are another hurdle in moving
>>> them to davinci_psc_clk_info[] table? If its too cumbersome to keep
>>> multiple entries in the table, they can be handled as an exception at
>>> the end of processing the table? Still they are not the norm so I hope
>>> the normal case will still benefit.
>>
>> Right, as I mentioned in the reply to the previous patch, instead of
>> assigning a con_id and dev_id to each clock, we would need to assign
>> an array with a list of clocks. I think that would work better than
>> trying to handle the extras as an exception since there, on average,
>> about 5 per SoC.
>
> Okay, are you going to try this to see how it looks? It looks like
> samsung (clk-s3c2410.c) and tegra (clk-tegra20.c) use such tables
> (although both use separate tables mapping just the gate number to
> con_id/dev_id).
>
> Others like u8540_clk.c and clk-mmp2.c have multiple calls in code to
> clk_register_clkdev() like you have, but they keep them right after the
> gate clock registration which makes it easy to see the mapping.
>
> clk-imx35.c has multiple clk_register_clkdev() calls, but uses an enum
> for the gates so its easy to see the mapping. This approach looks fine
> to me as well.
>
> So looks like there is a whole gamut of ways people have approached
> this. But I do think we need to change the scheme you have currently
> since it is difficult to review and audit (believe me on this one :))
>
OK, I'll figure out something here.
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
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
1 sibling, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-17 19:08 UTC (permalink / raw)
To: Sekhar Nori, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On 01/17/2018 05:57 AM, Sekhar Nori wrote:
> On Tuesday 16 January 2018 10:51 PM, David Lechner wrote:
>> On 01/16/2018 08:00 AM, Sekhar Nori wrote:
>>> On Monday 08 January 2018 07:47 AM, David Lechner wrote:
>>>> +void __init da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
>>>> +{
>>>> + struct clk_onecell_data *clk_data;
>>>> +
>>>> + clk_data = davinci_psc_register_clocks(psc0, da850_psc0_info, 16);
>>>> + if (!clk_data)
>>>> + return;
>>>> +
>>>> + clk_register_clkdev(clk_data->clks[3], NULL, "ti-aemif");
>>>> + clk_register_clkdev(clk_data->clks[3], "aemif", "davinci-nand.0");
>>>> + clk_register_clkdev(clk_data->clks[4], NULL, "spi_davinci.0");
>>>> + clk_register_clkdev(clk_data->clks[5], NULL, "da830-mmc.0");
>>>> + clk_register_clkdev(clk_data->clks[9], NULL, "serial8250.0");
>>>> + clk_register_clkdev(clk_data->clks[14], "arm", NULL);
>>>> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-rproc.0");
>>>> +
>>>> + clk_free_onecell_data(clk_data);
>>>> +
>>>> + clk_data = davinci_psc_register_clocks(psc1, da850_psc1_info, 32);
>>>> + if (!clk_data)
>>>> + return;
>>>> +
>>>> + clk_register_clkdev(clk_data->clks[1], "usb20_psc_clk", NULL);
>>>
>>> Is this con_id really needed now? Searching for "usb20_psc_clk" in your
>>> tree results in only this one hit.
>>
>> Yes, this is left over from previous attempts.
>>
>>>
>>>> + clk_register_clkdev(clk_data->clks[1], NULL, "musb-da8xx");
>>>> + clk_register_clkdev(clk_data->clks[1], NULL, "cppi41-dmaengine");
>>>
>>> I guess multiple dev_id matches like these are another hurdle in moving
>>> them to davinci_psc_clk_info[] table? If its too cumbersome to keep
>>> multiple entries in the table, they can be handled as an exception at
>>> the end of processing the table? Still they are not the norm so I hope
>>> the normal case will still benefit.
>>
>> Right, as I mentioned in the reply to the previous patch, instead of
>> assigning a con_id and dev_id to each clock, we would need to assign
>> an array with a list of clocks. I think that would work better than
>> trying to handle the extras as an exception since there, on average,
>> about 5 per SoC.
>
> Okay, are you going to try this to see how it looks?
It is looking like this:
static const struct davinci_psc_clkdev_info emfia_clkdev[] __initconst = {
LPSC_CLKDEV(NULL, "ti-aemif"),
LPSC_CLKDEV("aemif", "davinci-nand.0"),
{ }
};
static const struct davinci_psc_clkdev_info spi0_clkdev[] __initconst = {
LPSC_CLKDEV(NULL, "spi_davinci.0"),
{ }
};
static const struct davinci_psc_clkdev_info mmcsd0_clkdev[] __initconst = {
LPSC_CLKDEV(NULL, "da830-mmc.0"),
{ }
};
static const struct davinci_psc_clkdev_info uart0_clkdev[] __initconst = {
LPSC_CLKDEV(NULL, "serial8250.0"),
{ }
};
static const struct davinci_psc_clkdev_info arm_clkdev[] __initconst = {
/*
* REVISIT: cpufreq-davinci should be modified to use dev_id and drop
* use of con_id.
*/
LPSC_CLKDEV("arm", NULL),
{ }
};
static const struct davinci_psc_clkdev_info dsp_clkdev[] __initconst = {
LPSC_CLKDEV(NULL, "davinci-rproc.0"),
{ }
};
static const struct davinci_psc_clk_info da850_psc0_info[] __initconst = {
LPSC(0, 0, tpcc0, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
LPSC(1, 0, tptc0, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
LPSC(2, 0, tptc1, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
LPSC(3, 0, emifa, async1, emfia_clkdev, 0),
LPSC(4, 0, spi0, pll0_sysclk2, spi0_clkdev, 0),
LPSC(5, 0, mmcsd0, pll0_sysclk2, mmcsd0_clkdev, 0),
LPSC(6, 0, aintc, pll0_sysclk4, NULL, LPSC_ALWAYS_ENABLED),
LPSC(7, 0, arm_rom, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
LPSC(9, 0, uart0, pll0_sysclk2, uart0_clkdev, 0),
LPSC(13, 0, pruss, pll0_sysclk2, NULL, 0),
LPSC(14, 0, arm, pll0_sysclk6, arm_clkdev, LPSC_ALWAYS_ENABLED |
LPSC_ARM_RATE),
LPSC(15, 1, dsp, pll0_sysclk1, dsp_clkdev, LPSC_FORCE |
LPSC_LOCAL_RESET),
{ }
};
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-01-17 19:08 ` David Lechner
@ 2018-01-18 6:37 ` Sekhar Nori
0 siblings, 0 replies; 121+ messages in thread
From: Sekhar Nori @ 2018-01-18 6:37 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On Thursday 18 January 2018 12:38 AM, David Lechner wrote:
> It is looking like this:
>
>
> static const struct davinci_psc_clkdev_info emfia_clkdev[] __initconst = {
> LPSC_CLKDEV(NULL, "ti-aemif"),
> LPSC_CLKDEV("aemif", "davinci-nand.0"),
> { }
> };
>
> static const struct davinci_psc_clkdev_info spi0_clkdev[] __initconst = {
> LPSC_CLKDEV(NULL, "spi_davinci.0"),
> { }
> };
>
> static const struct davinci_psc_clkdev_info mmcsd0_clkdev[] __initconst = {
> LPSC_CLKDEV(NULL, "da830-mmc.0"),
> { }
> };
>
> static const struct davinci_psc_clkdev_info uart0_clkdev[] __initconst = {
> LPSC_CLKDEV(NULL, "serial8250.0"),
> { }
> };
>
> static const struct davinci_psc_clkdev_info arm_clkdev[] __initconst = {
> /*
> * REVISIT: cpufreq-davinci should be modified to use dev_id and drop
> * use of con_id.
> */
> LPSC_CLKDEV("arm", NULL),
> { }
> };
>
> static const struct davinci_psc_clkdev_info dsp_clkdev[] __initconst = {
> LPSC_CLKDEV(NULL, "davinci-rproc.0"),
> { }
> };
>
> static const struct davinci_psc_clk_info da850_psc0_info[] __initconst = {
> LPSC(0, 0, tpcc0, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
> LPSC(1, 0, tptc0, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
> LPSC(2, 0, tptc1, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
> LPSC(3, 0, emifa, async1, emfia_clkdev, 0),
> LPSC(4, 0, spi0, pll0_sysclk2, spi0_clkdev, 0),
> LPSC(5, 0, mmcsd0, pll0_sysclk2, mmcsd0_clkdev, 0),
> LPSC(6, 0, aintc, pll0_sysclk4, NULL, LPSC_ALWAYS_ENABLED),
> LPSC(7, 0, arm_rom, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
> LPSC(9, 0, uart0, pll0_sysclk2, uart0_clkdev, 0),
> LPSC(13, 0, pruss, pll0_sysclk2, NULL, 0),
> LPSC(14, 0, arm, pll0_sysclk6, arm_clkdev, LPSC_ALWAYS_ENABLED |
> LPSC_ARM_RATE),
> LPSC(15, 1, dsp, pll0_sysclk1, dsp_clkdev, LPSC_FORCE |
> LPSC_LOCAL_RESET),
> { }
> };
This looks good to me!
Regards,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
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-02-09 16:22 ` Bartosz Golaszewski
2018-02-09 16:48 ` Michael Turquette
1 sibling, 1 reply; 121+ messages in thread
From: Bartosz Golaszewski @ 2018-02-09 16:22 UTC (permalink / raw)
To: David Lechner
Cc: linux-clk, devicetree, Linux ARM, Michael Turquette,
Stephen Boyd, Rob Herring, Mark Rutland, Sekhar Nori,
Kevin Hilman, Adam Ford, Linux Kernel Mailing List
2018-01-08 3:17 GMT+01:00 David Lechner <david@lechnology.com>:
> This adds platform-specific declarations for the PSC clocks on TI DA850/
> OMAP-L138/AM18XX SoCs.
>
> Signed-off-by: David Lechner <david@lechnology.com>
> ---
> drivers/clk/davinci/Makefile | 1 +
> drivers/clk/davinci/psc-da850.c | 117 ++++++++++++++++++++++++++++++++++++++++
> include/linux/clk/davinci.h | 1 +
> 3 files changed, 119 insertions(+)
> create mode 100644 drivers/clk/davinci/psc-da850.c
>
> diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
> index fb14c8c..aef0390 100644
> --- a/drivers/clk/davinci/Makefile
> +++ b/drivers/clk/davinci/Makefile
> @@ -11,4 +11,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
>
> obj-y += psc.o
> obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
> +obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
> endif
> diff --git a/drivers/clk/davinci/psc-da850.c b/drivers/clk/davinci/psc-da850.c
> new file mode 100644
> index 0000000..3b4583d
> --- /dev/null
> +++ b/drivers/clk/davinci/psc-da850.c
> @@ -0,0 +1,117 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PSC clock descriptions for TI DA850/OMAP-L138/AM18XX
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>
> +#include <linux/init.h>
> +#include <linux/of.h>
> +#include <linux/types.h>
> +
> +#include "psc.h"
> +
> +static const struct davinci_psc_clk_info da850_psc0_info[] __initconst = {
> + LPSC(0, 0, tpcc0, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
> + LPSC(1, 0, tptc0, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
> + LPSC(2, 0, tptc1, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
> + LPSC(3, 0, aemif, pll0_sysclk3, 0),
> + LPSC(4, 0, spi0, pll0_sysclk2, 0),
> + LPSC(5, 0, mmcsd0, pll0_sysclk2, 0),
> + LPSC(6, 0, aintc, pll0_sysclk4, LPSC_ALWAYS_ENABLED),
> + LPSC(7, 0, arm_rom, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
> + LPSC(9, 0, uart0, pll0_sysclk2, 0),
> + LPSC(13, 0, pruss, pll0_sysclk2, 0),
> + LPSC(14, 0, arm, pll0_sysclk6, LPSC_ALWAYS_ENABLED),
> + LPSC(15, 1, dsp, pll0_sysclk1, LPSC_FORCE | LPSC_LOCAL_RESET),
> + { }
> +};
> +
> +static const struct davinci_psc_clk_info da850_psc1_info[] __initconst = {
> + LPSC(0, 0, tpcc1, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
> + LPSC(1, 0, usb0, pll0_sysclk2, 0),
> + LPSC(2, 0, usb1, pll0_sysclk4, 0),
> + LPSC(3, 0, gpio, pll0_sysclk4, 0),
> + LPSC(5, 0, emac, pll0_sysclk4, 0),
> + LPSC(6, 0, emif3, pll0_sysclk5, LPSC_ALWAYS_ENABLED),
> + LPSC(7, 0, mcasp0, async3, 0),
> + LPSC(8, 0, sata, pll0_sysclk2, LPSC_FORCE),
> + LPSC(9, 0, vpif, pll0_sysclk2, 0),
> + LPSC(10, 0, spi1, async3, 0),
> + LPSC(11, 0, i2c1, pll0_sysclk4, 0),
> + LPSC(12, 0, uart1, async3, 0),
> + LPSC(13, 0, uart2, async3, 0),
> + LPSC(14, 0, mcbsp0, async3, 0),
> + LPSC(15, 0, mcbsp1, async3, 0),
> + LPSC(16, 0, lcdc, pll0_sysclk2, 0),
> + LPSC(17, 0, ehrpwm, async3, 0),
> + LPSC(18, 0, mmcsd1, pll0_sysclk2, 0),
> + LPSC(20, 0, ecap, async3, 0),
> + LPSC(21, 0, tptc2, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
> + { }
> +};
> +
> +void __init da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
> +{
> + struct clk_onecell_data *clk_data;
> +
> + clk_data = davinci_psc_register_clocks(psc0, da850_psc0_info, 16);
> + if (!clk_data)
> + return;
> +
> + clk_register_clkdev(clk_data->clks[3], NULL, "ti-aemif");
> + clk_register_clkdev(clk_data->clks[3], "aemif", "davinci-nand.0");
> + clk_register_clkdev(clk_data->clks[4], NULL, "spi_davinci.0");
> + clk_register_clkdev(clk_data->clks[5], NULL, "da830-mmc.0");
> + clk_register_clkdev(clk_data->clks[9], NULL, "serial8250.0");
> + clk_register_clkdev(clk_data->clks[14], "arm", NULL);
> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-rproc.0");
> +
> + clk_free_onecell_data(clk_data);
> +
> + clk_data = davinci_psc_register_clocks(psc1, da850_psc1_info, 32);
> + if (!clk_data)
> + return;
> +
> + clk_register_clkdev(clk_data->clks[1], "usb20_psc_clk", NULL);
> + clk_register_clkdev(clk_data->clks[1], NULL, "musb-da8xx");
> + clk_register_clkdev(clk_data->clks[1], NULL, "cppi41-dmaengine");
> + clk_register_clkdev(clk_data->clks[2], NULL, "ohci-da8xx");
> + clk_register_clkdev(clk_data->clks[3], "gpio", NULL);
> + clk_register_clkdev(clk_data->clks[5], NULL, "davinci_emac.1");
> + clk_register_clkdev(clk_data->clks[5], "fck", "davinci_mdio.0");
> + clk_register_clkdev(clk_data->clks[7], NULL, "davinci-mcasp.0");
> + clk_register_clkdev(clk_data->clks[8], "fck", "ahci_da850");
> + clk_register_clkdev(clk_data->clks[9], NULL, "vpif");
> + clk_register_clkdev(clk_data->clks[10], NULL, "spi_davinci.1");
> + clk_register_clkdev(clk_data->clks[11], NULL, "i2c_davinci.2");
> + clk_register_clkdev(clk_data->clks[12], NULL, "serial8250.1");
> + clk_register_clkdev(clk_data->clks[13], NULL, "serial8250.2");
> + clk_register_clkdev(clk_data->clks[14], NULL, "davinci-mcbsp.0");
> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-mcbsp.1");
> + clk_register_clkdev(clk_data->clks[16], "fck", "da8xx_lcdc.0");
> + clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.0");
> + clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.1");
> + clk_register_clkdev(clk_data->clks[18], NULL, "da830-mmc.1");
> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.0");
> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.1");
> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.2");
> +
> + clk_free_onecell_data(clk_data);
> +}
> +
> +#ifdef CONFIG_OF
> +static void __init of_da850_psc0_clk_init(struct device_node *node)
> +{
> + of_davinci_psc_clk_init(node, da850_psc0_info, 16);
> +}
> +CLK_OF_DECLARE(da850_psc0_clk, "ti,da850-psc0", of_da850_psc0_clk_init);
> +
> +static void __init of_da850_psc1_clk_init(struct device_node *node)
> +{
> + of_davinci_psc_clk_init(node, da850_psc1_info, 32);
> +}
> +CLK_OF_DECLARE(da850_psc1_clk, "ti,da850-psc1", of_da850_psc1_clk_init);
> +#endif
> diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
> index 3ec8100..3d8bdfa 100644
> --- a/include/linux/clk/davinci.h
> +++ b/include/linux/clk/davinci.h
> @@ -17,5 +17,6 @@ void dm644x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
> void dm646x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
>
> void da830_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
> +void da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
>
> #endif /* __LINUX_CLK_DAVINCI_H__ */
> --
> 2.7.4
>
Hi David,
I've been working on moving the genpd code from its own driver to the
psc one. I couldn't get the system to boot though and problems
happened very early in the boot sequence. I struggled to figure out
what's happening, but eventually I noticed that psc uses
CLK_OF_DECLARE() to initialize clocks. The functions registered this
way are called very early in the boot sequence, way before
late_initcall() in which the genpd framework is initialized. This of
course makes it impossible to register genpd at the same time we
register PSCs.
Mike, Stephen - it would be great if you could confirm, but I believe
the clock framework now only accepts clock drivers which create real
platform drivers, in which case this series would need to be modified.
David: FYI I quickly converted the functions in psc-da850.c to actual
probe callbacks and it worked just fine on a da850-lcdk board.
Best regards,
Bartosz Golaszewski
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
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
0 siblings, 2 replies; 121+ messages in thread
From: Michael Turquette @ 2018-02-09 16:48 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: David Lechner, linux-clk, devicetree, Linux ARM, Stephen Boyd,
Rob Herring, Mark Rutland, Sekhar Nori, Kevin Hilman, Adam Ford,
Linux Kernel Mailing List
Hi Bartosz, all,
On Fri, Feb 9, 2018 at 8:22 AM, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> 2018-01-08 3:17 GMT+01:00 David Lechner <david@lechnology.com>:
>> This adds platform-specific declarations for the PSC clocks on TI DA850/
>> OMAP-L138/AM18XX SoCs.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
>> ---
>> drivers/clk/davinci/Makefile | 1 +
>> drivers/clk/davinci/psc-da850.c | 117 ++++++++++++++++++++++++++++++++++++++++
>> include/linux/clk/davinci.h | 1 +
>> 3 files changed, 119 insertions(+)
>> create mode 100644 drivers/clk/davinci/psc-da850.c
>>
>> diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
>> index fb14c8c..aef0390 100644
>> --- a/drivers/clk/davinci/Makefile
>> +++ b/drivers/clk/davinci/Makefile
>> @@ -11,4 +11,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
>>
>> obj-y += psc.o
>> obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
>> +obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
>> endif
>> diff --git a/drivers/clk/davinci/psc-da850.c b/drivers/clk/davinci/psc-da850.c
>> new file mode 100644
>> index 0000000..3b4583d
>> --- /dev/null
>> +++ b/drivers/clk/davinci/psc-da850.c
>> @@ -0,0 +1,117 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * PSC clock descriptions for TI DA850/OMAP-L138/AM18XX
>> + *
>> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/clkdev.h>
>> +#include <linux/init.h>
>> +#include <linux/of.h>
>> +#include <linux/types.h>
>> +
>> +#include "psc.h"
>> +
>> +static const struct davinci_psc_clk_info da850_psc0_info[] __initconst = {
>> + LPSC(0, 0, tpcc0, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>> + LPSC(1, 0, tptc0, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>> + LPSC(2, 0, tptc1, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>> + LPSC(3, 0, aemif, pll0_sysclk3, 0),
>> + LPSC(4, 0, spi0, pll0_sysclk2, 0),
>> + LPSC(5, 0, mmcsd0, pll0_sysclk2, 0),
>> + LPSC(6, 0, aintc, pll0_sysclk4, LPSC_ALWAYS_ENABLED),
>> + LPSC(7, 0, arm_rom, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>> + LPSC(9, 0, uart0, pll0_sysclk2, 0),
>> + LPSC(13, 0, pruss, pll0_sysclk2, 0),
>> + LPSC(14, 0, arm, pll0_sysclk6, LPSC_ALWAYS_ENABLED),
>> + LPSC(15, 1, dsp, pll0_sysclk1, LPSC_FORCE | LPSC_LOCAL_RESET),
>> + { }
>> +};
>> +
>> +static const struct davinci_psc_clk_info da850_psc1_info[] __initconst = {
>> + LPSC(0, 0, tpcc1, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>> + LPSC(1, 0, usb0, pll0_sysclk2, 0),
>> + LPSC(2, 0, usb1, pll0_sysclk4, 0),
>> + LPSC(3, 0, gpio, pll0_sysclk4, 0),
>> + LPSC(5, 0, emac, pll0_sysclk4, 0),
>> + LPSC(6, 0, emif3, pll0_sysclk5, LPSC_ALWAYS_ENABLED),
>> + LPSC(7, 0, mcasp0, async3, 0),
>> + LPSC(8, 0, sata, pll0_sysclk2, LPSC_FORCE),
>> + LPSC(9, 0, vpif, pll0_sysclk2, 0),
>> + LPSC(10, 0, spi1, async3, 0),
>> + LPSC(11, 0, i2c1, pll0_sysclk4, 0),
>> + LPSC(12, 0, uart1, async3, 0),
>> + LPSC(13, 0, uart2, async3, 0),
>> + LPSC(14, 0, mcbsp0, async3, 0),
>> + LPSC(15, 0, mcbsp1, async3, 0),
>> + LPSC(16, 0, lcdc, pll0_sysclk2, 0),
>> + LPSC(17, 0, ehrpwm, async3, 0),
>> + LPSC(18, 0, mmcsd1, pll0_sysclk2, 0),
>> + LPSC(20, 0, ecap, async3, 0),
>> + LPSC(21, 0, tptc2, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>> + { }
>> +};
>> +
>> +void __init da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
>> +{
>> + struct clk_onecell_data *clk_data;
>> +
>> + clk_data = davinci_psc_register_clocks(psc0, da850_psc0_info, 16);
>> + if (!clk_data)
>> + return;
>> +
>> + clk_register_clkdev(clk_data->clks[3], NULL, "ti-aemif");
>> + clk_register_clkdev(clk_data->clks[3], "aemif", "davinci-nand.0");
>> + clk_register_clkdev(clk_data->clks[4], NULL, "spi_davinci.0");
>> + clk_register_clkdev(clk_data->clks[5], NULL, "da830-mmc.0");
>> + clk_register_clkdev(clk_data->clks[9], NULL, "serial8250.0");
>> + clk_register_clkdev(clk_data->clks[14], "arm", NULL);
>> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-rproc.0");
>> +
>> + clk_free_onecell_data(clk_data);
>> +
>> + clk_data = davinci_psc_register_clocks(psc1, da850_psc1_info, 32);
>> + if (!clk_data)
>> + return;
>> +
>> + clk_register_clkdev(clk_data->clks[1], "usb20_psc_clk", NULL);
>> + clk_register_clkdev(clk_data->clks[1], NULL, "musb-da8xx");
>> + clk_register_clkdev(clk_data->clks[1], NULL, "cppi41-dmaengine");
>> + clk_register_clkdev(clk_data->clks[2], NULL, "ohci-da8xx");
>> + clk_register_clkdev(clk_data->clks[3], "gpio", NULL);
>> + clk_register_clkdev(clk_data->clks[5], NULL, "davinci_emac.1");
>> + clk_register_clkdev(clk_data->clks[5], "fck", "davinci_mdio.0");
>> + clk_register_clkdev(clk_data->clks[7], NULL, "davinci-mcasp.0");
>> + clk_register_clkdev(clk_data->clks[8], "fck", "ahci_da850");
>> + clk_register_clkdev(clk_data->clks[9], NULL, "vpif");
>> + clk_register_clkdev(clk_data->clks[10], NULL, "spi_davinci.1");
>> + clk_register_clkdev(clk_data->clks[11], NULL, "i2c_davinci.2");
>> + clk_register_clkdev(clk_data->clks[12], NULL, "serial8250.1");
>> + clk_register_clkdev(clk_data->clks[13], NULL, "serial8250.2");
>> + clk_register_clkdev(clk_data->clks[14], NULL, "davinci-mcbsp.0");
>> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-mcbsp.1");
>> + clk_register_clkdev(clk_data->clks[16], "fck", "da8xx_lcdc.0");
>> + clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.0");
>> + clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.1");
>> + clk_register_clkdev(clk_data->clks[18], NULL, "da830-mmc.1");
>> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.0");
>> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.1");
>> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.2");
>> +
>> + clk_free_onecell_data(clk_data);
>> +}
>> +
>> +#ifdef CONFIG_OF
>> +static void __init of_da850_psc0_clk_init(struct device_node *node)
>> +{
>> + of_davinci_psc_clk_init(node, da850_psc0_info, 16);
>> +}
>> +CLK_OF_DECLARE(da850_psc0_clk, "ti,da850-psc0", of_da850_psc0_clk_init);
>> +
>> +static void __init of_da850_psc1_clk_init(struct device_node *node)
>> +{
>> + of_davinci_psc_clk_init(node, da850_psc1_info, 32);
>> +}
>> +CLK_OF_DECLARE(da850_psc1_clk, "ti,da850-psc1", of_da850_psc1_clk_init);
>> +#endif
>> diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
>> index 3ec8100..3d8bdfa 100644
>> --- a/include/linux/clk/davinci.h
>> +++ b/include/linux/clk/davinci.h
>> @@ -17,5 +17,6 @@ void dm644x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
>> void dm646x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
>>
>> void da830_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
>> +void da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
>>
>> #endif /* __LINUX_CLK_DAVINCI_H__ */
>> --
>> 2.7.4
>>
>
> Hi David,
>
> I've been working on moving the genpd code from its own driver to the
> psc one. I couldn't get the system to boot though and problems
> happened very early in the boot sequence. I struggled to figure out
> what's happening, but eventually I noticed that psc uses
> CLK_OF_DECLARE() to initialize clocks. The functions registered this
> way are called very early in the boot sequence, way before
> late_initcall() in which the genpd framework is initialized. This of
> course makes it impossible to register genpd at the same time we
> register PSCs.
>
> Mike, Stephen - it would be great if you could confirm, but I believe
> the clock framework now only accepts clock drivers which create real
> platform drivers, in which case this series would need to be modified.
You are correct. All new uses of CLK_OF_DECLARE are met with high
suspicion, and all new drivers should be platform drivers.
There are cases when CLK_OF_DECLARE is necessary (sometimes
temporarily while things are reworked), but it seems this is not the
case for this driver based on your testing of the platform driver
approach. Please use the platform driver approach instead.
Thanks,
Mike
>
> David: FYI I quickly converted the functions in psc-da850.c to actual
> probe callbacks and it worked just fine on a da850-lcdk board.
>
> Best regards,
> Bartosz Golaszewski
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-02-09 16:48 ` Michael Turquette
@ 2018-02-12 3:03 ` David Lechner
2018-04-05 13:09 ` Sekhar Nori
1 sibling, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-02-12 3:03 UTC (permalink / raw)
To: Michael Turquette, Bartosz Golaszewski
Cc: linux-clk, devicetree, Linux ARM, Stephen Boyd, Rob Herring,
Mark Rutland, Sekhar Nori, Kevin Hilman, Adam Ford,
Linux Kernel Mailing List
On 02/09/2018 10:48 AM, Michael Turquette wrote:
> Hi Bartosz, all,
>
> On Fri, Feb 9, 2018 at 8:22 AM, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>> 2018-01-08 3:17 GMT+01:00 David Lechner <david@lechnology.com>:
>>> This adds platform-specific declarations for the PSC clocks on TI DA850/
>>> OMAP-L138/AM18XX SoCs.
>>>
>>> Signed-off-by: David Lechner <david@lechnology.com>
>>> ---
>>> drivers/clk/davinci/Makefile | 1 +
>>> drivers/clk/davinci/psc-da850.c | 117 ++++++++++++++++++++++++++++++++++++++++
>>> include/linux/clk/davinci.h | 1 +
>>> 3 files changed, 119 insertions(+)
>>> create mode 100644 drivers/clk/davinci/psc-da850.c
>>>
>>> diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
>>> index fb14c8c..aef0390 100644
>>> --- a/drivers/clk/davinci/Makefile
>>> +++ b/drivers/clk/davinci/Makefile
>>> @@ -11,4 +11,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
>>>
>>> obj-y += psc.o
>>> obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
>>> +obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
>>> endif
>>> diff --git a/drivers/clk/davinci/psc-da850.c b/drivers/clk/davinci/psc-da850.c
>>> new file mode 100644
>>> index 0000000..3b4583d
>>> --- /dev/null
>>> +++ b/drivers/clk/davinci/psc-da850.c
>>> @@ -0,0 +1,117 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * PSC clock descriptions for TI DA850/OMAP-L138/AM18XX
>>> + *
>>> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
>>> + */
>>> +
>>> +#include <linux/clk-provider.h>
>>> +#include <linux/clkdev.h>
>>> +#include <linux/init.h>
>>> +#include <linux/of.h>
>>> +#include <linux/types.h>
>>> +
>>> +#include "psc.h"
>>> +
>>> +static const struct davinci_psc_clk_info da850_psc0_info[] __initconst = {
>>> + LPSC(0, 0, tpcc0, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>>> + LPSC(1, 0, tptc0, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>>> + LPSC(2, 0, tptc1, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>>> + LPSC(3, 0, aemif, pll0_sysclk3, 0),
>>> + LPSC(4, 0, spi0, pll0_sysclk2, 0),
>>> + LPSC(5, 0, mmcsd0, pll0_sysclk2, 0),
>>> + LPSC(6, 0, aintc, pll0_sysclk4, LPSC_ALWAYS_ENABLED),
>>> + LPSC(7, 0, arm_rom, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>>> + LPSC(9, 0, uart0, pll0_sysclk2, 0),
>>> + LPSC(13, 0, pruss, pll0_sysclk2, 0),
>>> + LPSC(14, 0, arm, pll0_sysclk6, LPSC_ALWAYS_ENABLED),
>>> + LPSC(15, 1, dsp, pll0_sysclk1, LPSC_FORCE | LPSC_LOCAL_RESET),
>>> + { }
>>> +};
>>> +
>>> +static const struct davinci_psc_clk_info da850_psc1_info[] __initconst = {
>>> + LPSC(0, 0, tpcc1, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>>> + LPSC(1, 0, usb0, pll0_sysclk2, 0),
>>> + LPSC(2, 0, usb1, pll0_sysclk4, 0),
>>> + LPSC(3, 0, gpio, pll0_sysclk4, 0),
>>> + LPSC(5, 0, emac, pll0_sysclk4, 0),
>>> + LPSC(6, 0, emif3, pll0_sysclk5, LPSC_ALWAYS_ENABLED),
>>> + LPSC(7, 0, mcasp0, async3, 0),
>>> + LPSC(8, 0, sata, pll0_sysclk2, LPSC_FORCE),
>>> + LPSC(9, 0, vpif, pll0_sysclk2, 0),
>>> + LPSC(10, 0, spi1, async3, 0),
>>> + LPSC(11, 0, i2c1, pll0_sysclk4, 0),
>>> + LPSC(12, 0, uart1, async3, 0),
>>> + LPSC(13, 0, uart2, async3, 0),
>>> + LPSC(14, 0, mcbsp0, async3, 0),
>>> + LPSC(15, 0, mcbsp1, async3, 0),
>>> + LPSC(16, 0, lcdc, pll0_sysclk2, 0),
>>> + LPSC(17, 0, ehrpwm, async3, 0),
>>> + LPSC(18, 0, mmcsd1, pll0_sysclk2, 0),
>>> + LPSC(20, 0, ecap, async3, 0),
>>> + LPSC(21, 0, tptc2, pll0_sysclk2, LPSC_ALWAYS_ENABLED),
>>> + { }
>>> +};
>>> +
>>> +void __init da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
>>> +{
>>> + struct clk_onecell_data *clk_data;
>>> +
>>> + clk_data = davinci_psc_register_clocks(psc0, da850_psc0_info, 16);
>>> + if (!clk_data)
>>> + return;
>>> +
>>> + clk_register_clkdev(clk_data->clks[3], NULL, "ti-aemif");
>>> + clk_register_clkdev(clk_data->clks[3], "aemif", "davinci-nand.0");
>>> + clk_register_clkdev(clk_data->clks[4], NULL, "spi_davinci.0");
>>> + clk_register_clkdev(clk_data->clks[5], NULL, "da830-mmc.0");
>>> + clk_register_clkdev(clk_data->clks[9], NULL, "serial8250.0");
>>> + clk_register_clkdev(clk_data->clks[14], "arm", NULL);
>>> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-rproc.0");
>>> +
>>> + clk_free_onecell_data(clk_data);
>>> +
>>> + clk_data = davinci_psc_register_clocks(psc1, da850_psc1_info, 32);
>>> + if (!clk_data)
>>> + return;
>>> +
>>> + clk_register_clkdev(clk_data->clks[1], "usb20_psc_clk", NULL);
>>> + clk_register_clkdev(clk_data->clks[1], NULL, "musb-da8xx");
>>> + clk_register_clkdev(clk_data->clks[1], NULL, "cppi41-dmaengine");
>>> + clk_register_clkdev(clk_data->clks[2], NULL, "ohci-da8xx");
>>> + clk_register_clkdev(clk_data->clks[3], "gpio", NULL);
>>> + clk_register_clkdev(clk_data->clks[5], NULL, "davinci_emac.1");
>>> + clk_register_clkdev(clk_data->clks[5], "fck", "davinci_mdio.0");
>>> + clk_register_clkdev(clk_data->clks[7], NULL, "davinci-mcasp.0");
>>> + clk_register_clkdev(clk_data->clks[8], "fck", "ahci_da850");
>>> + clk_register_clkdev(clk_data->clks[9], NULL, "vpif");
>>> + clk_register_clkdev(clk_data->clks[10], NULL, "spi_davinci.1");
>>> + clk_register_clkdev(clk_data->clks[11], NULL, "i2c_davinci.2");
>>> + clk_register_clkdev(clk_data->clks[12], NULL, "serial8250.1");
>>> + clk_register_clkdev(clk_data->clks[13], NULL, "serial8250.2");
>>> + clk_register_clkdev(clk_data->clks[14], NULL, "davinci-mcbsp.0");
>>> + clk_register_clkdev(clk_data->clks[15], NULL, "davinci-mcbsp.1");
>>> + clk_register_clkdev(clk_data->clks[16], "fck", "da8xx_lcdc.0");
>>> + clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.0");
>>> + clk_register_clkdev(clk_data->clks[17], "fck", "ehrpwm.1");
>>> + clk_register_clkdev(clk_data->clks[18], NULL, "da830-mmc.1");
>>> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.0");
>>> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.1");
>>> + clk_register_clkdev(clk_data->clks[20], "fck", "ecap.2");
>>> +
>>> + clk_free_onecell_data(clk_data);
>>> +}
>>> +
>>> +#ifdef CONFIG_OF
>>> +static void __init of_da850_psc0_clk_init(struct device_node *node)
>>> +{
>>> + of_davinci_psc_clk_init(node, da850_psc0_info, 16);
>>> +}
>>> +CLK_OF_DECLARE(da850_psc0_clk, "ti,da850-psc0", of_da850_psc0_clk_init);
>>> +
>>> +static void __init of_da850_psc1_clk_init(struct device_node *node)
>>> +{
>>> + of_davinci_psc_clk_init(node, da850_psc1_info, 32);
>>> +}
>>> +CLK_OF_DECLARE(da850_psc1_clk, "ti,da850-psc1", of_da850_psc1_clk_init);
>>> +#endif
>>> diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
>>> index 3ec8100..3d8bdfa 100644
>>> --- a/include/linux/clk/davinci.h
>>> +++ b/include/linux/clk/davinci.h
>>> @@ -17,5 +17,6 @@ void dm644x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
>>> void dm646x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
>>>
>>> void da830_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
>>> +void da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
>>>
>>> #endif /* __LINUX_CLK_DAVINCI_H__ */
>>> --
>>> 2.7.4
>>>
>>
>> Hi David,
>>
>> I've been working on moving the genpd code from its own driver to the
>> psc one. I couldn't get the system to boot though and problems
>> happened very early in the boot sequence. I struggled to figure out
>> what's happening, but eventually I noticed that psc uses
>> CLK_OF_DECLARE() to initialize clocks. The functions registered this
>> way are called very early in the boot sequence, way before
>> late_initcall() in which the genpd framework is initialized. This of
>> course makes it impossible to register genpd at the same time we
>> register PSCs.
>>
>> Mike, Stephen - it would be great if you could confirm, but I believe
>> the clock framework now only accepts clock drivers which create real
>> platform drivers, in which case this series would need to be modified.
>
> You are correct. All new uses of CLK_OF_DECLARE are met with high
> suspicion, and all new drivers should be platform drivers.
Oh boy. I'll try to get a v7 out this week with these changes.
>
> There are cases when CLK_OF_DECLARE is necessary (sometimes
> temporarily while things are reworked), but it seems this is not the
> case for this driver based on your testing of the platform driver
> approach. Please use the platform driver approach instead.
>
> Thanks,
> Mike
>
>>
>> David: FYI I quickly converted the functions in psc-da850.c to actual
>> probe callbacks and it worked just fine on a da850-lcdk board.
>>
>> Best regards,
>> Bartosz Golaszewski
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
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
1 sibling, 1 reply; 121+ messages in thread
From: Sekhar Nori @ 2018-04-05 13:09 UTC (permalink / raw)
To: Michael Turquette, Bartosz Golaszewski
Cc: David Lechner, linux-clk, devicetree, Linux ARM, Stephen Boyd,
Rob Herring, Mark Rutland, Kevin Hilman, Adam Ford,
Linux Kernel Mailing List
Hi Bartosz,
On Friday 09 February 2018 10:18 PM, Michael Turquette wrote:
> On Fri, Feb 9, 2018 at 8:22 AM, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>> 2018-01-08 3:17 GMT+01:00 David Lechner <david@lechnology.com>:
>> Hi David,
>>
>> I've been working on moving the genpd code from its own driver to the
>> psc one. I couldn't get the system to boot though and problems
>> happened very early in the boot sequence. I struggled to figure out
>> what's happening, but eventually I noticed that psc uses
>> CLK_OF_DECLARE() to initialize clocks. The functions registered this
>> way are called very early in the boot sequence, way before
>> late_initcall() in which the genpd framework is initialized. This of
late_initcall() is too late for genpd to be initialized. As you may have
seen with the latest set of patches, we have problems with timer
initialization. After converting to platform devices, PSC and PLL clocks
get initialized post time_init(). We are working that around using
fixed-clocks, which hopefully will work (I still need to test many of
the affected platforms).
Can you please reply with the exact issue you faced with genpd framework
initialization so we do have that on record.
Thanks,
Sekhar
>> course makes it impossible to register genpd at the same time we
>> register PSCs.
>>
>> Mike, Stephen - it would be great if you could confirm, but I believe
>> the clock framework now only accepts clock drivers which create real
>> platform drivers, in which case this series would need to be modified.
>
> You are correct. All new uses of CLK_OF_DECLARE are met with high
> suspicion, and all new drivers should be platform drivers.
>
> There are cases when CLK_OF_DECLARE is necessary (sometimes
> temporarily while things are reworked), but it seems this is not the
> case for this driver based on your testing of the platform driver
> approach. Please use the platform driver approach instead.
>
> Thanks,
> Mike
>
>>
>> David: FYI I quickly converted the functions in psc-da850.c to actual
>> probe callbacks and it worked just fine on a da850-lcdk board.
>>
>> Best regards,
>> Bartosz Golaszewski
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-04-05 13:09 ` Sekhar Nori
@ 2018-04-05 13:44 ` Bartosz Golaszewski
2018-04-05 14:36 ` Sekhar Nori
0 siblings, 1 reply; 121+ messages in thread
From: Bartosz Golaszewski @ 2018-04-05 13:44 UTC (permalink / raw)
To: Sekhar Nori
Cc: Michael Turquette, David Lechner, linux-clk, devicetree,
Linux ARM, Stephen Boyd, Rob Herring, Mark Rutland, Kevin Hilman,
Adam Ford, Linux Kernel Mailing List
2018-04-05 15:09 GMT+02:00 Sekhar Nori <nsekhar@ti.com>:
> Hi Bartosz,
>
> On Friday 09 February 2018 10:18 PM, Michael Turquette wrote:
>> On Fri, Feb 9, 2018 at 8:22 AM, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>> 2018-01-08 3:17 GMT+01:00 David Lechner <david@lechnology.com>:
>
>>> Hi David,
>>>
>>> I've been working on moving the genpd code from its own driver to the
>>> psc one. I couldn't get the system to boot though and problems
>>> happened very early in the boot sequence. I struggled to figure out
>>> what's happening, but eventually I noticed that psc uses
>>> CLK_OF_DECLARE() to initialize clocks. The functions registered this
>>> way are called very early in the boot sequence, way before
>>> late_initcall() in which the genpd framework is initialized. This of
>
> late_initcall() is too late for genpd to be initialized. As you may have
> seen with the latest set of patches, we have problems with timer
> initialization. After converting to platform devices, PSC and PLL clocks
> get initialized post time_init(). We are working that around using
> fixed-clocks, which hopefully will work (I still need to test many of
> the affected platforms).
>
> Can you please reply with the exact issue you faced with genpd framework
> initialization so we do have that on record.
>
The exact issue manifested itself in a NULL-pointer dereference panic
when I tried moving the genpd code I had initially implemented as a
separate platform driver to what I believe was v6 or v7 of David's
series (before the psc driver became a platform driver, when it was
still using CLK_OF_DECLARE()). When I had tested a simple conversion
of that version to a platform_driver, genpd worked fine.
I don't have the stack traces from these panics, but I recall some
debugfs functions being involved and the genpd late_initcalls are
related to debugfs. Looking at it now I don't see how exactly it could
fail though.
Best regards,
Bartosz
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
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
0 siblings, 2 replies; 121+ messages in thread
From: Sekhar Nori @ 2018-04-05 14:36 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Mark Rutland, devicetree, David Lechner, Kevin Hilman,
Michael Turquette, Stephen Boyd, Linux Kernel Mailing List,
Rob Herring, Adam Ford, linux-clk, Linux ARM
On Thursday 05 April 2018 07:14 PM, Bartosz Golaszewski wrote:
> 2018-04-05 15:09 GMT+02:00 Sekhar Nori <nsekhar@ti.com>:
>> Hi Bartosz,
>>
>> On Friday 09 February 2018 10:18 PM, Michael Turquette wrote:
>>> On Fri, Feb 9, 2018 at 8:22 AM, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>>> 2018-01-08 3:17 GMT+01:00 David Lechner <david@lechnology.com>:
>>
>>>> Hi David,
>>>>
>>>> I've been working on moving the genpd code from its own driver to the
>>>> psc one. I couldn't get the system to boot though and problems
>>>> happened very early in the boot sequence. I struggled to figure out
>>>> what's happening, but eventually I noticed that psc uses
>>>> CLK_OF_DECLARE() to initialize clocks. The functions registered this
>>>> way are called very early in the boot sequence, way before
>>>> late_initcall() in which the genpd framework is initialized. This of
>>
>> late_initcall() is too late for genpd to be initialized. As you may have
>> seen with the latest set of patches, we have problems with timer
>> initialization. After converting to platform devices, PSC and PLL clocks
>> get initialized post time_init(). We are working that around using
>> fixed-clocks, which hopefully will work (I still need to test many of
>> the affected platforms).
>>
>> Can you please reply with the exact issue you faced with genpd framework
>> initialization so we do have that on record.
>>
>
> The exact issue manifested itself in a NULL-pointer dereference panic
> when I tried moving the genpd code I had initially implemented as a
> separate platform driver to what I believe was v6 or v7 of David's
> series (before the psc driver became a platform driver, when it was
> still using CLK_OF_DECLARE()). When I had tested a simple conversion
> of that version to a platform_driver, genpd worked fine.
>
> I don't have the stack traces from these panics, but I recall some
> debugfs functions being involved and the genpd late_initcalls are
> related to debugfs. Looking at it now I don't see how exactly it could
> fail though.
Do you have the code where you faced the problem stashed somewhere? I am
not (yet) advocating going back to CLK_OF_DECLARE(). But there is a
definite issue with timer being ready when not using CLK_OF_DECLARE().
So, I want to make sure there the reason why we are going down the
platform device path is a amply clear.
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-04-05 14:36 ` Sekhar Nori
@ 2018-04-05 15:37 ` David Lechner
2018-04-05 15:51 ` Bartosz Golaszewski
1 sibling, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-04-05 15:37 UTC (permalink / raw)
To: Sekhar Nori, Bartosz Golaszewski
Cc: Michael Turquette, linux-clk, devicetree, Linux ARM,
Stephen Boyd, Rob Herring, Mark Rutland, Kevin Hilman, Adam Ford,
Linux Kernel Mailing List
On 04/05/2018 09:36 AM, Sekhar Nori wrote:
> On Thursday 05 April 2018 07:14 PM, Bartosz Golaszewski wrote:
>> 2018-04-05 15:09 GMT+02:00 Sekhar Nori <nsekhar@ti.com>:
>>> Hi Bartosz,
>>>
>>> On Friday 09 February 2018 10:18 PM, Michael Turquette wrote:
>>>> On Fri, Feb 9, 2018 at 8:22 AM, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>>>> 2018-01-08 3:17 GMT+01:00 David Lechner <david@lechnology.com>:
>>>
>>>>> Hi David,
>>>>>
>>>>> I've been working on moving the genpd code from its own driver to the
>>>>> psc one. I couldn't get the system to boot though and problems
>>>>> happened very early in the boot sequence. I struggled to figure out
>>>>> what's happening, but eventually I noticed that psc uses
>>>>> CLK_OF_DECLARE() to initialize clocks. The functions registered this
>>>>> way are called very early in the boot sequence, way before
>>>>> late_initcall() in which the genpd framework is initialized. This of
>>>
>>> late_initcall() is too late for genpd to be initialized. As you may have
>>> seen with the latest set of patches, we have problems with timer
>>> initialization. After converting to platform devices, PSC and PLL clocks
>>> get initialized post time_init(). We are working that around using
>>> fixed-clocks, which hopefully will work (I still need to test many of
>>> the affected platforms).
>>>
>>> Can you please reply with the exact issue you faced with genpd framework
>>> initialization so we do have that on record.
>>>
>>
>> The exact issue manifested itself in a NULL-pointer dereference panic
>> when I tried moving the genpd code I had initially implemented as a
>> separate platform driver to what I believe was v6 or v7 of David's
>> series (before the psc driver became a platform driver, when it was
>> still using CLK_OF_DECLARE()). When I had tested a simple conversion
>> of that version to a platform_driver, genpd worked fine.
>>
>> I don't have the stack traces from these panics, but I recall some
>> debugfs functions being involved and the genpd late_initcalls are
>> related to debugfs. Looking at it now I don't see how exactly it could
>> fail though.
>
> Do you have the code where you faced the problem stashed somewhere? I am
> not (yet) advocating going back to CLK_OF_DECLARE(). But there is a
> definite issue with timer being ready when not using CLK_OF_DECLARE().
> So, I want to make sure there the reason why we are going down the
> platform device path is a amply clear.
>
> Thanks,
> Sekhar
>
This is the thread that led to the conversion to platform devices:
https://lkml.org/lkml/2018/2/9/541
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
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
1 sibling, 1 reply; 121+ messages in thread
From: Bartosz Golaszewski @ 2018-04-05 15:51 UTC (permalink / raw)
To: Sekhar Nori
Cc: Michael Turquette, David Lechner, linux-clk, devicetree,
Linux ARM, Stephen Boyd, Rob Herring, Mark Rutland, Kevin Hilman,
Adam Ford, Linux Kernel Mailing List
2018-04-05 16:36 GMT+02:00 Sekhar Nori <nsekhar@ti.com>:
> On Thursday 05 April 2018 07:14 PM, Bartosz Golaszewski wrote:
>> 2018-04-05 15:09 GMT+02:00 Sekhar Nori <nsekhar@ti.com>:
>>> Hi Bartosz,
>>>
>>> On Friday 09 February 2018 10:18 PM, Michael Turquette wrote:
>>>> On Fri, Feb 9, 2018 at 8:22 AM, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>>>> 2018-01-08 3:17 GMT+01:00 David Lechner <david@lechnology.com>:
>>>
>>>>> Hi David,
>>>>>
>>>>> I've been working on moving the genpd code from its own driver to the
>>>>> psc one. I couldn't get the system to boot though and problems
>>>>> happened very early in the boot sequence. I struggled to figure out
>>>>> what's happening, but eventually I noticed that psc uses
>>>>> CLK_OF_DECLARE() to initialize clocks. The functions registered this
>>>>> way are called very early in the boot sequence, way before
>>>>> late_initcall() in which the genpd framework is initialized. This of
>>>
>>> late_initcall() is too late for genpd to be initialized. As you may have
>>> seen with the latest set of patches, we have problems with timer
>>> initialization. After converting to platform devices, PSC and PLL clocks
>>> get initialized post time_init(). We are working that around using
>>> fixed-clocks, which hopefully will work (I still need to test many of
>>> the affected platforms).
>>>
>>> Can you please reply with the exact issue you faced with genpd framework
>>> initialization so we do have that on record.
>>>
>>
>> The exact issue manifested itself in a NULL-pointer dereference panic
>> when I tried moving the genpd code I had initially implemented as a
>> separate platform driver to what I believe was v6 or v7 of David's
>> series (before the psc driver became a platform driver, when it was
>> still using CLK_OF_DECLARE()). When I had tested a simple conversion
>> of that version to a platform_driver, genpd worked fine.
>>
>> I don't have the stack traces from these panics, but I recall some
>> debugfs functions being involved and the genpd late_initcalls are
>> related to debugfs. Looking at it now I don't see how exactly it could
>> fail though.
>
> Do you have the code where you faced the problem stashed somewhere? I am
> not (yet) advocating going back to CLK_OF_DECLARE(). But there is a
> definite issue with timer being ready when not using CLK_OF_DECLARE().
> So, I want to make sure there the reason why we are going down the
> platform device path is a amply clear.
>
> Thanks,
> Sekhar
Yes, you can still find it on my github[1].
Bart
[1] github.com:brgl/linux.git topic/davinci-genpd-final-v2
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-04-05 15:51 ` Bartosz Golaszewski
@ 2018-04-06 9:37 ` Sekhar Nori
2018-04-06 16:46 ` Stephen Boyd
0 siblings, 1 reply; 121+ messages in thread
From: Sekhar Nori @ 2018-04-06 9:37 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Michael Turquette, David Lechner, linux-clk, devicetree,
Linux ARM, Stephen Boyd, Rob Herring, Mark Rutland, Kevin Hilman,
Adam Ford, Linux Kernel Mailing List
Hi Bart,
On Thursday 05 April 2018 09:21 PM, Bartosz Golaszewski wrote:
> 2018-04-05 16:36 GMT+02:00 Sekhar Nori <nsekhar@ti.com>:
>> On Thursday 05 April 2018 07:14 PM, Bartosz Golaszewski wrote:
>>> 2018-04-05 15:09 GMT+02:00 Sekhar Nori <nsekhar@ti.com>:
>>>> Hi Bartosz,
>>>>
>>>> On Friday 09 February 2018 10:18 PM, Michael Turquette wrote:
>>>>> On Fri, Feb 9, 2018 at 8:22 AM, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>>>>> 2018-01-08 3:17 GMT+01:00 David Lechner <david@lechnology.com>:
>>>>
>>>>>> Hi David,
>>>>>>
>>>>>> I've been working on moving the genpd code from its own driver to the
>>>>>> psc one. I couldn't get the system to boot though and problems
>>>>>> happened very early in the boot sequence. I struggled to figure out
>>>>>> what's happening, but eventually I noticed that psc uses
>>>>>> CLK_OF_DECLARE() to initialize clocks. The functions registered this
>>>>>> way are called very early in the boot sequence, way before
>>>>>> late_initcall() in which the genpd framework is initialized. This of
>>>>
>>>> late_initcall() is too late for genpd to be initialized. As you may have
>>>> seen with the latest set of patches, we have problems with timer
>>>> initialization. After converting to platform devices, PSC and PLL clocks
>>>> get initialized post time_init(). We are working that around using
>>>> fixed-clocks, which hopefully will work (I still need to test many of
>>>> the affected platforms).
>>>>
>>>> Can you please reply with the exact issue you faced with genpd framework
>>>> initialization so we do have that on record.
>>>>
>>>
>>> The exact issue manifested itself in a NULL-pointer dereference panic
>>> when I tried moving the genpd code I had initially implemented as a
>>> separate platform driver to what I believe was v6 or v7 of David's
>>> series (before the psc driver became a platform driver, when it was
>>> still using CLK_OF_DECLARE()). When I had tested a simple conversion
>>> of that version to a platform_driver, genpd worked fine.
>>>
>>> I don't have the stack traces from these panics, but I recall some
>>> debugfs functions being involved and the genpd late_initcalls are
>>> related to debugfs. Looking at it now I don't see how exactly it could
>>> fail though.
>>
>> Do you have the code where you faced the problem stashed somewhere? I am
>> not (yet) advocating going back to CLK_OF_DECLARE(). But there is a
>> definite issue with timer being ready when not using CLK_OF_DECLARE().
>> So, I want to make sure there the reason why we are going down the
>> platform device path is a amply clear.
>>
>> Thanks,
>> Sekhar
>
> Yes, you can still find it on my github[1].
>
> Bart
>
> [1] github.com:brgl/linux.git topic/davinci-genpd-final-v2
The panic issue in your branch is not related to genpd. Its because you
are accessing platform bus before it is initialized. The attached[1]
patch on top of your branch made it boot again.
With your branch booting, I can see genpd related debugfs entries
getting created. I don't see devices being attached to the domains you
have though. I did not debug that. I suspect some matching issue.
Can you please check that and confirm there is no issue with genpd and
using CLK_OF_DECLARE() to initialize clocks?
Unless you report an issue back, or Mike and Stephen have ideas about
how to handle the dependency between PSC/PLL derived timer clock
initialization and and timer_probe(), I think we need to move back to
using CLK_OF_DECLARE().
Thanks,
Sekhar
---8<---
diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c
index 9d9f94eee544..7e3d114efdac 100644
--- a/drivers/clk/davinci/psc.c
+++ b/drivers/clk/davinci/psc.c
@@ -281,12 +281,18 @@ int __davinci_psc_register_clocks(const struct davinci_psc_clk_info *info,
}
}
- DO_ONCE(pm_clk_add_notifier,
- &platform_bus_type, &platform_bus_notifier);
-
return 0;
}
+static int __init davinci_pm_runtime_init(void)
+{
+ pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
+
+ return 0;
+}
+core_initcall(davinci_pm_runtime_init);
+
int davinci_psc_register_clocks(const struct davinci_psc_clk_info *info,
void __iomem *base)
{
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-04-06 9:37 ` Sekhar Nori
@ 2018-04-06 16:46 ` Stephen Boyd
2018-04-23 14:59 ` David Lechner
0 siblings, 1 reply; 121+ messages in thread
From: Stephen Boyd @ 2018-04-06 16:46 UTC (permalink / raw)
To: Bartosz Golaszewski, Sekhar Nori
Cc: Michael Turquette, David Lechner, linux-clk, devicetree,
Linux ARM, Stephen Boyd, Rob Herring, Mark Rutland, Kevin Hilman,
Adam Ford, Linux Kernel Mailing List
Quoting Sekhar Nori (2018-04-06 02:37:03)
>
> Can you please check that and confirm there is no issue with genpd and
> using CLK_OF_DECLARE() to initialize clocks?
>
> Unless you report an issue back, or Mike and Stephen have ideas about
> how to handle the dependency between PSC/PLL derived timer clock
> initialization and and timer_probe(), I think we need to move back to
> using CLK_OF_DECLARE().
In such a case, please use the hybrid approach where the clks required
for the clockevent and/or clocksource are registered in the early
CLK_OF_DECLARE path but the rest of the clks get registered with a
proper platform device and driver. There are examples of this approach
on other platforms already.
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-04-06 16:46 ` Stephen Boyd
@ 2018-04-23 14:59 ` David Lechner
2018-04-24 8:28 ` Sekhar Nori
0 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-04-23 14:59 UTC (permalink / raw)
To: Stephen Boyd, Bartosz Golaszewski, Sekhar Nori
Cc: Michael Turquette, linux-clk, devicetree, Linux ARM,
Stephen Boyd, Rob Herring, Mark Rutland, Kevin Hilman, Adam Ford,
Linux Kernel Mailing List
On 04/06/2018 11:46 AM, Stephen Boyd wrote:
> Quoting Sekhar Nori (2018-04-06 02:37:03)
>>
>> Can you please check that and confirm there is no issue with genpd and
>> using CLK_OF_DECLARE() to initialize clocks?
>>
>> Unless you report an issue back, or Mike and Stephen have ideas about
>> how to handle the dependency between PSC/PLL derived timer clock
>> initialization and and timer_probe(), I think we need to move back to
>> using CLK_OF_DECLARE().
>
> In such a case, please use the hybrid approach where the clks required
> for the clockevent and/or clocksource are registered in the early
> CLK_OF_DECLARE path but the rest of the clks get registered with a
> proper platform device and driver. There are examples of this approach
> on other platforms already.
>
I looked at this a bit last week, but I didn't come up with any approach
that I was happy with. It seems like it would be nice to just register
the absolute minimum clocks needed. On DA8XX, that would just be the PLL0
AUXCLK. On most of the other SoCs, it would be the PLL AUXCLK plus one
LPSC clock. The AUXCLKs are easy because they are just a simple gate
from the oscillator. The LPSC clocks are a bit more tricky because they
have a complex sequence for turning on. Furthermore, on DM646X, we need
the whole PLL up to SYSCLK3 plus one LPSC clock, so things get a bit
messy there.
The other approach I considered was to make the PLL and PSC drivers
work as platform devices or pure clock devices so that when needed,
the whole IP block could be registered in very early init. However,
this approach will pretty much require massive changes to the drivers
to remove all of the uses of devm_, dev_err, etc. so that it works
when dev == NULL.
Any other bright ideas or a preference for one of these two approaches?
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-04-23 14:59 ` David Lechner
@ 2018-04-24 8:28 ` Sekhar Nori
2018-04-24 16:11 ` David Lechner
0 siblings, 1 reply; 121+ messages in thread
From: Sekhar Nori @ 2018-04-24 8:28 UTC (permalink / raw)
To: David Lechner, Stephen Boyd, Bartosz Golaszewski
Cc: Michael Turquette, linux-clk, devicetree, Linux ARM,
Stephen Boyd, Rob Herring, Mark Rutland, Kevin Hilman, Adam Ford,
Linux Kernel Mailing List
On Monday 23 April 2018 08:29 PM, David Lechner wrote:
> On 04/06/2018 11:46 AM, Stephen Boyd wrote:
>> Quoting Sekhar Nori (2018-04-06 02:37:03)
>>>
>>> Can you please check that and confirm there is no issue with genpd and
>>> using CLK_OF_DECLARE() to initialize clocks?
>>>
>>> Unless you report an issue back, or Mike and Stephen have ideas about
>>> how to handle the dependency between PSC/PLL derived timer clock
>>> initialization and and timer_probe(), I think we need to move back to
>>> using CLK_OF_DECLARE().
>>
>> In such a case, please use the hybrid approach where the clks required
>> for the clockevent and/or clocksource are registered in the early
>> CLK_OF_DECLARE path but the rest of the clks get registered with a
>> proper platform device and driver. There are examples of this approach
>> on other platforms already.
>>
>
> I looked at this a bit last week, but I didn't come up with any approach
> that I was happy with. It seems like it would be nice to just register
> the absolute minimum clocks needed. On DA8XX, that would just be the PLL0
> AUXCLK. On most of the other SoCs, it would be the PLL AUXCLK plus one
> LPSC clock. The AUXCLKs are easy because they are just a simple gate
> from the oscillator. The LPSC clocks are a bit more tricky because they
> have a complex sequence for turning on. Furthermore, on DM646X, we need
> the whole PLL up to SYSCLK3 plus one LPSC clock, so things get a bit
> messy there.
Things might change in the context of work being done here by Bartosz
for converting clocks to early platform devices.
But, keeping that development aside for a moment: I think this means the
PLLs and PSCs need to be CLK_OF_DECLARE(). What we can have as platform
devices are clocks that are not in the path to get timer clock working
(like CFGCHIP clocks).
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-04-24 8:28 ` Sekhar Nori
@ 2018-04-24 16:11 ` David Lechner
2018-04-25 6:07 ` Sekhar Nori
0 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-04-24 16:11 UTC (permalink / raw)
To: Sekhar Nori, Stephen Boyd, Bartosz Golaszewski
Cc: Michael Turquette, linux-clk, devicetree, Linux ARM,
Stephen Boyd, Rob Herring, Mark Rutland, Kevin Hilman, Adam Ford,
Linux Kernel Mailing List
On 04/24/2018 03:28 AM, Sekhar Nori wrote:
> On Monday 23 April 2018 08:29 PM, David Lechner wrote:
>> On 04/06/2018 11:46 AM, Stephen Boyd wrote:
>>> Quoting Sekhar Nori (2018-04-06 02:37:03)
>>>>
>>>> Can you please check that and confirm there is no issue with genpd and
>>>> using CLK_OF_DECLARE() to initialize clocks?
>>>>
>>>> Unless you report an issue back, or Mike and Stephen have ideas about
>>>> how to handle the dependency between PSC/PLL derived timer clock
>>>> initialization and and timer_probe(), I think we need to move back to
>>>> using CLK_OF_DECLARE().
>>>
>>> In such a case, please use the hybrid approach where the clks required
>>> for the clockevent and/or clocksource are registered in the early
>>> CLK_OF_DECLARE path but the rest of the clks get registered with a
>>> proper platform device and driver. There are examples of this approach
>>> on other platforms already.
>>>
>>
>> I looked at this a bit last week, but I didn't come up with any approach
>> that I was happy with. It seems like it would be nice to just register
>> the absolute minimum clocks needed. On DA8XX, that would just be the PLL0
>> AUXCLK. On most of the other SoCs, it would be the PLL AUXCLK plus one
>> LPSC clock. The AUXCLKs are easy because they are just a simple gate
>> from the oscillator. The LPSC clocks are a bit more tricky because they
>> have a complex sequence for turning on. Furthermore, on DM646X, we need
>> the whole PLL up to SYSCLK3 plus one LPSC clock, so things get a bit
>> messy there.
>
> Things might change in the context of work being done here by Bartosz
> for converting clocks to early platform devices.
>
> But, keeping that development aside for a moment: I think this means the
> PLLs and PSCs need to be CLK_OF_DECLARE(). What we can have as platform
> devices are clocks that are not in the path to get timer clock working
> (like CFGCHIP clocks).
CLK_OF_DECLARE() only matters on DA850. None of the other SoCs use device
tree. And on DA850, the timer0 clock is just the PLL0 AUXCLK, so PSCs can
still be platform devices there. And in fact, one of the PSC clocks on
DA850 depends on async3, which is a CFGCHIP clock, so if we made the PSCs
CLK_OF_DECLARE(), then we also have to make at least the async3 CFGCHIP
clock CLK_OF_DECLARE(). But, like I said, I think that can be avoided by
leaving the PSC clocks as a platform device on DA850 (and DA830).
For everything else, we need the legacy board file equivalent of
CLK_OF_DECLARE(), which is basically what I had here in v5 of the
series.
So, if we want this to keep moving before the if/when of Bartosz's
early platform device stuff, I'm thinking that I will make the PLL
and PSC drivers loadable with or without a platform device and let
each SoC pick which one it should use.
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-04-24 16:11 ` David Lechner
@ 2018-04-25 6:07 ` Sekhar Nori
2018-04-25 10:09 ` Bartosz Golaszewski
0 siblings, 1 reply; 121+ messages in thread
From: Sekhar Nori @ 2018-04-25 6:07 UTC (permalink / raw)
To: David Lechner, Stephen Boyd, Bartosz Golaszewski
Cc: Michael Turquette, linux-clk, devicetree, Linux ARM,
Stephen Boyd, Rob Herring, Mark Rutland, Kevin Hilman, Adam Ford,
Linux Kernel Mailing List
On Tuesday 24 April 2018 09:41 PM, David Lechner wrote:
> On 04/24/2018 03:28 AM, Sekhar Nori wrote:
>> On Monday 23 April 2018 08:29 PM, David Lechner wrote:
>>> On 04/06/2018 11:46 AM, Stephen Boyd wrote:
>>>> Quoting Sekhar Nori (2018-04-06 02:37:03)
>>>>>
>>>>> Can you please check that and confirm there is no issue with genpd and
>>>>> using CLK_OF_DECLARE() to initialize clocks?
>>>>>
>>>>> Unless you report an issue back, or Mike and Stephen have ideas about
>>>>> how to handle the dependency between PSC/PLL derived timer clock
>>>>> initialization and and timer_probe(), I think we need to move back to
>>>>> using CLK_OF_DECLARE().
>>>>
>>>> In such a case, please use the hybrid approach where the clks required
>>>> for the clockevent and/or clocksource are registered in the early
>>>> CLK_OF_DECLARE path but the rest of the clks get registered with a
>>>> proper platform device and driver. There are examples of this approach
>>>> on other platforms already.
>>>>
>>>
>>> I looked at this a bit last week, but I didn't come up with any approach
>>> that I was happy with. It seems like it would be nice to just register
>>> the absolute minimum clocks needed. On DA8XX, that would just be the
>>> PLL0
>>> AUXCLK. On most of the other SoCs, it would be the PLL AUXCLK plus one
>>> LPSC clock. The AUXCLKs are easy because they are just a simple gate
>>> from the oscillator. The LPSC clocks are a bit more tricky because they
>>> have a complex sequence for turning on. Furthermore, on DM646X, we need
>>> the whole PLL up to SYSCLK3 plus one LPSC clock, so things get a bit
>>> messy there.
>>
>> Things might change in the context of work being done here by Bartosz
>> for converting clocks to early platform devices.
>>
>> But, keeping that development aside for a moment: I think this means the
>> PLLs and PSCs need to be CLK_OF_DECLARE(). What we can have as platform
>> devices are clocks that are not in the path to get timer clock working
>> (like CFGCHIP clocks).
>
> CLK_OF_DECLARE() only matters on DA850. None of the other SoCs use device
Thats true today, but lets not make the assumption that none of the
other DaVinci SoCs will gain DT support ever. We don't want churn in CCF
support once someone tries to add DT support for other platforms.
I already have people using DM365 in mainline, for example.
> tree. And on DA850, the timer0 clock is just the PLL0 AUXCLK, so PSCs can> still be platform devices there. And in fact, one of the PSC clocks on
> DA850 depends on async3, which is a CFGCHIP clock, so if we made the PSCs
> CLK_OF_DECLARE(), then we also have to make at least the async3 CFGCHIP
> clock CLK_OF_DECLARE(). But, like I said, I think that can be avoided by
> leaving the PSC clocks as a platform device on DA850 (and DA830).
Okay, I did not realize that there is a dependency between CFGCHIP clk
and PSC too.
> For everything else, we need the legacy board file equivalent of
> CLK_OF_DECLARE(), which is basically what I had here in v5 of the
> series.
Yeah. I did not realize the dependency with timer when platform devices
were suggested. Sorry.
>
> So, if we want this to keep moving before the if/when of Bartosz's
> early platform device stuff, I'm thinking that I will make the PLL
After looking at feedback to Bartosz's series, and the fact that
previous attempts at doing the same thing were rejected, I think there
is benefit in keeping CCF support moving independent Bartosz's work.
Otherwise, we have no chance of getting anything merged for v4.18.
Early initialization of clocks and dependency with timer is a pretty
common theme across SoCs. As and when a better way to support is found,
I am sure DaVinci can be converted over along with rest of the devices.
> and PSC drivers loadable with or without a platform device and let
> each SoC pick which one it should use.
This sounds flexible. We have to see how the patches look. But I would
caution against adding a lot of dead code. If there is no way some of
the clocks will be useful as platform device, I see no point of
supporting them as such just in anticipation.
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-04-25 6:07 ` Sekhar Nori
@ 2018-04-25 10:09 ` Bartosz Golaszewski
2018-04-25 10:26 ` Bartosz Golaszewski
0 siblings, 1 reply; 121+ messages in thread
From: Bartosz Golaszewski @ 2018-04-25 10:09 UTC (permalink / raw)
To: Sekhar Nori
Cc: David Lechner, Stephen Boyd, Michael Turquette, linux-clk,
devicetree, Linux ARM, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, Linux Kernel Mailing List
2018-04-25 8:07 GMT+02:00 Sekhar Nori <nsekhar@ti.com>:
> On Tuesday 24 April 2018 09:41 PM, David Lechner wrote:
>> On 04/24/2018 03:28 AM, Sekhar Nori wrote:
>>> On Monday 23 April 2018 08:29 PM, David Lechner wrote:
>>>> On 04/06/2018 11:46 AM, Stephen Boyd wrote:
>>>>> Quoting Sekhar Nori (2018-04-06 02:37:03)
>>>>>>
>>>>>> Can you please check that and confirm there is no issue with genpd and
>>>>>> using CLK_OF_DECLARE() to initialize clocks?
>>>>>>
>>>>>> Unless you report an issue back, or Mike and Stephen have ideas about
>>>>>> how to handle the dependency between PSC/PLL derived timer clock
>>>>>> initialization and and timer_probe(), I think we need to move back to
>>>>>> using CLK_OF_DECLARE().
>>>>>
>>>>> In such a case, please use the hybrid approach where the clks required
>>>>> for the clockevent and/or clocksource are registered in the early
>>>>> CLK_OF_DECLARE path but the rest of the clks get registered with a
>>>>> proper platform device and driver. There are examples of this approach
>>>>> on other platforms already.
>>>>>
>>>>
>>>> I looked at this a bit last week, but I didn't come up with any approach
>>>> that I was happy with. It seems like it would be nice to just register
>>>> the absolute minimum clocks needed. On DA8XX, that would just be the
>>>> PLL0
>>>> AUXCLK. On most of the other SoCs, it would be the PLL AUXCLK plus one
>>>> LPSC clock. The AUXCLKs are easy because they are just a simple gate
>>>> from the oscillator. The LPSC clocks are a bit more tricky because they
>>>> have a complex sequence for turning on. Furthermore, on DM646X, we need
>>>> the whole PLL up to SYSCLK3 plus one LPSC clock, so things get a bit
>>>> messy there.
>>>
>>> Things might change in the context of work being done here by Bartosz
>>> for converting clocks to early platform devices.
>>>
>>> But, keeping that development aside for a moment: I think this means the
>>> PLLs and PSCs need to be CLK_OF_DECLARE(). What we can have as platform
>>> devices are clocks that are not in the path to get timer clock working
>>> (like CFGCHIP clocks).
>>
>> CLK_OF_DECLARE() only matters on DA850. None of the other SoCs use device
>
> Thats true today, but lets not make the assumption that none of the
> other DaVinci SoCs will gain DT support ever. We don't want churn in CCF
> support once someone tries to add DT support for other platforms.
>
> I already have people using DM365 in mainline, for example.
>
>> tree. And on DA850, the timer0 clock is just the PLL0 AUXCLK, so PSCs can> still be platform devices there. And in fact, one of the PSC clocks on
>> DA850 depends on async3, which is a CFGCHIP clock, so if we made the PSCs
>> CLK_OF_DECLARE(), then we also have to make at least the async3 CFGCHIP
>> clock CLK_OF_DECLARE(). But, like I said, I think that can be avoided by
>> leaving the PSC clocks as a platform device on DA850 (and DA830).
>
> Okay, I did not realize that there is a dependency between CFGCHIP clk
> and PSC too.
>
>> For everything else, we need the legacy board file equivalent of
>> CLK_OF_DECLARE(), which is basically what I had here in v5 of the
>> series.
>
> Yeah. I did not realize the dependency with timer when platform devices
> were suggested. Sorry.
>
>>
>> So, if we want this to keep moving before the if/when of Bartosz's
>> early platform device stuff, I'm thinking that I will make the PLL
>
> After looking at feedback to Bartosz's series, and the fact that
> previous attempts at doing the same thing were rejected, I think there
> is benefit in keeping CCF support moving independent Bartosz's work.
> Otherwise, we have no chance of getting anything merged for v4.18.
>
It's true, that the feedback was not very positive, but I'm still
thinking I can come up with something that would get accepted. Last
time someone came up with the idea, the problem it was supposed to
solve was different (dependencies between devices) and was eventually
fixed with introduction of probe deferral.
This time around we really want these devices probed early. The main
concern was using a device tree compatible. If I can instead just
early probe all devices whose drivers are registered as early without
touching the device tree (as Frank Rowand suggested) then maybe the
response of the community would be better.
Thanks,
Bart
> Early initialization of clocks and dependency with timer is a pretty
> common theme across SoCs. As and when a better way to support is found,
> I am sure DaVinci can be converted over along with rest of the devices.
>
>> and PSC drivers loadable with or without a platform device and let
>> each SoC pick which one it should use.
>
> This sounds flexible. We have to see how the patches look. But I would
> caution against adding a lot of dead code. If there is no way some of
> the clocks will be useful as platform device, I see no point of
> supporting them as such just in anticipation.
>
> Thanks,
> Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 12/44] clk: davinci: Add platform information for TI DA850 PSC
2018-04-25 10:09 ` Bartosz Golaszewski
@ 2018-04-25 10:26 ` Bartosz Golaszewski
0 siblings, 0 replies; 121+ messages in thread
From: Bartosz Golaszewski @ 2018-04-25 10:26 UTC (permalink / raw)
To: Sekhar Nori
Cc: David Lechner, Stephen Boyd, Michael Turquette, linux-clk,
devicetree, Linux ARM, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, Linux Kernel Mailing List
2018-04-25 12:09 GMT+02:00 Bartosz Golaszewski <brgl@bgdev.pl>:
> 2018-04-25 8:07 GMT+02:00 Sekhar Nori <nsekhar@ti.com>:
>> On Tuesday 24 April 2018 09:41 PM, David Lechner wrote:
>>> On 04/24/2018 03:28 AM, Sekhar Nori wrote:
>>>> On Monday 23 April 2018 08:29 PM, David Lechner wrote:
>>>>> On 04/06/2018 11:46 AM, Stephen Boyd wrote:
>>>>>> Quoting Sekhar Nori (2018-04-06 02:37:03)
>>>>>>>
>>>>>>> Can you please check that and confirm there is no issue with genpd and
>>>>>>> using CLK_OF_DECLARE() to initialize clocks?
>>>>>>>
>>>>>>> Unless you report an issue back, or Mike and Stephen have ideas about
>>>>>>> how to handle the dependency between PSC/PLL derived timer clock
>>>>>>> initialization and and timer_probe(), I think we need to move back to
>>>>>>> using CLK_OF_DECLARE().
>>>>>>
>>>>>> In such a case, please use the hybrid approach where the clks required
>>>>>> for the clockevent and/or clocksource are registered in the early
>>>>>> CLK_OF_DECLARE path but the rest of the clks get registered with a
>>>>>> proper platform device and driver. There are examples of this approach
>>>>>> on other platforms already.
>>>>>>
>>>>>
>>>>> I looked at this a bit last week, but I didn't come up with any approach
>>>>> that I was happy with. It seems like it would be nice to just register
>>>>> the absolute minimum clocks needed. On DA8XX, that would just be the
>>>>> PLL0
>>>>> AUXCLK. On most of the other SoCs, it would be the PLL AUXCLK plus one
>>>>> LPSC clock. The AUXCLKs are easy because they are just a simple gate
>>>>> from the oscillator. The LPSC clocks are a bit more tricky because they
>>>>> have a complex sequence for turning on. Furthermore, on DM646X, we need
>>>>> the whole PLL up to SYSCLK3 plus one LPSC clock, so things get a bit
>>>>> messy there.
>>>>
>>>> Things might change in the context of work being done here by Bartosz
>>>> for converting clocks to early platform devices.
>>>>
>>>> But, keeping that development aside for a moment: I think this means the
>>>> PLLs and PSCs need to be CLK_OF_DECLARE(). What we can have as platform
>>>> devices are clocks that are not in the path to get timer clock working
>>>> (like CFGCHIP clocks).
>>>
>>> CLK_OF_DECLARE() only matters on DA850. None of the other SoCs use device
>>
>> Thats true today, but lets not make the assumption that none of the
>> other DaVinci SoCs will gain DT support ever. We don't want churn in CCF
>> support once someone tries to add DT support for other platforms.
>>
>> I already have people using DM365 in mainline, for example.
>>
>>> tree. And on DA850, the timer0 clock is just the PLL0 AUXCLK, so PSCs can> still be platform devices there. And in fact, one of the PSC clocks on
>>> DA850 depends on async3, which is a CFGCHIP clock, so if we made the PSCs
>>> CLK_OF_DECLARE(), then we also have to make at least the async3 CFGCHIP
>>> clock CLK_OF_DECLARE(). But, like I said, I think that can be avoided by
>>> leaving the PSC clocks as a platform device on DA850 (and DA830).
>>
>> Okay, I did not realize that there is a dependency between CFGCHIP clk
>> and PSC too.
>>
>>> For everything else, we need the legacy board file equivalent of
>>> CLK_OF_DECLARE(), which is basically what I had here in v5 of the
>>> series.
>>
>> Yeah. I did not realize the dependency with timer when platform devices
>> were suggested. Sorry.
>>
>>>
>>> So, if we want this to keep moving before the if/when of Bartosz's
>>> early platform device stuff, I'm thinking that I will make the PLL
>>
>> After looking at feedback to Bartosz's series, and the fact that
>> previous attempts at doing the same thing were rejected, I think there
>> is benefit in keeping CCF support moving independent Bartosz's work.
>> Otherwise, we have no chance of getting anything merged for v4.18.
>>
>
> It's true, that the feedback was not very positive, but I'm still
> thinking I can come up with something that would get accepted. Last
> time someone came up with the idea, the problem it was supposed to
> solve was different (dependencies between devices) and was eventually
> fixed with introduction of probe deferral.
>
> This time around we really want these devices probed early. The main
> concern was using a device tree compatible. If I can instead just
> early probe all devices whose drivers are registered as early without
> touching the device tree (as Frank Rowand suggested) then maybe the
* It was actually Mark Rutland.
> response of the community would be better.
>
> Thanks,
> Bart
>
>> Early initialization of clocks and dependency with timer is a pretty
>> common theme across SoCs. As and when a better way to support is found,
>> I am sure DaVinci can be converted over along with rest of the devices.
>>
>>> and PSC drivers loadable with or without a platform device and let
>>> each SoC pick which one it should use.
>>
>> This sounds flexible. We have to see how the patches look. But I would
>> caution against adding a lot of dead code. If there is no way some of
>> the clocks will be useful as platform device, I see no point of
>> supporting them as such just in anticipation.
>>
>> Thanks,
>> Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 13/44] clk: davinci: Add platform information for TI DM355 PSC
[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
@ 2018-01-08 2:17 ` David Lechner
[not found] ` <1515377863-20358-14-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
1 sibling, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Lechner
This adds platform-specific declarations for the PSC clocks on TI
DaVinci 355 based systems.
Signed-off-by: David Lechner <david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm355.c | 78 +++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 80 insertions(+)
create mode 100644 drivers/clk/davinci/psc-dm355.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index aef0390..e0da5c3 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -12,4 +12,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DM646x) += pll-dm646x.o
obj-y += psc.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
+obj-$(CONFIG_ARCH_DAVINCI_DM355) += psc-dm355.o
endif
diff --git a/drivers/clk/davinci/psc-dm355.c b/drivers/clk/davinci/psc-dm355.c
new file mode 100644
index 0000000..09075ed
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm355.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM355
+ *
+ * Copyright (C) 2017 David Lechner <david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+static const struct davinci_psc_clk_info dm355_psc_info[] __initconst = {
+ LPSC(0, 0, vpss_master, pll1_sysclk4, 0),
+ LPSC(1, 0, vpss_slave, pll1_sysclk4, 0),
+ LPSC(5, 0, timer3, pll1_aux_clk, 0),
+ LPSC(6, 0, spi1, pll1_sysclk2, 0),
+ LPSC(7, 0, mmcsd1, pll1_sysclk2, 0),
+ LPSC(8, 0, asp1, pll1_sysclk2, 0),
+ LPSC(9, 0, usb, pll1_sysclk2, 0),
+ LPSC(10, 0, pwm3, pll1_aux_clk, 0),
+ LPSC(11, 0, spi2, pll1_sysclk2, 0),
+ LPSC(12, 0, rto, pll1_aux_clk, 0),
+ LPSC(14, 0, aemif, pll1_sysclk2, 0),
+ LPSC(15, 0, mmcsd0, pll1_sysclk2, 0),
+ LPSC(17, 0, asp0, pll1_sysclk2, 0),
+ LPSC(18, 0, i2c, pll1_aux_clk, 0),
+ LPSC(19, 0, uart0, pll1_aux_clk, 0),
+ LPSC(20, 0, uart1, pll1_aux_clk, 0),
+ LPSC(21, 0, uart2, pll1_sysclk2, 0),
+ LPSC(22, 0, spi0, pll1_sysclk2, 0),
+ LPSC(23, 0, pwm0, pll1_aux_clk, 0),
+ LPSC(24, 0, pwm1, pll1_aux_clk, 0),
+ LPSC(25, 0, pwm2, pll1_aux_clk, 0),
+ LPSC(26, 0, gpio, pll1_sysclk2, 0),
+ LPSC(27, 0, timer0, pll1_aux_clk, 0),
+ LPSC(28, 0, timer1, pll1_aux_clk, 0),
+ /* REVISIT: why can't this be disabled? */
+ LPSC(29, 0, timer2, pll1_aux_clk, LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, arm, pll1_sysclk1, LPSC_ALWAYS_ENABLED),
+ LPSC(40, 0, mjcp, pll1_sysclk1, 0),
+ LPSC(41, 0, vpss_dac, pll1_sysclk3, 0),
+ { }
+};
+
+void __init dm355_psc_clk_init(void __iomem *psc)
+{
+ struct clk_onecell_data *clk_data;
+
+ clk_data = davinci_psc_register_clocks(psc, dm355_psc_info, 42);
+ if (!clk_data)
+ return;
+
+ clk_register_clkdev(clk_data->clks[0], "master", "vpss");
+ clk_register_clkdev(clk_data->clks[1], "slave", "vpss");
+ clk_register_clkdev(clk_data->clks[6], NULL, "spi_davinci.1");
+ clk_register_clkdev(clk_data->clks[7], NULL, "dm6441-mmc.1");
+ clk_register_clkdev(clk_data->clks[8], NULL, "davinci-mcbsp.1");
+ clk_register_clkdev(clk_data->clks[9], "usb", NULL);
+ clk_register_clkdev(clk_data->clks[11], NULL, "spi_davinci.2");
+ clk_register_clkdev(clk_data->clks[14], "aemif", NULL);
+ clk_register_clkdev(clk_data->clks[15], NULL, "dm6441-mmc.0");
+ clk_register_clkdev(clk_data->clks[17], NULL, "davinci-mcbsp.0");
+ clk_register_clkdev(clk_data->clks[18], NULL, "i2c_davinci.1");
+ clk_register_clkdev(clk_data->clks[19], NULL, "serial8250.0");
+ clk_register_clkdev(clk_data->clks[20], NULL, "serial8250.1");
+ clk_register_clkdev(clk_data->clks[21], NULL, "serial8250.2");
+ clk_register_clkdev(clk_data->clks[22], NULL, "spi_davinci.0");
+ clk_register_clkdev(clk_data->clks[26], "gpio", NULL);
+ clk_register_clkdev(clk_data->clks[27], "timer0", NULL);
+ clk_register_clkdev(clk_data->clks[29], NULL, "davinci-wdt");
+ clk_register_clkdev(clk_data->clks[31], "arm", NULL);
+ clk_register_clkdev(clk_data->clks[41], "vpss_dac", NULL);
+
+ clk_free_onecell_data(clk_data);
+}
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index 3d8bdfa..dc09177 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -18,5 +18,6 @@ void dm646x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
void da830_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
void da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
+void dm355_psc_clk_init(void __iomem *psc);
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 14/44] clk: davinci: Add platform information for TI DM365 PSC
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (11 preceding siblings ...)
[not found] ` <1515377863-20358-1-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
@ 2018-01-08 2:17 ` 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
` (15 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds platform-specific declarations for the PSC clocks on TI
DaVinci 365 based systems.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm365.c | 83 +++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 85 insertions(+)
create mode 100644 drivers/clk/davinci/psc-dm365.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index e0da5c3..78dc1eb 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -13,4 +13,5 @@ obj-y += psc.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += psc-dm355.o
+obj-$(CONFIG_ARCH_DAVINCI_DM365) += psc-dm365.o
endif
diff --git a/drivers/clk/davinci/psc-dm365.c b/drivers/clk/davinci/psc-dm365.c
new file mode 100644
index 0000000..0232832
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm365.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM365
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+static const struct davinci_psc_clk_info dm365_psc_info[] __initconst = {
+ LPSC(1, 0, vpss_slave, pll1_sysclk5, 0),
+ LPSC(5, 0, timer3, pll1_aux_clk, 0),
+ LPSC(6, 0, spi1, pll1_sysclk4, 0),
+ LPSC(7, 0, mmcsd1, pll1_sysclk4, 0),
+ LPSC(8, 0, asp0, pll1_sysclk4, 0),
+ LPSC(9, 0, usb, pll1_aux_clk, 0),
+ LPSC(10, 0, pwm3, ref_clk, 0),
+ LPSC(11, 0, spi2, pll1_sysclk4, 0),
+ LPSC(12, 0, rto, pll1_sysclk4, 0),
+ LPSC(14, 0, aemif, pll1_sysclk4, 0),
+ LPSC(15, 0, mmcsd0, pll1_sysclk8, 0),
+ LPSC(18, 0, i2c, pll1_aux_clk, 0),
+ LPSC(19, 0, uart0, pll1_aux_clk, 0),
+ LPSC(20, 0, uart1, pll1_sysclk4, 0),
+ LPSC(22, 0, spi0, pll1_sysclk4, 0),
+ LPSC(23, 0, pwm0, pll1_aux_clk, 0),
+ LPSC(24, 0, pwm1, pll1_aux_clk, 0),
+ LPSC(25, 0, pwm2, pll1_aux_clk, 0),
+ LPSC(26, 0, gpio, pll1_sysclk4, 0),
+ LPSC(27, 0, timer0, pll1_aux_clk, 0),
+ LPSC(28, 0, timer1, pll1_aux_clk, 0),
+ /* REVISIT: why can't this be disabled? */
+ LPSC(29, 0, timer2, pll1_aux_clk, LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, arm, pll2_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(38, 0, spi3, pll1_sysclk4, 0),
+ LPSC(39, 0, spi4, pll1_aux_clk, 0),
+ LPSC(40, 0, emac, pll2_sysclk4, 0),
+ LPSC(44, 1, voice_codec, pll1_sysclk3, 0),
+ LPSC(46, 1, vpss_dac, pll1_sysclk3, 0),
+ LPSC(47, 0, vpss_master, pll1_sysclk5, 0),
+ LPSC(50, 0, mjcp, pll1_sysclk3, 0),
+ { }
+};
+
+void __init dm365_psc_clk_init(void __iomem *psc)
+{
+ struct clk_onecell_data *clk_data;
+
+ clk_data = davinci_psc_register_clocks(psc, dm365_psc_info, 52);
+ if (!clk_data)
+ return;
+
+ clk_register_clkdev(clk_data->clks[1], "slave", "vpss");
+ clk_register_clkdev(clk_data->clks[6], NULL, "spi_davinci.1");
+ clk_register_clkdev(clk_data->clks[7], NULL, "da830-mmc.1");
+ clk_register_clkdev(clk_data->clks[8], NULL, "davinci-mcbsp");
+ clk_register_clkdev(clk_data->clks[9], "usb", NULL);
+ clk_register_clkdev(clk_data->clks[11], NULL, "spi_davinci.2");
+ clk_register_clkdev(clk_data->clks[14], "aemif", NULL);
+ clk_register_clkdev(clk_data->clks[15], NULL, "da830-mmc.0");
+ clk_register_clkdev(clk_data->clks[18], NULL, "i2c_davinci.1");
+ clk_register_clkdev(clk_data->clks[19], NULL, "serial8250.0");
+ clk_register_clkdev(clk_data->clks[20], NULL, "serial8250.1");
+ clk_register_clkdev(clk_data->clks[22], NULL, "spi_davinci.0");
+ clk_register_clkdev(clk_data->clks[26], "gpio", NULL);
+ clk_register_clkdev(clk_data->clks[27], "timer0", NULL);
+ clk_register_clkdev(clk_data->clks[29], NULL, "davinci-wdt");
+ clk_register_clkdev(clk_data->clks[31], "arm", NULL);
+ clk_register_clkdev(clk_data->clks[38], NULL, "spi_davinci.3");
+ clk_register_clkdev(clk_data->clks[39], NULL, "spi_davinci.4");
+ clk_register_clkdev(clk_data->clks[40], NULL, "davinci_emac.1");
+ clk_register_clkdev(clk_data->clks[40], "fck", "davinci_mdio.0");
+ clk_register_clkdev(clk_data->clks[44], NULL, "davinci_voicecodec");
+ clk_register_clkdev(clk_data->clks[46], "vpss_dac", NULL);
+ clk_register_clkdev(clk_data->clks[47], "master", "vpss");
+
+ clk_free_onecell_data(clk_data);
+}
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index dc09177..c7d8c5f 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -19,5 +19,6 @@ void dm646x_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
void da830_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
void da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
void dm355_psc_clk_init(void __iomem *psc);
+void dm365_psc_clk_init(void __iomem *psc);
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 14/44] clk: davinci: Add platform information for TI DM365 PSC
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
0 siblings, 0 replies; 121+ messages in thread
From: Sekhar Nori @ 2018-01-16 14:16 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> This adds platform-specific declarations for the PSC clocks on TI
> DaVinci 365 based systems.
>
> Signed-off-by: David Lechner <david@lechnology.com>
Apart from some comments on other patches that apply to this too, I have
no new comments.
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 15/44] clk: davinci: Add platform information for TI DM644x PSC
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (12 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 14/44] clk: davinci: Add platform information for TI DM365 PSC David Lechner
@ 2018-01-08 2:17 ` 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
` (14 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds platform-specific declarations for the PSC clocks on TI
DaVinci 644x based systems.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm644x.c | 73 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 75 insertions(+)
create mode 100644 drivers/clk/davinci/psc-dm644x.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 78dc1eb..a20e379 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -14,4 +14,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DA830) += psc-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += psc-dm355.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += psc-dm365.o
+obj-$(CONFIG_ARCH_DAVINCI_DM644x) += psc-dm644x.o
endif
diff --git a/drivers/clk/davinci/psc-dm644x.c b/drivers/clk/davinci/psc-dm644x.c
new file mode 100644
index 0000000..ef5ef14
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm644x.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM644x
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+static const struct davinci_psc_clk_info dm644x_psc_info[] __initconst = {
+ LPSC(0, 0, vpss_master, pll1_sysclk3, 0),
+ LPSC(1, 0, vpss_slave, pll1_sysclk3, 0),
+ LPSC(6, 0, emac, pll1_sysclk5, 0),
+ LPSC(9, 0, usb, pll1_sysclk5, 0),
+ LPSC(10, 0, ide, pll1_sysclk5, 0),
+ LPSC(11, 0, vlynq, pll1_sysclk5, 0),
+ LPSC(14, 0, aemif, pll1_sysclk5, 0),
+ LPSC(15, 0, mmcsd, pll1_sysclk5, 0),
+ LPSC(17, 0, asp0, pll1_sysclk5, 0),
+ LPSC(18, 0, i2c, pll1_aux_clk, 0),
+ LPSC(19, 0, uart0, pll1_aux_clk, 0),
+ LPSC(20, 0, uart1, pll1_aux_clk, 0),
+ LPSC(21, 0, uart2, pll1_aux_clk, 0),
+ LPSC(22, 0, spi, pll1_sysclk5, 0),
+ LPSC(23, 0, pwm0, pll1_aux_clk, 0),
+ LPSC(24, 0, pwm1, pll1_aux_clk, 0),
+ LPSC(25, 0, pwm2, pll1_aux_clk, 0),
+ LPSC(26, 0, gpio, pll1_sysclk5, 0),
+ LPSC(27, 0, timer0, pll1_aux_clk, 0),
+ LPSC(28, 0, timer1, pll1_aux_clk, 0),
+ /* REVISIT: why can't this be disabled? */
+ LPSC(29, 0, timer2, pll1_aux_clk, LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, arm, pll1_sysclk2, LPSC_ALWAYS_ENABLED),
+ /* REVISIT how to disable? */
+ LPSC(39, 1, dsp, pll1_sysclk1, LPSC_ALWAYS_ENABLED),
+ /* REVISIT how to disable? */
+ LPSC(40, 1, vicp, pll1_sysclk2, LPSC_ALWAYS_ENABLED),
+ { }
+};
+
+void __init dm644x_psc_clk_init(void __iomem *psc)
+{
+ struct clk_onecell_data *clk_data;
+
+ clk_data = davinci_psc_register_clocks(psc, dm644x_psc_info, 41);
+ if (!clk_data)
+ return;
+
+ clk_register_clkdev(clk_data->clks[0], "master", "vpss");
+ clk_register_clkdev(clk_data->clks[1], "slave", "vpss");
+ clk_register_clkdev(clk_data->clks[6], NULL, "davinci_emac.1");
+ clk_register_clkdev(clk_data->clks[6], "fck", "davinci_mdio.0");
+ clk_register_clkdev(clk_data->clks[9], "usb", NULL);
+ clk_register_clkdev(clk_data->clks[10], NULL, "palm_bk3710");
+ clk_register_clkdev(clk_data->clks[14], "aemif", NULL);
+ clk_register_clkdev(clk_data->clks[15], NULL, "dm6441-mmc.0");
+ clk_register_clkdev(clk_data->clks[17], NULL, "davinci-mcbsp");
+ clk_register_clkdev(clk_data->clks[18], NULL, "i2c_davinci.1");
+ clk_register_clkdev(clk_data->clks[19], NULL, "serial8250.0");
+ clk_register_clkdev(clk_data->clks[20], NULL, "serial8250.1");
+ clk_register_clkdev(clk_data->clks[21], NULL, "serial8250.2");
+ clk_register_clkdev(clk_data->clks[26], "gpio", NULL);
+ clk_register_clkdev(clk_data->clks[27], "timer0", NULL);
+ clk_register_clkdev(clk_data->clks[29], NULL, "davinci-wdt");
+ clk_register_clkdev(clk_data->clks[31], "arm", NULL);
+
+ clk_free_onecell_data(clk_data);
+}
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index c7d8c5f..6d2896d 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -20,5 +20,6 @@ void da830_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
void da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
void dm355_psc_clk_init(void __iomem *psc);
void dm365_psc_clk_init(void __iomem *psc);
+void dm644x_psc_clk_init(void __iomem *psc);
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 15/44] clk: davinci: Add platform information for TI DM644x PSC
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
0 siblings, 0 replies; 121+ messages in thread
From: Sekhar Nori @ 2018-01-17 13:57 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, Kevin Hilman, Michael Turquette, Stephen Boyd,
linux-kernel, Rob Herring, Adam Ford
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> This adds platform-specific declarations for the PSC clocks on TI
> DaVinci 644x based systems.
>
> Signed-off-by: David Lechner <david@lechnology.com>
Looks good to me except comments I already gave for similar patches.
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 16/44] clk: davinci: Add platform information for TI DM646x PSC
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (13 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 15/44] clk: davinci: Add platform information for TI DM644x PSC David Lechner
@ 2018-01-08 2:17 ` 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
` (13 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds platform-specific declarations for the PSC clocks on TI
DaVinci 646x based systems.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm646x.c | 68 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 70 insertions(+)
create mode 100644 drivers/clk/davinci/psc-dm646x.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index a20e379..6c388d4 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -15,4 +15,5 @@ obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += psc-dm355.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += psc-dm365.o
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += psc-dm644x.o
+obj-$(CONFIG_ARCH_DAVINCI_DM646x) += psc-dm646x.o
endif
diff --git a/drivers/clk/davinci/psc-dm646x.c b/drivers/clk/davinci/psc-dm646x.c
new file mode 100644
index 0000000..cbc3976
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm646x.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM646x
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+static const struct davinci_psc_clk_info dm646x_psc_info[] __initconst = {
+ LPSC(0, 0, arm, pll1_sysclk2, LPSC_ALWAYS_ENABLED),
+ /* REVISIT how to disable? */
+ LPSC(1, 0, dsp, pll1_sysclk1, LPSC_ALWAYS_ENABLED),
+ LPSC(4, 0, edma_cc, pll1_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(5, 0, edma_tc0, pll1_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(6, 0, edma_tc1, pll1_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, edma_tc2, pll1_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(8, 0, edma_tc3, pll1_sysclk2, LPSC_ALWAYS_ENABLED),
+ LPSC(10, 0, ide, pll1_sysclk4, 0),
+ LPSC(14, 0, emac, pll1_sysclk3, 0),
+ LPSC(16, 0, vpif0, ref_clk, LPSC_ALWAYS_ENABLED),
+ LPSC(17, 0, vpif1, ref_clk, LPSC_ALWAYS_ENABLED),
+ LPSC(21, 0, aemif, pll1_sysclk3, LPSC_ALWAYS_ENABLED),
+ LPSC(22, 0, mcasp0, pll1_sysclk3, 0),
+ LPSC(23, 0, mcasp1, pll1_sysclk3, 0),
+ LPSC(26, 0, uart0, aux_clkin, 0),
+ LPSC(27, 0, uart1, aux_clkin, 0),
+ LPSC(28, 0, uart2, aux_clkin, 0),
+ /* REVIST: disabling hangs system */
+ LPSC(29, 0, pwm0, pll1_sysclk3, LPSC_ALWAYS_ENABLED),
+ /* REVIST: disabling hangs system */
+ LPSC(30, 0, pwm1, pll1_sysclk3, LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, i2c, pll1_sysclk3, 0),
+ LPSC(33, 0, gpio, pll1_sysclk3, 0),
+ LPSC(34, 0, timer0, pll1_sysclk3, 0),
+ LPSC(35, 0, timer1, pll1_sysclk3, 0),
+ { }
+};
+
+void __init dm646x_psc_clk_init(void __iomem *psc)
+{
+ struct clk_onecell_data *clk_data;
+
+ clk_data = davinci_psc_register_clocks(psc, dm646x_psc_info, 41);
+ if (!clk_data)
+ return;
+
+ clk_register_clkdev(clk_data->clks[0], "arm", NULL);
+ clk_register_clkdev(clk_data->clks[10], NULL, "palm_bk3710");
+ clk_register_clkdev(clk_data->clks[14], NULL, "davinci_emac.1");
+ clk_register_clkdev(clk_data->clks[14], "fck", "davinci_mdio.0");
+ clk_register_clkdev(clk_data->clks[21], "aemif", NULL);
+ clk_register_clkdev(clk_data->clks[22], NULL, "davinci-mcasp.0");
+ clk_register_clkdev(clk_data->clks[23], NULL, "davinci-mcasp.1");
+ clk_register_clkdev(clk_data->clks[26], NULL, "serial8250.0");
+ clk_register_clkdev(clk_data->clks[27], NULL, "serial8250.1");
+ clk_register_clkdev(clk_data->clks[28], NULL, "serial8250.2");
+ clk_register_clkdev(clk_data->clks[31], NULL, "i2c_davinci.1");
+ clk_register_clkdev(clk_data->clks[33], "gpio", NULL);
+ clk_register_clkdev(clk_data->clks[34], "timer0", NULL);
+
+ clk_free_onecell_data(clk_data);
+}
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index 6d2896d..3810ea3 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -21,5 +21,6 @@ void da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1);
void dm355_psc_clk_init(void __iomem *psc);
void dm365_psc_clk_init(void __iomem *psc);
void dm644x_psc_clk_init(void __iomem *psc);
+void dm646x_psc_clk_init(void __iomem *psc);
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 16/44] clk: davinci: Add platform information for TI DM646x PSC
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
0 siblings, 0 replies; 121+ messages in thread
From: Sekhar Nori @ 2018-01-17 14:59 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> +void __init dm646x_psc_clk_init(void __iomem *psc)
> +{
> + struct clk_onecell_data *clk_data;
> +
> + clk_data = davinci_psc_register_clocks(psc, dm646x_psc_info, 41);
> + if (!clk_data)
> + return;
> +
> + clk_register_clkdev(clk_data->clks[0], "arm", NULL);
I don't think this "arm" con_id is used any where for non-DA850 SoCs.
And same with "dsp" in other files. Probably best to drop these dubious
usage ones rather than carry them forward.
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 17/44] dt-bindings: clock: Add bindings for DA8XX CFGCHIP gate clocks
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (14 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 16/44] clk: davinci: Add platform information for TI DM646x PSC David Lechner
@ 2018-01-08 2:17 ` David Lechner
[not found] ` <1515377863-20358-18-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-08 2:17 ` [PATCH v5 18/44] dt-bindings: clock: Add binding for TI DA8XX CFGCHIP mux clocks David Lechner
` (12 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds a new binding for the gate clocks present in the CFGCHIP syscon
registers in TI DA8XX SoCs. There are actually other gate clocks in this
block that could be added in the future, but TBCLK is currently the only
one being used.
Signed-off-by: David Lechner <david@lechnology.com>
---
.../clock/ti/davinci/da8xx-cfgchip-gate.txt | 38 ++++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-gate.txt
diff --git a/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-gate.txt b/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-gate.txt
new file mode 100644
index 0000000..55821b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-gate.txt
@@ -0,0 +1,38 @@
+Binding for TI DA8XX/OMAP-L13X/AM17XX/AM18XX CFGCHIP gate clocks
+
+TI DA8XX/OMAP-L13X/AM17XX/AM18XX SoCs contain a general purpose set of
+registers call CFGCHIPn. Some of these registers function as clock
+gates. This document describes the bindings for those clocks.
+
+Required properties:
+- compatible: shall be "ti,da830-tbclk".
+- #clock-cells: from common clock binding; shall be set to 0.
+- clocks: phandle to the parent clock
+
+Optional properties:
+- clock-output-names: from common clock binding.
+
+Parent:
+This node must be a child of a "ti,da830-cfgchip" node.
+
+Assignment:
+The assigned-clocks and assigned-clock-parents from the common clock bindings
+can be used to indicate which parent clock should be used.
+
+Examples:
+
+ cfgchip: syscon@1417c {
+ compatible = "ti,da830-cfgchip", "syscon", "simple-mfd";
+ reg = <0x1417c 0x14>;
+
+ ehrpwm_tbclk: tbclk {
+ compatible = "ti,da830-tbclk";
+ #clock-cells = <0>;
+ clocks = <&psc1 17>;
+ clock-output-names = "ehrpwm_tbclk";
+ };
+ };
+
+Also see:
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
+
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 18/44] dt-bindings: clock: Add binding for TI DA8XX CFGCHIP mux clocks
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (15 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 17/44] dt-bindings: clock: Add bindings for DA8XX CFGCHIP gate clocks David Lechner
@ 2018-01-08 2:17 ` David Lechner
2018-01-08 2:17 ` [PATCH v5 19/44] clk: davinci: New driver for TI DA8XX CFGCHIP clocks David Lechner
` (11 subsequent siblings)
28 siblings, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds a new binding for multiplexer clocks that are part of the
CFGCHIPn registers on TI DA8XX-like SoCs. Currently, there are only
bindings given for the ASYNC3 clock domain, but there are additional
clock multiplexers in this syscon that could be added in the future
if needed.
Signed-off-by: David Lechner <david@lechnology.com>
---
.../clock/ti/davinci/da8xx-cfgchip-mux.txt | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-mux.txt
diff --git a/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-mux.txt b/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-mux.txt
new file mode 100644
index 0000000..8c874ad
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-mux.txt
@@ -0,0 +1,42 @@
+Binding for TI DA8XX/OMAP-L13X/AM17XX/AM18XX CFGCHIP multiplexer clocks
+
+TI DA8XX/OMAP-L13X/AM17XX/AM18XX SoCs contain a general purpose set of
+registers call CFGCHIPn. Some of these registers function as clock
+multiplexers. This document describes the bindings for those clocks.
+
+Required properties:
+- compatible: shall be "ti,da850-async3-clock".
+- #clock-cells: from common clock binding; shall be set to 0.
+- clocks: phandle list of clocks corresponding to clock-names
+- clock-names: must include the following: "pll0_sysclk2", "pll1_sysclk2".
+
+Optional properties:
+- clock-output-names: from common clock binding.
+
+Parent:
+This node must be a child of a "ti,da830-cfgchip" node.
+
+Assignment:
+The assigned-clocks and assigned-clock-parents from the common clock bindings
+can be used to indicate which parent clock should be used.
+
+Examples:
+
+ cfgchip: syscon@1417c {
+ compatible = "ti,da830-cfgchip", "syscon", "simple-mfd";
+ reg = <0x1417c 0x14>;
+
+ async3_clk: async3 {
+ compatible = "ti,da850-async3-clock";
+ #clock-cells = <0>;
+ clocks = <&pll0_sysclk 2>, <&pll1_sysclk 2>;
+ clock-names = "pll0_sysclk2", "pll1_sysclk2";
+ assigned-clocks = <&async3_clk>;
+ assigned-clock-parents = <&pll1_sysclk 2>;
+ clock-output-names = "async3";
+ };
+ };
+
+Also see:
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
+
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 19/44] clk: davinci: New driver for TI DA8XX CFGCHIP clocks
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (16 preceding siblings ...)
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 ` David Lechner
2018-01-17 15:31 ` Sekhar Nori
2018-01-08 2:17 ` [PATCH v5 20/44] dt-bindings: clock: Add bindings for TI DA8XX USB PHY clocks David Lechner
` (10 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds a new driver for the gate and multiplexer clocks in the
CFGCHIPn syscon registers on TI DA8XX-type SoCs.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 2 +
drivers/clk/davinci/da8xx-cfgchip.c | 203 ++++++++++++++++++++++++++++++++++++
2 files changed, 205 insertions(+)
create mode 100644 drivers/clk/davinci/da8xx-cfgchip.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 6c388d4..11178b7 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -1,6 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
ifeq ($(CONFIG_COMMON_CLK), y)
+obj-$(CONFIG_ARCH_DAVINCI_DA8XX) += da8xx-cfgchip.o
+
obj-y += pll.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c
new file mode 100644
index 0000000..772e09a
--- /dev/null
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for DA8xx/AM17xx/AM18xx/OMAP-L13x CFGCHIP
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_OF
+struct da8xx_cfgchip_gate_clk {
+ struct clk_hw hw;
+ struct regmap *regmap;
+ u32 reg;
+ u32 mask;
+};
+
+#define to_da8xx_cfgchip_gate_clk(_hw) \
+ container_of((_hw), struct da8xx_cfgchip_gate_clk, hw)
+
+static int da8xx_cfgchip_gate_clk_enable(struct clk_hw *hw)
+{
+ struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);
+
+ return regmap_write_bits(clk->regmap, clk->reg, clk->mask, clk->mask);
+}
+
+static void da8xx_cfgchip_gate_clk_disable(struct clk_hw *hw)
+{
+ struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);
+
+ regmap_write_bits(clk->regmap, clk->reg, clk->mask, 0);
+}
+
+static int da8xx_cfgchip_gate_clk_is_enabled(struct clk_hw *hw)
+{
+ struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);
+ unsigned int val;
+
+ regmap_read(clk->regmap, clk->reg, &val);
+
+ return !!(val & clk->mask);
+}
+
+static const struct clk_ops da8xx_cfgchip_gate_clk_ops = {
+ .enable = da8xx_cfgchip_gate_clk_enable,
+ .disable = da8xx_cfgchip_gate_clk_disable,
+ .is_enabled = da8xx_cfgchip_gate_clk_is_enabled,
+};
+
+static void da8xx_cfgchip_gate_clk_init(struct device_node *np, u32 reg,
+ u32 mask)
+{
+ struct da8xx_cfgchip_gate_clk *clk;
+ struct clk_init_data init;
+ const char *name = np->name;
+ const char *parent_name;
+ struct regmap *regmap;
+ int ret;
+
+ of_property_read_string(np, "clock-output-names", &name);
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap)) {
+ pr_err("%s: no regmap for syscon parent of %s (%ld)\n",
+ __func__, np->full_name, PTR_ERR(regmap));
+ return;
+ }
+
+ clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+ if (!clk)
+ return;
+
+ init.name = name;
+ init.ops = &da8xx_cfgchip_gate_clk_ops;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+ init.flags = 0;
+
+ clk->hw.init = &init;
+ clk->regmap = regmap;
+ clk->reg = reg;
+ clk->mask = mask;
+
+ ret = clk_hw_register(NULL, &clk->hw);
+ if (ret) {
+ pr_err("%s: failed to register %s (%d)\n", __func__,
+ np->full_name, ret);
+ return;
+ }
+
+ of_clk_add_hw_provider(np, of_clk_hw_simple_get, &clk->hw);
+}
+
+static void da8xx_tbclk_init(struct device_node *np)
+{
+ da8xx_cfgchip_gate_clk_init(np, CFGCHIP(1), CFGCHIP1_TBCLKSYNC);
+}
+CLK_OF_DECLARE(da8xx_tbclk, "ti,da830-tbclk", da8xx_tbclk_init);
+
+struct da8xx_cfgchip_mux_clk {
+ struct clk_hw hw;
+ struct regmap *regmap;
+ u32 reg;
+ u32 mask;
+};
+
+#define to_da8xx_cfgchip_mux_clk(_hw) \
+ container_of((_hw), struct da8xx_cfgchip_mux_clk, hw)
+
+static int da8xx_cfgchip_mux_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct da8xx_cfgchip_mux_clk *clk = to_da8xx_cfgchip_mux_clk(hw);
+ unsigned int val = index ? clk->mask : 0;
+
+ return regmap_write_bits(clk->regmap, clk->reg, clk->mask, val);
+}
+
+static u8 da8xx_cfgchip_mux_clk_get_parent(struct clk_hw *hw)
+{
+ struct da8xx_cfgchip_mux_clk *clk = to_da8xx_cfgchip_mux_clk(hw);
+ unsigned int val;
+
+ regmap_read(clk->regmap, clk->reg, &val);
+
+ return (val & clk->mask) ? 1 : 0;
+}
+
+static const struct clk_ops da8xx_cfgchip_mux_clk_ops = {
+ .set_parent = da8xx_cfgchip_mux_clk_set_parent,
+ .get_parent = da8xx_cfgchip_mux_clk_get_parent,
+};
+
+static void da8xx_cfgchip_mux_clk_init(struct device_node *np, u32 reg,
+ u32 mask)
+{
+ struct da8xx_cfgchip_mux_clk *clk;
+ struct clk_init_data init;
+ const char *name = np->name;
+ const char *parent_names[2];
+ struct regmap *regmap;
+ int ret;
+
+ ret = of_property_match_string(np, "clock-names", "pll0_sysclk2");
+ parent_names[0] = of_clk_get_parent_name(np, ret);
+ if (!parent_names[0]) {
+ pr_err("%s: missing pll0_sysclk2 clock\n", __func__);
+ return;
+ }
+
+ ret = of_property_match_string(np, "clock-names", "pll1_sysclk2");
+ parent_names[1] = of_clk_get_parent_name(np, ret);
+ if (!parent_names[1]) {
+ pr_err("%s: missing pll1_sysclk2 clock\n", __func__);
+ return;
+ }
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap)) {
+ pr_err("%s: no regmap for syscon parent of %s (%ld)\n",
+ __func__, np->full_name, PTR_ERR(regmap));
+ return;
+ }
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+ if (!clk)
+ return;
+
+ init.name = name;
+ init.ops = &da8xx_cfgchip_mux_clk_ops;
+ init.parent_names = parent_names;
+ init.num_parents = 2;
+ init.flags = 0;
+
+ clk->hw.init = &init;
+ clk->regmap = regmap;
+ clk->reg = reg;
+ clk->mask = mask;
+
+ ret = clk_hw_register(NULL, &clk->hw);
+ if (ret) {
+ pr_err("%s: failed to register %s (%d)\n", __func__,
+ np->full_name, ret);
+ return;
+ }
+
+ of_clk_add_hw_provider(np, of_clk_hw_simple_get, &clk->hw);
+}
+
+static void da8xx_async3_init(struct device_node *np)
+{
+ da8xx_cfgchip_mux_clk_init(np, CFGCHIP(3), CFGCHIP3_ASYNC3_CLKSRC);
+}
+CLK_OF_DECLARE(da8xx_async3, "ti,da850-async3-clock", da8xx_async3_init);
+#endif
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 19/44] clk: davinci: New driver for TI DA8XX CFGCHIP clocks
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
0 siblings, 1 reply; 121+ messages in thread
From: Sekhar Nori @ 2018-01-17 15:31 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, Kevin Hilman, Michael Turquette, Stephen Boyd,
linux-kernel, Rob Herring, Adam Ford
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> This adds a new driver for the gate and multiplexer clocks in the
> CFGCHIPn syscon registers on TI DA8XX-type SoCs.
>
> Signed-off-by: David Lechner <david@lechnology.com>
> ---
> drivers/clk/davinci/Makefile | 2 +
> drivers/clk/davinci/da8xx-cfgchip.c | 203 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 205 insertions(+)
> create mode 100644 drivers/clk/davinci/da8xx-cfgchip.c
>
> diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
> index 6c388d4..11178b7 100644
> --- a/drivers/clk/davinci/Makefile
> +++ b/drivers/clk/davinci/Makefile
> @@ -1,6 +1,8 @@
> # SPDX-License-Identifier: GPL-2.0
>
> ifeq ($(CONFIG_COMMON_CLK), y)
> +obj-$(CONFIG_ARCH_DAVINCI_DA8XX) += da8xx-cfgchip.o
> +
> obj-y += pll.o
> obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
> obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
> diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c
> new file mode 100644
> index 0000000..772e09a
> --- /dev/null
> +++ b/drivers/clk/davinci/da8xx-cfgchip.c
> @@ -0,0 +1,203 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Clock driver for DA8xx/AM17xx/AM18xx/OMAP-L13x CFGCHIP
> + *
> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
2018
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/mfd/da8xx-cfgchip.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +#ifdef CONFIG_OF
Is this ifdef really needed, or included to save space for non-OF
builds? I think it can be removed if not really needed.
> +static void da8xx_cfgchip_gate_clk_init(struct device_node *np, u32 reg,
> + u32 mask)
> +{
> + struct da8xx_cfgchip_gate_clk *clk;
> + struct clk_init_data init;
> + const char *name = np->name;
> + const char *parent_name;
> + struct regmap *regmap;
> + int ret;
> +
> + of_property_read_string(np, "clock-output-names", &name);
> + parent_name = of_clk_get_parent_name(np, 0);
> +
> + regmap = syscon_node_to_regmap(of_get_parent(np));
> + if (IS_ERR(regmap)) {
> + pr_err("%s: no regmap for syscon parent of %s (%ld)\n",
> + __func__, np->full_name, PTR_ERR(regmap));
please use pr_fmt for this driver too.
> +static void da8xx_cfgchip_mux_clk_init(struct device_node *np, u32 reg,
> + u32 mask)
> +{
> + struct da8xx_cfgchip_mux_clk *clk;
> + struct clk_init_data init;
> + const char *name = np->name;
> + const char *parent_names[2];
> + struct regmap *regmap;
> + int ret;
> +
> + ret = of_property_match_string(np, "clock-names", "pll0_sysclk2");
> + parent_names[0] = of_clk_get_parent_name(np, ret);
> + if (!parent_names[0]) {
> + pr_err("%s: missing pll0_sysclk2 clock\n", __func__);
> + return;
> + }
> +
> + ret = of_property_match_string(np, "clock-names", "pll1_sysclk2");
> + parent_names[1] = of_clk_get_parent_name(np, ret);
> + if (!parent_names[1]) {
> + pr_err("%s: missing pll1_sysclk2 clock\n", __func__);
> + return;
> + }
The fact that you are looking specifically for pll0_sysclk2 and
pll1_sysclk2 makes it really specific to async3 and the same function
cannot be used for something like EMIFA clock source. Can this part of
the function be factored out so rest of the function can still be reused
for another clock?
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* Re: [PATCH v5 19/44] clk: davinci: New driver for TI DA8XX CFGCHIP clocks
2018-01-17 15:31 ` Sekhar Nori
@ 2018-01-17 17:35 ` David Lechner
0 siblings, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-01-17 17:35 UTC (permalink / raw)
To: Sekhar Nori, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On 01/17/2018 09:31 AM, Sekhar Nori wrote:
> On Monday 08 January 2018 07:47 AM, David Lechner wrote:
>> This adds a new driver for the gate and multiplexer clocks in the
>> CFGCHIPn syscon registers on TI DA8XX-type SoCs.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
>> ---
>> drivers/clk/davinci/Makefile | 2 +
>> drivers/clk/davinci/da8xx-cfgchip.c | 203 ++++++++++++++++++++++++++++++++++++
>> 2 files changed, 205 insertions(+)
>> create mode 100644 drivers/clk/davinci/da8xx-cfgchip.c
>>
>> diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
>> index 6c388d4..11178b7 100644
>> --- a/drivers/clk/davinci/Makefile
>> +++ b/drivers/clk/davinci/Makefile
>> @@ -1,6 +1,8 @@
>> # SPDX-License-Identifier: GPL-2.0
>>
>> ifeq ($(CONFIG_COMMON_CLK), y)
>> +obj-$(CONFIG_ARCH_DAVINCI_DA8XX) += da8xx-cfgchip.o
>> +
>> obj-y += pll.o
>> obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
>> obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o
>> diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c
>> new file mode 100644
>> index 0000000..772e09a
>> --- /dev/null
>> +++ b/drivers/clk/davinci/da8xx-cfgchip.c
>> @@ -0,0 +1,203 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Clock driver for DA8xx/AM17xx/AM18xx/OMAP-L13x CFGCHIP
>> + *
>> + * Copyright (C) 2017 David Lechner <david@lechnology.com>
>
> 2018
>
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/mfd/da8xx-cfgchip.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/of.h>
>> +#include <linux/regmap.h>
>> +#include <linux/slab.h>
>> +
>> +#ifdef CONFIG_OF
>
> Is this ifdef really needed, or included to save space for non-OF
> builds? I think it can be removed if not really needed.
>
>> +static void da8xx_cfgchip_gate_clk_init(struct device_node *np, u32 reg,
>> + u32 mask)
>> +{
>> + struct da8xx_cfgchip_gate_clk *clk;
>> + struct clk_init_data init;
>> + const char *name = np->name;
>> + const char *parent_name;
>> + struct regmap *regmap;
>> + int ret;
>> +
>> + of_property_read_string(np, "clock-output-names", &name);
>> + parent_name = of_clk_get_parent_name(np, 0);
>> +
>> + regmap = syscon_node_to_regmap(of_get_parent(np));
>> + if (IS_ERR(regmap)) {
>> + pr_err("%s: no regmap for syscon parent of %s (%ld)\n",
>> + __func__, np->full_name, PTR_ERR(regmap));
>
> please use pr_fmt for this driver too.
>
>> +static void da8xx_cfgchip_mux_clk_init(struct device_node *np, u32 reg,
>> + u32 mask)
>> +{
>> + struct da8xx_cfgchip_mux_clk *clk;
>> + struct clk_init_data init;
>> + const char *name = np->name;
>> + const char *parent_names[2];
>> + struct regmap *regmap;
>> + int ret;
>> +
>> + ret = of_property_match_string(np, "clock-names", "pll0_sysclk2");
>> + parent_names[0] = of_clk_get_parent_name(np, ret);
>> + if (!parent_names[0]) {
>> + pr_err("%s: missing pll0_sysclk2 clock\n", __func__);
>> + return;
>> + }
>> +
>> + ret = of_property_match_string(np, "clock-names", "pll1_sysclk2");
>> + parent_names[1] = of_clk_get_parent_name(np, ret);
>> + if (!parent_names[1]) {
>> + pr_err("%s: missing pll1_sysclk2 clock\n", __func__);
>> + return;
>> + }
>
> The fact that you are looking specifically for pll0_sysclk2 and
> pll1_sysclk2 makes it really specific to async3 and the same function
> cannot be used for something like EMIFA clock source. Can this part of
> the function be factored out so rest of the function can still be reused
> for another clock?
>
Already fixed this stuff a couple days ago. ;-)
And I went ahead and added the EMIFA clocks (the mux and the DIV4.5)
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 20/44] dt-bindings: clock: Add bindings for TI DA8XX USB PHY clocks
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (17 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 19/44] clk: davinci: New driver for TI DA8XX CFGCHIP clocks David Lechner
@ 2018-01-08 2:17 ` David Lechner
2018-01-18 12:10 ` Sekhar Nori
2018-01-08 2:17 ` [PATCH v5 21/44] clk: davinci: New driver " David Lechner
` (9 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds a new binding for TI DA8XX USB PHY clocks. These clocks are part
of a syscon register called CFGCHIP3.
Signed-off-by: David Lechner <david@lechnology.com>
---
.../clock/ti/davinci/da8xx-cfgchip-usb-phy.txt | 55 ++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-usb-phy.txt
diff --git a/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-usb-phy.txt b/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-usb-phy.txt
new file mode 100644
index 0000000..8a12e1b
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip-usb-phy.txt
@@ -0,0 +1,55 @@
+Binding for TI DA8XX/OMAP-L13X/AM17XX/AM18XX CFGCHIP USB PHY clocks
+
+TI DA8XX/OMAP-L13X/AM17XX/AM18XX SoCs contain a general purpose set of
+registers call CFGCHIPn. Some of these registers function as the USB PHY
+clocks. This document describes the bindings for those clocks.
+
+Required properties:
+- compatible: shall be one of:
+ - "ti,da830-usb0-phy-clock" for the USB 2.0 PHY
+ - "ti,da830-usb1-phy-clock" for the USB 1.1 PHY
+- #clock-cells: from common clock binding; shall be set to 0.
+- clocks: phandle list of clocks corresponding to clock-names
+- clock-names: depends on compatible:
+ - for "ti,da830-usb0-phy-clock" must be "usb_refclkin", "auxclk",
+ "usb0_lpsc"
+ - for "ti,da830-usb1-phy-clock" must be "usb0_phy", "usb_refclkin"
+
+Optional properties:
+- clock-output-names: from common clock binding.
+
+Parent:
+ This node must be a child of a "ti,da830-cfgchip" node.
+
+Assignment:
+ The assigned-clocks and assigned-clock-parents properties from the
+ common clock bindings can be used to indicate which parent clock should
+ be used. Note: for "ti,da830-usb0-phy-clock", only "usb_refclkin" or
+ "auxclk" can be used as the assigned parent clock ("usb0_lpsc" is not
+ an actual parent clock and only used internally).
+
+Examples:
+
+ cfgchip: syscon@1417c {
+ compatible = "ti,da830-cfgchip", "syscon", "simple-mfd";
+ reg = <0x1417c 0x14>;
+
+ usb0_phy_clk: usb0-phy-clock {
+ compatible = "ti,da830-usb0-phy-clock";
+ #clock-cells = <0>;
+ clocks = <&usb_refclkin>, <&pll0_aux_clk>, <&psc1 1>;
+ clock-names = "usb_refclkin", "auxclk", "usb0_lpsc";
+ clock-output-names = "usb0_phy_clk";
+ };
+
+ usb1_phy_clk: usb1-phy-clock {
+ compatible = "ti,da830-usb1-phy-clock";
+ #clock-cells = <0>;
+ clocks = <&usb0_phy_clk>, <&usb_refclkin>;
+ clock-names = "usb0_phy", "usb_refclkin";
+ clock-output-names = "usb1_phy_clk";
+ };
+ };
+
+Also see:
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 20/44] dt-bindings: clock: Add bindings for TI DA8XX USB PHY clocks
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>
0 siblings, 1 reply; 121+ messages in thread
From: Sekhar Nori @ 2018-01-18 12:10 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Mark Rutland, Kevin Hilman, Michael Turquette, Stephen Boyd,
linux-kernel, Rob Herring, Adam Ford
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> This adds a new binding for TI DA8XX USB PHY clocks. These clocks are part
> of a syscon register called CFGCHIP3.
CFGCHIP2
>
> Signed-off-by: David Lechner <david@lechnology.com>
> +Examples:
> +
> + cfgchip: syscon@1417c {
> + compatible = "ti,da830-cfgchip", "syscon", "simple-mfd";
> + reg = <0x1417c 0x14>;
> +
> + usb0_phy_clk: usb0-phy-clock {
> + compatible = "ti,da830-usb0-phy-clock";
> + #clock-cells = <0>;
> + clocks = <&usb_refclkin>, <&pll0_aux_clk>, <&psc1 1>;
> + clock-names = "usb_refclkin", "auxclk", "usb0_lpsc";
> + clock-output-names = "usb0_phy_clk";
Probably call this "usb0_phy" to match with the input name used for
usb1_phy_clk?
> + };
> +
> + usb1_phy_clk: usb1-phy-clock {
> + compatible = "ti,da830-usb1-phy-clock";
> + #clock-cells = <0>;
> + clocks = <&usb0_phy_clk>, <&usb_refclkin>;
> + clock-names = "usb0_phy", "usb_refclkin";
> + clock-output-names = "usb1_phy_clk";
> + };
> + };
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 21/44] clk: davinci: New driver for TI DA8XX USB PHY clocks
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (18 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 20/44] dt-bindings: clock: Add bindings for TI DA8XX USB PHY clocks David Lechner
@ 2018-01-08 2:17 ` David Lechner
2018-01-18 13:05 ` Sekhar Nori
2018-01-08 2:17 ` [PATCH v5 22/44] ARM: davinci: move davinci_clk_init() to init_time David Lechner
` (8 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds a new driver for the USB PHY clocks in the CFGCHIP2 syscon
register on TI DA8XX-type SoCs.
The USB0 (USB 2.0) PHY clock is an interesting case because it calls
clk_enable() in a reentrant way. The USB 2.0 PSC only has to be enabled
temporarily while we are locking the PLL, which takes place during the
clk_enable() callback.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/da8xx-usb-phy-clk.c | 425 ++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 13 +
3 files changed, 439 insertions(+)
create mode 100644 drivers/clk/davinci/da8xx-usb-phy-clk.c
diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile
index 11178b7..4c772a7 100644
--- a/drivers/clk/davinci/Makefile
+++ b/drivers/clk/davinci/Makefile
@@ -2,6 +2,7 @@
ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_DAVINCI_DA8XX) += da8xx-cfgchip.o
+obj-$(CONFIG_ARCH_DAVINCI_DA8XX) += da8xx-usb-phy-clk.o
obj-y += pll.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += pll-da830.o
diff --git a/drivers/clk/davinci/da8xx-usb-phy-clk.c b/drivers/clk/davinci/da8xx-usb-phy-clk.c
new file mode 100644
index 0000000..fc6ea07
--- /dev/null
+++ b/drivers/clk/davinci/da8xx-usb-phy-clk.c
@@ -0,0 +1,425 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * da8xx-usb-phy-clk - TI DaVinci DA8xx USB PHY clocks driver
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ *
+ * This driver exposes the USB PHY clocks on DA8xx/AM18xx/OMAP-L13x SoCs.
+ * The clocks consist of two muxes and a PLL. The USB 2.0 PHY mux and PLL are
+ * combined into a single clock in Linux. The USB 1.0 PHY clock just consists
+ * of a mux. These clocks are controlled through CFGCHIP2, which is accessed
+ * as a syscon regmap since it is shared with other devices.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+/* --- USB 2.0 PHY clock --- */
+
+struct da8xx_usb0_phy_clk {
+ struct clk_hw hw;
+ struct clk *clk;
+ struct regmap *regmap;
+};
+
+enum da8xx_usb0_phy_clk_parent {
+ DA8XX_USB0_PHY_CLK_PARENT_USB_REFCLKIN,
+ DA8XX_USB0_PHY_CLK_PARENT_PLL0_AUXCLK,
+};
+
+#define to_da8xx_usb0_phy_clk(_hw) \
+ container_of((_hw), struct da8xx_usb0_phy_clk, hw)
+
+static int da8xx_usb0_phy_clk_prepare(struct clk_hw *hw)
+{
+ struct da8xx_usb0_phy_clk *clk = to_da8xx_usb0_phy_clk(hw);
+
+ /* The USB 2.0 PSC clock is only needed temporarily during the USB 2.0
+ * PHY clock enable, but since clk_prepare() can't be called in an
+ * atomic context (i.e. in clk_enable()), we have to prepare it here.
+ */
+ return clk_prepare(clk->clk);
+}
+
+static void da8xx_usb0_phy_clk_unprepare(struct clk_hw *hw)
+{
+ struct da8xx_usb0_phy_clk *clk = to_da8xx_usb0_phy_clk(hw);
+
+ clk_unprepare(clk->clk);
+}
+
+static int da8xx_usb0_phy_clk_enable(struct clk_hw *hw)
+{
+ struct da8xx_usb0_phy_clk *clk = to_da8xx_usb0_phy_clk(hw);
+ unsigned int mask, val;
+ int ret;
+
+ /* Locking the USB 2.O PLL requires that the USB 2.O PSC is enabled
+ * temporaily. It can be turned back off once the PLL is locked.
+ */
+ clk_enable(clk->clk);
+
+ /* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
+ * PHY may use the USB 2.0 PLL clock without USB 2.0 OTG being used.
+ */
+ mask = CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_PHY_PLLON;
+ val = CFGCHIP2_PHY_PLLON;
+
+ regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+ ret = regmap_read_poll_timeout(clk->regmap, CFGCHIP(2), val,
+ val & CFGCHIP2_PHYCLKGD, 0, 500000);
+
+ clk_disable(clk->clk);
+
+ return ret;
+}
+
+static void da8xx_usb0_phy_clk_disable(struct clk_hw *hw)
+{
+ struct da8xx_usb0_phy_clk *clk = to_da8xx_usb0_phy_clk(hw);
+ unsigned int val;
+
+ val = CFGCHIP2_PHYPWRDN;
+ regmap_write_bits(clk->regmap, CFGCHIP(2), val, val);
+}
+
+static int da8xx_usb0_phy_clk_is_enabled(struct clk_hw *hw)
+{
+ struct da8xx_usb0_phy_clk *clk = to_da8xx_usb0_phy_clk(hw);
+ unsigned int val;
+
+ regmap_read(clk->regmap, CFGCHIP(2), &val);
+
+ return !!(val & CFGCHIP2_PHYCLKGD);
+}
+
+static unsigned long da8xx_usb0_phy_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct da8xx_usb0_phy_clk *clk = to_da8xx_usb0_phy_clk(hw);
+ unsigned int mask, val;
+
+ /* The parent clock rate must be one of the following */
+ mask = CFGCHIP2_REFFREQ_MASK;
+ switch (parent_rate) {
+ case 12000000:
+ val = CFGCHIP2_REFFREQ_12MHZ;
+ break;
+ case 13000000:
+ val = CFGCHIP2_REFFREQ_13MHZ;
+ break;
+ case 19200000:
+ val = CFGCHIP2_REFFREQ_19_2MHZ;
+ break;
+ case 20000000:
+ val = CFGCHIP2_REFFREQ_20MHZ;
+ break;
+ case 24000000:
+ val = CFGCHIP2_REFFREQ_24MHZ;
+ break;
+ case 26000000:
+ val = CFGCHIP2_REFFREQ_26MHZ;
+ break;
+ case 38400000:
+ val = CFGCHIP2_REFFREQ_38_4MHZ;
+ break;
+ case 40000000:
+ val = CFGCHIP2_REFFREQ_40MHZ;
+ break;
+ case 48000000:
+ val = CFGCHIP2_REFFREQ_48MHZ;
+ break;
+ default:
+ return 0;
+ }
+
+ regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+
+ /* USB 2.0 PLL always supplies 48MHz */
+ return 48000000;
+}
+
+static long da8xx_usb0_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ return 48000000;
+}
+
+static int da8xx_usb0_phy_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct da8xx_usb0_phy_clk *clk = to_da8xx_usb0_phy_clk(hw);
+ unsigned int mask, val;
+
+ /* Set the mux depending on the parent clock. */
+ mask = CFGCHIP2_USB2PHYCLKMUX;
+ switch (index) {
+ case DA8XX_USB0_PHY_CLK_PARENT_USB_REFCLKIN:
+ val = 0;
+ break;
+ case DA8XX_USB0_PHY_CLK_PARENT_PLL0_AUXCLK:
+ val = CFGCHIP2_USB2PHYCLKMUX;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+
+ return 0;
+}
+
+static u8 da8xx_usb0_phy_clk_get_parent(struct clk_hw *hw)
+{
+ struct da8xx_usb0_phy_clk *clk = to_da8xx_usb0_phy_clk(hw);
+ unsigned int val;
+
+ regmap_read(clk->regmap, CFGCHIP(2), &val);
+
+ if (val & CFGCHIP2_USB2PHYCLKMUX)
+ return DA8XX_USB0_PHY_CLK_PARENT_PLL0_AUXCLK;
+
+ return DA8XX_USB0_PHY_CLK_PARENT_USB_REFCLKIN;
+}
+
+static const struct clk_ops da8xx_usb0_phy_clk_ops = {
+ .prepare = da8xx_usb0_phy_clk_prepare,
+ .unprepare = da8xx_usb0_phy_clk_unprepare,
+ .enable = da8xx_usb0_phy_clk_enable,
+ .disable = da8xx_usb0_phy_clk_disable,
+ .is_enabled = da8xx_usb0_phy_clk_is_enabled,
+ .recalc_rate = da8xx_usb0_phy_clk_recalc_rate,
+ .round_rate = da8xx_usb0_phy_clk_round_rate,
+ .set_parent = da8xx_usb0_phy_clk_set_parent,
+ .get_parent = da8xx_usb0_phy_clk_get_parent,
+};
+
+/**
+ * da8xx_usb0_phy_clk_register - Register a new USB 2.0 PHY clock
+ * @name: The clock name
+ * @parent0: The name of the USB_REFCLKIN clock
+ * @parent1: The name of the PLL0 AUXCLK
+ * @usb0_psc_clk: The USB 2.0 PSC clock
+ * @regmap: The CFGCHIP regmap
+ */
+struct clk *da8xx_usb0_phy_clk_register(const char *name,
+ const char *parent0,
+ const char *parent1,
+ struct clk *usb0_psc_clk,
+ struct regmap *regmap)
+{
+ const char * const parent_names[] = {
+ [DA8XX_USB0_PHY_CLK_PARENT_USB_REFCLKIN] = parent0,
+ [DA8XX_USB0_PHY_CLK_PARENT_PLL0_AUXCLK] = parent1,
+ };
+ struct da8xx_usb0_phy_clk *clk;
+ struct clk_init_data init;
+
+ clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+ if (!clk)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &da8xx_usb0_phy_clk_ops;
+ init.parent_names = parent_names;
+ init.num_parents = 2;
+
+ clk->hw.init = &init;
+ clk->clk = usb0_psc_clk;
+ clk->regmap = regmap;
+
+ return clk_register(NULL, &clk->hw);
+}
+
+/* --- USB 1.1 PHY clock --- */
+
+struct da8xx_usb1_phy_clk {
+ struct clk_hw hw;
+ struct regmap *regmap;
+};
+
+enum usb1_phy_clk_parent {
+ DA8XX_USB1_PHY_CLK_PARENT_USB0_PHY_PLL,
+ DA8XX_USB1_PHY_CLK_PARENT_USB_REFCLKIN,
+};
+
+#define to_da8xx_usb1_phy_clk(_hw) \
+ container_of((_hw), struct da8xx_usb1_phy_clk, hw)
+
+static int da8xx_usb1_phy_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct da8xx_usb1_phy_clk *clk = to_da8xx_usb1_phy_clk(hw);
+ unsigned int mask, val;
+
+ /* Set the USB 1.1 PHY clock mux based on the parent clock. */
+ mask = CFGCHIP2_USB1PHYCLKMUX;
+ switch (index) {
+ case DA8XX_USB1_PHY_CLK_PARENT_USB_REFCLKIN:
+ val = CFGCHIP2_USB1PHYCLKMUX;
+ break;
+ case DA8XX_USB1_PHY_CLK_PARENT_USB0_PHY_PLL:
+ val = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
+
+ return 0;
+}
+
+static u8 da8xx_usb1_phy_clk_get_parent(struct clk_hw *hw)
+{
+ struct da8xx_usb1_phy_clk *clk = to_da8xx_usb1_phy_clk(hw);
+ unsigned int val;
+
+ regmap_read(clk->regmap, CFGCHIP(2), &val);
+
+ if (val & CFGCHIP2_USB1PHYCLKMUX)
+ return DA8XX_USB1_PHY_CLK_PARENT_USB_REFCLKIN;
+
+ return DA8XX_USB1_PHY_CLK_PARENT_USB0_PHY_PLL;
+}
+
+static const struct clk_ops da8xx_usb1_phy_clk_ops = {
+ .set_parent = da8xx_usb1_phy_clk_set_parent,
+ .get_parent = da8xx_usb1_phy_clk_get_parent,
+};
+
+/**
+ * da8xx_usb1_phy_clk_register - Register a new USB 1.1 PHY clock
+ * @name: The clock name
+ * @parent0: The name of the USB 2.0 PHY clock
+ * @parent1: The name of the USB_REFCLKIN clock
+ * @regmap: The CFGCHIP regmap
+ */
+struct clk *da8xx_usb1_phy_clk_register(const char *name,
+ const char *parent0,
+ const char *parent1,
+ struct regmap *regmap)
+{
+ const char * const parent_names[] = {
+ [DA8XX_USB1_PHY_CLK_PARENT_USB0_PHY_PLL] = parent0,
+ [DA8XX_USB1_PHY_CLK_PARENT_USB_REFCLKIN] = parent1,
+ };
+ struct da8xx_usb1_phy_clk *clk;
+ struct clk_init_data init;
+
+ clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+ if (!clk)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &da8xx_usb1_phy_clk_ops;
+ init.parent_names = parent_names;
+ init.num_parents = 2;
+
+ clk->hw.init = &init;
+ clk->regmap = regmap;
+
+ return clk_register(NULL, &clk->hw);
+}
+
+#ifdef CONFIG_OF
+static void da8xx_usb0_phy_clk_init(struct device_node *np)
+{
+ const char *name = np->name;
+ const char *parent0, *parent1;
+ struct regmap *regmap;
+ struct clk *usb0_psc_clk, *clk;
+ int ret;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap)) {
+ pr_err("%s: No regmap for syscon parent of %s (%ld)\n",
+ __func__, np->full_name, PTR_ERR(regmap));
+ return;
+ }
+
+ ret = of_property_match_string(np, "clock-names", "usb_refclkin");
+ parent0 = of_clk_get_parent_name(np, ret);
+ if (!parent0) {
+ pr_err("%s: Could not get usb_refclkin (%d)\n", __func__, ret);
+ return;
+ }
+
+ ret = of_property_match_string(np, "clock-names", "auxclk");
+ parent1 = of_clk_get_parent_name(np, ret);
+ if (!parent1) {
+ pr_err("%s: Could not get auxclk (%d)\n", __func__, ret);
+ return;
+ }
+
+ usb0_psc_clk = of_clk_get_by_name(np, "usb0_lpsc");
+ if (IS_ERR(usb0_psc_clk)) {
+ pr_err("%s: Could not get usb0_lpsc (%ld)\n", __func__,
+ PTR_ERR(usb0_psc_clk));
+ return;
+ }
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ clk = da8xx_usb0_phy_clk_register(name, parent0, parent1, usb0_psc_clk,
+ regmap);
+ if (IS_ERR(clk)) {
+ pr_err("%s: Failed to register clock %s (%ld)\n", __func__,
+ np->full_name, PTR_ERR(clk));
+ clk_put(usb0_psc_clk);
+ return;
+ }
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+CLK_OF_DECLARE(da8xx_usb0_phy_clk, "ti,da830-usb0-phy-clock",
+ da8xx_usb0_phy_clk_init);
+
+static void da8xx_usb1_phy_clk_init(struct device_node *np)
+{
+ const char *name = np->name;
+ const char *parent0, *parent1;
+ struct regmap *regmap;
+ struct clk *clk;
+ int ret;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap)) {
+ pr_err("%s: No regmap for syscon parent of %s (%ld)\n",
+ __func__, np->full_name, PTR_ERR(regmap));
+ return;
+ }
+
+ ret = of_property_match_string(np, "clock-names", "usb0_phy");
+ parent0 = of_clk_get_parent_name(np, ret);
+ if (!parent0) {
+ pr_err("%s: Could not get usb0_phy (%d)\n", __func__, ret);
+ return;
+ }
+
+ ret = of_property_match_string(np, "clock-names", "usb_refclkin");
+ parent1 = of_clk_get_parent_name(np, ret);
+ if (!parent1) {
+ pr_err("%s: Could not get usb_refclkin (%d)\n", __func__, ret);
+ return;
+ }
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ clk = da8xx_usb1_phy_clk_register(name, parent0, parent1, regmap);
+ if (IS_ERR(clk)) {
+ pr_err("%s: Failed to register clock %s (%ld)\n",
+ __func__, np->full_name, PTR_ERR(clk));
+ return;
+ }
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+CLK_OF_DECLARE(da8xx_usb1_phy_clk, "ti,da830-usb1-phy-clock",
+ da8xx_usb1_phy_clk_init);
+#endif
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index 3810ea3..ec7403e 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -9,6 +9,9 @@
#include <linux/types.h>
+struct clk;
+struct regmap;
+
void da830_pll_clk_init(void __iomem *pll);
void da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1);
void dm355_pll_clk_init(void __iomem *pll1, void __iomem *pll2);
@@ -23,4 +26,14 @@ void dm365_psc_clk_init(void __iomem *psc);
void dm644x_psc_clk_init(void __iomem *psc);
void dm646x_psc_clk_init(void __iomem *psc);
+struct clk *da8xx_usb0_phy_clk_register(const char *name,
+ const char *parent0,
+ const char *parent1,
+ struct clk *usb0_psc_clk,
+ struct regmap *regmap);
+struct clk *da8xx_usb1_phy_clk_register(const char *name,
+ const char *parent0,
+ const char *parent1,
+ struct regmap *regmap);
+
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 21/44] clk: davinci: New driver for TI DA8XX USB PHY clocks
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>
0 siblings, 1 reply; 121+ messages in thread
From: Sekhar Nori @ 2018-01-18 13:05 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> +static int da8xx_usb1_phy_clk_set_parent(struct clk_hw *hw, u8 index)
> +{
> + struct da8xx_usb1_phy_clk *clk = to_da8xx_usb1_phy_clk(hw);
> + unsigned int mask, val;
> +
> + /* Set the USB 1.1 PHY clock mux based on the parent clock. */
> + mask = CFGCHIP2_USB1PHYCLKMUX;
> + switch (index) {
> + case DA8XX_USB1_PHY_CLK_PARENT_USB_REFCLKIN:
> + val = CFGCHIP2_USB1PHYCLKMUX;
> + break;
> + case DA8XX_USB1_PHY_CLK_PARENT_USB0_PHY_PLL:
> + val = 0;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + regmap_write_bits(clk->regmap, CFGCHIP(2), mask, val);
This function can be simplified quite a bit if you use a shift.
#define CFGCHIP2_USB1PHYCLKMUX_SHIFT 12
static int da8xx_usb1_phy_clk_set_parent(struct clk_hw *hw, u8 index)
{
struct da8xx_usb1_phy_clk *clk = to_da8xx_usb1_phy_clk(hw);
regmap_write_bits(clk->regmap, CFGCHIP(2),
CFGCHIP2_USB1PHYCLKMUX,
index << CFGCHIP2_USB1PHYCLKMUX_SHIFT);
}
Same thing for da8xx_usb0_phy_clk_set_parent() as well.
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 22/44] ARM: davinci: move davinci_clk_init() to init_time
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (19 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 21/44] clk: davinci: New driver " David Lechner
@ 2018-01-08 2:17 ` David Lechner
2018-01-08 2:17 ` [PATCH v5 23/44] ARM: da830: add new clock init using common clock framework David Lechner
` (7 subsequent siblings)
28 siblings, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This moves the call of davinci_clk_init() from map_io to init_time for all
boards.
This is the proper place to init clocks. This is also done in preparation
for moving to the common clock framework.
dm646x is a special case because we need to handle different ref_clk rates
depending on which board is being used. The clock init in this case is
modified to set the rate before registering the clocks instead of using
davinci_set_refclk_rate() to recalculate the entire clock tree after all
of the clocks are registered.
Also, the cpu_clks field is removed from struct davinci_soc_info since it
is no longer needed.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/board-da830-evm.c | 2 +-
arch/arm/mach-davinci/board-da850-evm.c | 2 +-
arch/arm/mach-davinci/board-dm355-evm.c | 2 +-
arch/arm/mach-davinci/board-dm355-leopard.c | 2 +-
arch/arm/mach-davinci/board-dm365-evm.c | 2 +-
arch/arm/mach-davinci/board-dm644x-evm.c | 2 +-
arch/arm/mach-davinci/board-dm646x-evm.c | 19 +++++++++++++------
arch/arm/mach-davinci/board-mityomapl138.c | 2 +-
arch/arm/mach-davinci/board-neuros-osd2.c | 2 +-
arch/arm/mach-davinci/board-omapl138-hawk.c | 2 +-
arch/arm/mach-davinci/board-sffsdr.c | 2 +-
arch/arm/mach-davinci/da830.c | 7 +++++--
arch/arm/mach-davinci/da850.c | 7 +++++--
arch/arm/mach-davinci/da8xx-dt.c | 2 +-
arch/arm/mach-davinci/davinci.h | 4 ++++
arch/arm/mach-davinci/dm355.c | 8 ++++++--
arch/arm/mach-davinci/dm365.c | 8 ++++++--
arch/arm/mach-davinci/dm644x.c | 8 ++++++--
arch/arm/mach-davinci/dm646x.c | 22 +++++++++++-----------
arch/arm/mach-davinci/include/mach/common.h | 1 -
arch/arm/mach-davinci/include/mach/da8xx.h | 3 +++
21 files changed, 70 insertions(+), 39 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index a58bfca..7adf009 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -638,7 +638,7 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM")
.atag_offset = 0x100,
.map_io = da830_evm_map_io,
.init_irq = cp_intc_init,
- .init_time = davinci_timer_init,
+ .init_time = da830_init_time,
.init_machine = da830_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 6039ec1..8602d0d 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1481,7 +1481,7 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
.atag_offset = 0x100,
.map_io = da850_evm_map_io,
.init_irq = cp_intc_init,
- .init_time = davinci_timer_init,
+ .init_time = da850_init_time,
.init_machine = da850_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index d60d998..3c15cb7 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -416,7 +416,7 @@ MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
.atag_offset = 0x100,
.map_io = dm355_evm_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm355_init_time,
.init_machine = dm355_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index 1e7e9b8..3ebc89d 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -271,7 +271,7 @@ MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
.atag_offset = 0x100,
.map_io = dm355_leopard_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm355_init_time,
.init_machine = dm355_leopard_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 17b2c29..3daeac7 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -774,7 +774,7 @@ MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
.atag_offset = 0x100,
.map_io = dm365_evm_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm365_init_time,
.init_machine = dm365_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 5e1afc2..8d8c4ab 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -817,7 +817,7 @@ MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
.atag_offset = 0x100,
.map_io = davinci_evm_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm644x_init_time,
.init_machine = davinci_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index 003bbe5..2d37f5b 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -44,10 +44,8 @@
#include <mach/common.h>
#include <mach/irqs.h>
#include <mach/serial.h>
-#include <mach/clock.h>
#include "davinci.h"
-#include "clock.h"
#define NAND_BLOCK_SIZE SZ_128K
@@ -716,14 +714,23 @@ static void __init evm_init_i2c(void)
}
#endif
+#define DM646X_REF_FREQ 27000000
+#define DM646X_AUX_FREQ 24000000
#define DM6467T_EVM_REF_FREQ 33000000
static void __init davinci_map_io(void)
{
dm646x_init();
+}
- if (machine_is_davinci_dm6467tevm())
- davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
+static void __init dm646x_evm_init_time(void)
+{
+ dm646x_init_time(DM646X_REF_FREQ, DM646X_AUX_FREQ);
+}
+
+static void __init dm6467t_evm_init_time(void)
+{
+ dm646x_init_time(DM6467T_EVM_REF_FREQ, DM646X_AUX_FREQ);
}
#define DM646X_EVM_PHY_ID "davinci_mdio-0:01"
@@ -797,7 +804,7 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
.atag_offset = 0x100,
.map_io = davinci_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm646x_evm_init_time,
.init_machine = evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
@@ -807,7 +814,7 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
.atag_offset = 0x100,
.map_io = davinci_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm6467t_evm_init_time,
.init_machine = evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index 0b23cf3..f9a725a 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -570,7 +570,7 @@ MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808")
.atag_offset = 0x100,
.map_io = mityomapl138_map_io,
.init_irq = cp_intc_init,
- .init_time = davinci_timer_init,
+ .init_time = da850_init_time,
.init_machine = mityomapl138_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index 1e27baa..ff871a0 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -227,7 +227,7 @@ MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
.atag_offset = 0x100,
.map_io = davinci_ntosd2_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm644x_init_time,
.init_machine = davinci_ntosd2_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 88ab45c..bc8a747 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -334,7 +334,7 @@ MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
.atag_offset = 0x100,
.map_io = omapl138_hawk_map_io,
.init_irq = cp_intc_init,
- .init_time = davinci_timer_init,
+ .init_time = da850_init_time,
.init_machine = omapl138_hawk_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 1f02d4e..2922da9 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -150,7 +150,7 @@ MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
.atag_offset = 0x100,
.map_io = davinci_sffsdr_map_io,
.init_irq = davinci_irq_init,
- .init_time = davinci_timer_init,
+ .init_time = dm644x_init_time,
.init_machine = davinci_sffsdr_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 57ab18c..350d767 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -1200,7 +1200,6 @@ static const struct davinci_soc_info davinci_soc_info_da830 = {
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
.ids = da830_ids,
.ids_num = ARRAY_SIZE(da830_ids),
- .cpu_clks = da830_clks,
.psc_bases = da830_psc_bases,
.psc_bases_num = ARRAY_SIZE(da830_psc_bases),
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
@@ -1220,6 +1219,10 @@ void __init da830_init(void)
da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module");
+}
- davinci_clk_init(davinci_soc_info_da830.cpu_clks);
+void __init da830_init_time(void)
+{
+ davinci_clk_init(da830_clks);
+ davinci_timer_init();
}
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index aa37cbd..34117e61 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1353,7 +1353,6 @@ static const struct davinci_soc_info davinci_soc_info_da850 = {
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
.ids = da850_ids,
.ids_num = ARRAY_SIZE(da850_ids),
- .cpu_clks = da850_clks,
.psc_bases = da850_psc_bases,
.psc_bases_num = ARRAY_SIZE(da850_psc_bases),
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
@@ -1392,6 +1391,10 @@ void __init da850_init(void)
v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+}
- davinci_clk_init(davinci_soc_info_da850.cpu_clks);
+void __init da850_init_time(void)
+{
+ davinci_clk_init(da850_clks);
+ davinci_timer_init();
}
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index 779e8ce..ab199f4 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -96,7 +96,7 @@ static const char *const da850_boards_compat[] __initconst = {
DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
.map_io = da850_init,
- .init_time = davinci_timer_init,
+ .init_time = da850_init_time,
.init_machine = da850_init_machine,
.dt_compat = da850_boards_compat,
.init_late = davinci_init_late,
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index c62b90c..270cef8 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -83,6 +83,7 @@ int davinci_init_wdt(void);
/* DM355 function declarations */
void dm355_init(void);
+void dm355_init_time(void);
void dm355_init_spi0(unsigned chipselect_mask,
const struct spi_board_info *info, unsigned len);
void dm355_init_asp1(u32 evt_enable);
@@ -91,6 +92,7 @@ int dm355_gpio_register(void);
/* DM365 function declarations */
void dm365_init(void);
+void dm365_init_time(void);
void dm365_init_asp(void);
void dm365_init_vc(void);
void dm365_init_ks(struct davinci_ks_platform_data *pdata);
@@ -102,12 +104,14 @@ int dm365_gpio_register(void);
/* DM644x function declarations */
void dm644x_init(void);
+void dm644x_init_time(void);
void dm644x_init_asp(void);
int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
int dm644x_gpio_register(void);
/* DM646x function declarations */
void dm646x_init(void);
+void dm646x_init_time(unsigned long ref_clk_rate, unsigned long aux_clkin_rate);
void dm646x_init_mcasp0(struct snd_platform_data *pdata);
void dm646x_init_mcasp1(struct snd_platform_data *pdata);
int dm646x_init_edma(struct edma_rsv_info *rsv);
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 938747f..f294804 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -1012,7 +1012,6 @@ static const struct davinci_soc_info davinci_soc_info_dm355 = {
.jtag_id_reg = 0x01c40028,
.ids = dm355_ids,
.ids_num = ARRAY_SIZE(dm355_ids),
- .cpu_clks = dm355_clks,
.psc_bases = dm355_psc_bases,
.psc_bases_num = ARRAY_SIZE(dm355_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
@@ -1043,7 +1042,12 @@ void __init dm355_init(void)
{
davinci_common_init(&davinci_soc_info_dm355);
davinci_map_sysmod();
- davinci_clk_init(davinci_soc_info_dm355.cpu_clks);
+}
+
+void __init dm355_init_time(void)
+{
+ davinci_clk_init(dm355_clks);
+ davinci_timer_init();
}
int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 5d9f96d..1e3df9d 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -1116,7 +1116,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = {
.jtag_id_reg = 0x01c40028,
.ids = dm365_ids,
.ids_num = ARRAY_SIZE(dm365_ids),
- .cpu_clks = dm365_clks,
.psc_bases = dm365_psc_bases,
.psc_bases_num = ARRAY_SIZE(dm365_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
@@ -1168,7 +1167,12 @@ void __init dm365_init(void)
{
davinci_common_init(&davinci_soc_info_dm365);
davinci_map_sysmod();
- davinci_clk_init(davinci_soc_info_dm365.cpu_clks);
+}
+
+void __init dm365_init_time(void)
+{
+ davinci_clk_init(dm365_clks);
+ davinci_timer_init();
}
static struct resource dm365_vpss_resources[] = {
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 6b41e1c..b409801 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -905,7 +905,6 @@ static const struct davinci_soc_info davinci_soc_info_dm644x = {
.jtag_id_reg = 0x01c40028,
.ids = dm644x_ids,
.ids_num = ARRAY_SIZE(dm644x_ids),
- .cpu_clks = dm644x_clks,
.psc_bases = dm644x_psc_bases,
.psc_bases_num = ARRAY_SIZE(dm644x_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
@@ -931,7 +930,12 @@ void __init dm644x_init(void)
{
davinci_common_init(&davinci_soc_info_dm644x);
davinci_map_sysmod();
- davinci_clk_init(davinci_soc_info_dm644x.cpu_clks);
+}
+
+void __init dm644x_init_time(void)
+{
+ davinci_clk_init(dm644x_clks);
+ davinci_timer_init();
}
int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 6fc06a6..d4d7658 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -39,12 +39,6 @@
#define VSCLKDIS_MASK (BIT_MASK(11) | BIT_MASK(10) | BIT_MASK(9) |\
BIT_MASK(8))
-/*
- * Device specific clocks
- */
-#define DM646X_REF_FREQ 27000000
-#define DM646X_AUX_FREQ 24000000
-
#define DM646X_EMAC_BASE 0x01c80000
#define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000)
#define DM646X_EMAC_CNTRL_OFFSET 0x0000
@@ -64,13 +58,12 @@ static struct pll_data pll2_data = {
static struct clk ref_clk = {
.name = "ref_clk",
- .rate = DM646X_REF_FREQ,
- .set_rate = davinci_simple_set_rate,
+ /* rate is initalized in dm646x_init_time() */
};
static struct clk aux_clkin = {
.name = "aux_clkin",
- .rate = DM646X_AUX_FREQ,
+ /* rate is initalized in dm646x_init_time() */
};
static struct clk pll1_clk = {
@@ -888,7 +881,6 @@ static const struct davinci_soc_info davinci_soc_info_dm646x = {
.jtag_id_reg = 0x01c40028,
.ids = dm646x_ids,
.ids_num = ARRAY_SIZE(dm646x_ids),
- .cpu_clks = dm646x_clks,
.psc_bases = dm646x_psc_bases,
.psc_bases_num = ARRAY_SIZE(dm646x_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
@@ -956,7 +948,15 @@ void __init dm646x_init(void)
{
davinci_common_init(&davinci_soc_info_dm646x);
davinci_map_sysmod();
- davinci_clk_init(davinci_soc_info_dm646x.cpu_clks);
+}
+
+void __init dm646x_init_time(unsigned long ref_clk_rate,
+ unsigned long aux_clkin_rate)
+{
+ ref_clk.rate = ref_clk_rate;
+ aux_clkin.rate = aux_clkin_rate;
+ davinci_clk_init(dm646x_clks);
+ davinci_timer_init();
}
static int __init dm646x_init_devices(void)
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 19b9346..f0d5e858 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -53,7 +53,6 @@ struct davinci_soc_info {
u32 jtag_id_reg;
struct davinci_id *ids;
unsigned long ids_num;
- struct clk_lookup *cpu_clks;
u32 *psc_bases;
unsigned long psc_bases_num;
u32 pinmux_base;
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 751d2ac..3481a0d 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -87,7 +87,10 @@ extern unsigned int da850_max_speed;
#define DA8XX_ARM_RAM_BASE 0xffff0000
void da830_init(void);
+void da830_init_time(void);
+
void da850_init(void);
+void da850_init_time(void);
int da830_register_edma(struct edma_rsv_info *rsv);
int da850_register_edma(struct edma_rsv_info *rsv[2]);
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 23/44] ARM: da830: add new clock init using common clock framework
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (20 preceding siblings ...)
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 ` David Lechner
2018-01-08 2:17 ` [PATCH v5 24/44] ARM: da850: " David Lechner
` (6 subsequent siblings)
28 siblings, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds the new board-specfic clock init in mach-davinci/da830.c using
the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/da830.c | 41 +++++++++++++++++++++++++++++++++++------
1 file changed, 35 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 350d767..cbb351d 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -8,23 +8,29 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
#include <linux/gpio.h>
#include <linux/init.h>
-#include <linux/clk.h>
#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach/map.h>
-#include "psc.h"
-#include <mach/irqs.h>
-#include <mach/cputype.h>
#include <mach/common.h>
-#include <mach/time.h>
+#include <mach/cputype.h>
#include <mach/da8xx.h>
+#include <mach/irqs.h>
+#include <mach/time.h>
-#include "clock.h"
#include "mux.h"
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
+
/* Offsets of the 8 compare registers on the da830 */
#define DA830_CMP12_0 0x60
#define DA830_CMP12_1 0x64
@@ -37,6 +43,7 @@
#define DA830_REF_FREQ 24000000
+#ifndef CONFIG_COMMON_CLK
static struct pll_data pll0_data = {
.num = 1,
.phys_base = DA8XX_PLL0_BASE,
@@ -432,6 +439,7 @@ static struct clk_lookup da830_clks[] = {
CLK(NULL, "rmii", &rmii_clk),
CLK(NULL, NULL, NULL),
};
+#endif
/*
* Device specific mux setup
@@ -1223,6 +1231,27 @@ void __init da830_init(void)
void __init da830_init_time(void)
{
+#ifdef CONFIG_COMMON_CLK
+ void __iomem *pll0, *psc0, *psc1;
+ struct clk *clk;
+
+ pll0 = ioremap(DA8XX_PLL0_BASE, SZ_4K);
+ psc0 = ioremap(DA8XX_PSC0_BASE, SZ_4K);
+ psc1 = ioremap(DA8XX_PSC1_BASE, SZ_4K);
+
+ clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA830_REF_FREQ);
+ da830_pll_clk_init(pll0);
+ da830_psc_clk_init(psc0, psc1);
+ clk = clk_register_fixed_factor(NULL, "i2c0", "pll0_aux_clk", 0, 1, 1);
+ clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+ clk = clk_register_fixed_factor(NULL, "timer0", "pll0_aux_clk", 0, 1, 1);
+ clk_register_clkdev(clk, "timer0", NULL);
+ clk = clk_register_fixed_factor(NULL, "timer1", "pll0_aux_clk", 0, 1, 1);
+ clk_register_clkdev(clk, NULL, "davinci-wdt");
+ clk = clk_register_fixed_factor(NULL, "rmii", "pll0_sysclk7", 0, 1, 1);
+ clk_register_clkdev(clk, "rmii", NULL);
+#else
davinci_clk_init(da830_clks);
+#endif
davinci_timer_init();
}
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 24/44] ARM: da850: add new clock init using common clock framework
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (21 preceding siblings ...)
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 ` David Lechner
[not found] ` <1515377863-20358-25-git-send-email-david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
2018-01-08 2:17 ` [PATCH v5 25/44] ARM: dm355: " David Lechner
` (5 subsequent siblings)
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds the new board-specfic clock init in mach-davinci/da850.c using
the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Some CFGCHIP* #defines are removed since they are included in the
linux/mfd/da8xx-cfgchip.h header file.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/da850.c | 74 +++++++++++++++++++++++++++++++++++--------
1 file changed, 61 insertions(+), 13 deletions(-)
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 34117e61..4804096 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -11,39 +11,44 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
+#include <linux/cpufreq.h>
#include <linux/gpio.h>
#include <linux/init.h>
-#include <linux/clk.h>
+#include <linux/log2.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_device.h>
-#include <linux/cpufreq.h>
#include <linux/regulator/consumer.h>
-#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach/map.h>
-#include "psc.h"
-#include <mach/irqs.h>
-#include <mach/cputype.h>
#include <mach/common.h>
-#include <mach/time.h>
-#include <mach/da8xx.h>
#include <mach/cpufreq.h>
+#include <mach/cputype.h>
+#include <mach/da8xx.h>
+#include <mach/irqs.h>
#include <mach/pm.h>
+#include <mach/time.h>
-#include "clock.h"
#include "mux.h"
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
+
#define DA850_PLL1_BASE 0x01e1a000
#define DA850_TIMER64P2_BASE 0x01f0c000
#define DA850_TIMER64P3_BASE 0x01f0d000
#define DA850_REF_FREQ 24000000
-#define CFGCHIP3_ASYNC3_CLKSRC BIT(4)
-#define CFGCHIP3_PLL1_MASTER_LOCK BIT(5)
-#define CFGCHIP0_PLL_MASTER_LOCK BIT(4)
-
+#ifndef CONFIG_COMMON_CLK
static int da850_set_armrate(struct clk *clk, unsigned long rate);
static int da850_round_armrate(struct clk *clk, unsigned long rate);
static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);
@@ -583,6 +588,7 @@ static struct clk_lookup da850_clks[] = {
CLK("ecap.2", "fck", &ecap2_clk),
CLK(NULL, NULL, NULL),
};
+#endif
/*
* Device specific mux setup
@@ -1170,6 +1176,7 @@ int da850_register_cpufreq(char *async_clk)
return platform_device_register(&da850_cpufreq_device);
}
+#ifndef CONFIG_COMMON_CLK
static int da850_round_armrate(struct clk *clk, unsigned long rate)
{
int ret = 0, diff;
@@ -1232,12 +1239,14 @@ static int da850_set_pll0rate(struct clk *clk, unsigned long rate)
return 0;
}
+#endif /* CONFIG_COMMON_CLK */
#else
int __init da850_register_cpufreq(char *async_clk)
{
return 0;
}
+#ifndef CONFIG_COMMON_CLK
static int da850_set_armrate(struct clk *clk, unsigned long rate)
{
return -EINVAL;
@@ -1252,6 +1261,7 @@ static int da850_round_armrate(struct clk *clk, unsigned long rate)
{
return clk->rate;
}
+#endif /* CONFIG_COMMON_CLK */
#endif
/* VPIF resource, platform data */
@@ -1395,6 +1405,44 @@ void __init da850_init(void)
void __init da850_init_time(void)
{
+#ifdef CONFIG_COMMON_CLK
+ void __iomem *pll0, *pll1, *psc0, *psc1;
+ struct clk *clk;
+ struct clk_hw *parent;
+
+ pll0 = ioremap(DA8XX_PLL0_BASE, SZ_4K);
+ pll1 = ioremap(DA850_PLL1_BASE, SZ_4K);
+ psc0 = ioremap(DA8XX_PSC0_BASE, SZ_4K);
+ psc1 = ioremap(DA8XX_PSC1_BASE, SZ_4K);
+
+ clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA850_REF_FREQ);
+ da850_pll_clk_init(pll0, pll1);
+ clk = clk_register_mux(NULL, "async3",
+ (const char * const[]){ "pll0_sysclk2", "pll1_sysclk2" },
+ 2, 0, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG),
+ ilog2(CFGCHIP3_ASYNC3_CLKSRC), 1, 0, NULL);
+ /* pll1_sysclk2 is not affected by CPU scaling, so use it for async3 */
+ parent = clk_hw_get_parent_by_index(__clk_get_hw(clk), 1);
+ if (parent)
+ clk_set_parent(clk, parent->clk);
+ else
+ pr_warn("%s: Failed to find async3 parent clock\n", __func__);
+ da850_psc_clk_init(psc0, psc1);
+ clk = clk_register_fixed_factor(NULL, "i2c0", "pll0_aux_clk", 0, 1, 1);
+ clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+ clk = clk_register_fixed_factor(NULL, "timer0", "pll0_aux_clk", 0, 1, 1);
+ clk_register_clkdev(clk, "timer0", NULL);
+ clk = clk_register_fixed_factor(NULL, "timer1", "pll0_aux_clk", 0, 1, 1);
+ clk_register_clkdev(clk, NULL, "davinci-wdt");
+ clk = clk_register_fixed_factor(NULL, "rmii", "pll0_sysclk7", 0, 1, 1);
+ clk_register_clkdev(clk, "rmii", NULL);
+ clk = clk_register_gate(NULL, "ehrpwm_tbclk", "ehrpwm", 0,
+ DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG),
+ ilog2(CFGCHIP1_TBCLKSYNC), 0, NULL);
+ clk_register_clkdev(clk, "tbclk", "ehrpwm.0");
+ clk_register_clkdev(clk, "tbclk", "ehrpwm.1");
+#else
davinci_clk_init(da850_clks);
+#endif
davinci_timer_init();
}
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 25/44] ARM: dm355: add new clock init using common clock framework
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (22 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 24/44] ARM: da850: " David Lechner
@ 2018-01-08 2:17 ` David Lechner
2018-01-08 2:17 ` [PATCH v5 26/44] ARM: dm365: " David Lechner
` (4 subsequent siblings)
28 siblings, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds the new board-specfic clock init in mach-davinci/dm355.c using
the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/dm355.c | 47 +++++++++++++++++++++++++++++++++----------
1 file changed, 36 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index f294804..f087840 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -8,31 +8,37 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
-#include <linux/init.h>
+#include <linux/clk-provider.h>
#include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
-#include <linux/spi/spi.h>
+#include <linux/init.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
#include <asm/mach/map.h>
+#include <mach/common.h>
#include <mach/cputype.h>
-#include "psc.h"
-#include <mach/mux.h>
#include <mach/irqs.h>
-#include <mach/time.h>
+#include <mach/mux.h>
#include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
+#include "asp.h"
#include "davinci.h"
-#include "clock.h"
#include "mux.h"
-#include "asp.h"
+
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
#define DM355_UART2_BASE (IO_PHYS + 0x206000)
#define DM355_OSD_BASE (IO_PHYS + 0x70200)
@@ -43,6 +49,7 @@
*/
#define DM355_REF_FREQ 24000000 /* 24 or 36 MHz */
+#ifndef CONFIG_COMMON_CLK
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
@@ -382,7 +389,7 @@ static struct clk_lookup dm355_clks[] = {
CLK(NULL, "usb", &usb_clk),
CLK(NULL, NULL, NULL),
};
-
+#endif
/*----------------------------------------------------------------------*/
static u64 dm355_spi0_dma_mask = DMA_BIT_MASK(32);
@@ -1046,7 +1053,25 @@ void __init dm355_init(void)
void __init dm355_init_time(void)
{
+#ifdef CONFIG_COMMON_CLK
+ void __iomem *pll1, *pll2, *psc;
+
+ pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_4K);
+ pll2 = ioremap(DAVINCI_PLL2_BASE, SZ_4K);
+ psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+
+ clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM355_REF_FREQ);
+ dm355_pll_clk_init(pll1, pll2);
+ dm355_psc_clk_init(psc);
+
+ /* NOTE: clkout1 can be externally gated by muxing GPIO-18 */
+ clk_register_fixed_factor(NULL, "clkout1", "pll1_aux_clk", 0, 1, 1);
+ clk_register_fixed_factor(NULL, "clkout2", "pll1_sysclkbp", 0, 1, 1);
+ /* NOTE: clkout3 can be externally gated by muxing GPIO-16 */
+ clk_register_fixed_factor(NULL, "clkout3", "pll2_sysclkbp", 0, 1, 1);
+#else
davinci_clk_init(dm355_clks);
+#endif
davinci_timer_init();
}
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 26/44] ARM: dm365: add new clock init using common clock framework
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (23 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 25/44] ARM: dm355: " David Lechner
@ 2018-01-08 2:17 ` David Lechner
2018-01-08 2:17 ` [PATCH v5 27/44] ARM: dm644x: " David Lechner
` (3 subsequent siblings)
28 siblings, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds the new board-specfic clock init in mach-davinci/dm365.c using
the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/dm365.c | 41 ++++++++++++++++++++++++++++++-----------
1 file changed, 30 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 1e3df9d..fbbe31c 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -12,32 +12,38 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-#include <linux/init.h>
+#include <linux/clk-provider.h>
#include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
-#include <linux/spi/spi.h>
+#include <linux/init.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/keyscan-davinci.h>
#include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
#include <asm/mach/map.h>
+#include <mach/common.h>
#include <mach/cputype.h>
-#include "psc.h"
-#include <mach/mux.h>
#include <mach/irqs.h>
-#include <mach/time.h>
+#include <mach/mux.h>
#include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
+#include "asp.h"
#include "davinci.h"
-#include "clock.h"
#include "mux.h"
-#include "asp.h"
+
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */
#define DM365_RTC_BASE 0x01c69000
@@ -54,6 +60,7 @@
#define DM365_EMAC_CNTRL_RAM_OFFSET 0x1000
#define DM365_EMAC_CNTRL_RAM_SIZE 0x2000
+#ifndef CONFIG_COMMON_CLK
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
@@ -485,7 +492,7 @@ static struct clk_lookup dm365_clks[] = {
CLK(NULL, "mjcp", &mjcp_clk),
CLK(NULL, NULL, NULL),
};
-
+#endif
/*----------------------------------------------------------------------*/
#define INTMUX 0x18
@@ -1171,7 +1178,19 @@ void __init dm365_init(void)
void __init dm365_init_time(void)
{
+#ifdef CONFIG_COMMON_CLK
+ void __iomem *pll1, *pll2, *psc;
+
+ pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_4K);
+ pll2 = ioremap(DAVINCI_PLL2_BASE, SZ_4K);
+ psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+
+ clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM365_REF_FREQ);
+ dm365_pll_clk_init(pll1, pll2);
+ dm365_psc_clk_init(psc);
+#else
davinci_clk_init(dm365_clks);
+#endif
davinci_timer_init();
}
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 27/44] ARM: dm644x: add new clock init using common clock framework
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (24 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 26/44] ARM: dm365: " David Lechner
@ 2018-01-08 2:17 ` David Lechner
2018-01-08 2:17 ` [PATCH v5 28/44] ARM: dm646x: " David Lechner
` (2 subsequent siblings)
28 siblings, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds the new board-specfic clock init in mach-davinci/dm644x.c using
the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/dm644x.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index b409801..bc2e243 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -8,28 +8,34 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
-#include <linux/init.h>
+#include <linux/clk-provider.h>
#include <linux/clk.h>
-#include <linux/serial_8250.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
#include <linux/dmaengine.h>
-#include <linux/platform_device.h>
+#include <linux/init.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
#include <asm/mach/map.h>
+#include <mach/common.h>
#include <mach/cputype.h>
#include <mach/irqs.h>
-#include "psc.h"
#include <mach/mux.h>
-#include <mach/time.h>
#include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
+#include "asp.h"
#include "davinci.h"
-#include "clock.h"
#include "mux.h"
-#include "asp.h"
+
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
/*
* Device specific clocks
@@ -43,6 +49,7 @@
#define DM644X_EMAC_CNTRL_RAM_OFFSET 0x2000
#define DM644X_EMAC_CNTRL_RAM_SIZE 0x2000
+#ifndef CONFIG_COMMON_CLK
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
@@ -326,6 +333,7 @@ static struct clk_lookup dm644x_clks[] = {
CLK("davinci-wdt", NULL, &timer2_clk),
CLK(NULL, NULL, NULL),
};
+#endif
static struct emac_platform_data dm644x_emac_pdata = {
.ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET,
@@ -934,7 +942,19 @@ void __init dm644x_init(void)
void __init dm644x_init_time(void)
{
+#ifdef CONFIG_COMMON_CLK
+ void __iomem *pll1, *pll2, *psc;
+
+ pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_4K);
+ pll2 = ioremap(DAVINCI_PLL2_BASE, SZ_4K);
+ psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+
+ clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM644X_REF_FREQ);
+ dm644x_pll_clk_init(pll1, pll2);
+ dm644x_psc_clk_init(psc);
+#else
davinci_clk_init(dm644x_clks);
+#endif
davinci_timer_init();
}
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 28/44] ARM: dm646x: add new clock init using common clock framework
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (25 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 27/44] ARM: dm644x: " David Lechner
@ 2018-01-08 2:17 ` David Lechner
2018-01-08 2:17 ` [PATCH v5 29/44] ARM: da8xx: add new USB PHY " David Lechner
2018-01-08 2:17 ` [PATCH v5 35/44] ARM: da850: Remove legacy clock init David Lechner
28 siblings, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds the new board-specfic clock init in mach-davinci/dm646x.c using
the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/dm646x.c | 41 +++++++++++++++++++++++++++++++++--------
1 file changed, 33 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index d4d7658..bdaf769 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -8,29 +8,35 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
#include <asm/mach/map.h>
+#include <mach/common.h>
#include <mach/cputype.h>
#include <mach/irqs.h>
-#include "psc.h"
#include <mach/mux.h>
-#include <mach/time.h>
#include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
+#include "asp.h"
#include "davinci.h"
-#include "clock.h"
#include "mux.h"
-#include "asp.h"
+
+#ifndef CONFIG_COMMON_CLK
+#include "clock.h"
+#include "psc.h"
+#endif
#define DAVINCI_VPIF_BASE (0x01C12000)
@@ -46,6 +52,7 @@
#define DM646X_EMAC_CNTRL_RAM_OFFSET 0x2000
#define DM646X_EMAC_CNTRL_RAM_SIZE 0x2000
+#ifndef CONFIG_COMMON_CLK
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
@@ -356,6 +363,7 @@ static struct clk_lookup dm646x_clks[] = {
CLK(NULL, "vpif1", &vpif1_clk),
CLK(NULL, NULL, NULL),
};
+#endif
static struct emac_platform_data dm646x_emac_pdata = {
.ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET,
@@ -953,9 +961,26 @@ void __init dm646x_init(void)
void __init dm646x_init_time(unsigned long ref_clk_rate,
unsigned long aux_clkin_rate)
{
+#ifdef CONFIG_COMMON_CLK
+ void __iomem *pll1, *pll2, *psc;
+ struct clk *clk;
+
+ pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_4K);
+ pll2 = ioremap(DAVINCI_PLL2_BASE, SZ_4K);
+ psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+
+ clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, ref_clk_rate);
+ clk_register_fixed_rate(NULL, "aux_clkin", NULL, 0, aux_clkin_rate);
+ dm646x_pll_clk_init(pll1, pll2);
+ dm646x_psc_clk_init(psc);
+ /* no LPSC, always enabled; c.f. spruep9a */
+ clk = clk_register_fixed_factor(NULL, "timer2", "pll1_sysclk3", 0, 1, 1);
+ clk_register_clkdev(clk, NULL, "davinci-wdt");
+#else
ref_clk.rate = ref_clk_rate;
aux_clkin.rate = aux_clkin_rate;
davinci_clk_init(dm646x_clks);
+#endif
davinci_timer_init();
}
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* [PATCH v5 29/44] ARM: da8xx: add new USB PHY clock init using common clock framework
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (26 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 28/44] ARM: dm646x: " David Lechner
@ 2018-01-08 2:17 ` David Lechner
2018-01-18 15:14 ` Sekhar Nori
2018-01-08 2:17 ` [PATCH v5 35/44] ARM: da850: Remove legacy clock init David Lechner
28 siblings, 1 reply; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This adds the new USB PHY clock init in mach-davinci/usb-da8xx.c using
the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/usb-da8xx.c | 84 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index d480a02..d7340670 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -2,28 +2,36 @@
/*
* DA8xx USB
*/
+#include <linux/clk-provider.h>
#include <linux/clk.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/mfd/syscon.h>
#include <linux/phy/phy.h>
#include <linux/platform_data/usb-davinci.h>
#include <linux/platform_device.h>
#include <linux/usb/musb.h>
-#include <mach/clock.h>
#include <mach/common.h>
#include <mach/cputype.h>
#include <mach/da8xx.h>
#include <mach/irqs.h>
+#ifndef CONFIG_COMMON_CLK
+#include <mach/clock.h>
#include "clock.h"
+#endif
#define DA8XX_USB0_BASE 0x01e00000
#define DA8XX_USB1_BASE 0x01e25000
+#ifndef CONFIG_COMMON_CLK
static struct clk *usb20_clk;
+#endif
static struct platform_device da8xx_usb_phy = {
.name = "da8xx-usb-phy",
@@ -128,6 +136,7 @@ int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
return platform_device_register(&da8xx_usb11_device);
}
+#ifndef CONFIG_COMMON_CLK
static struct clk usb_refclkin = {
.name = "usb_refclkin",
.set_rate = davinci_simple_set_rate,
@@ -354,3 +363,76 @@ int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
return ret;
}
+#else
+/**
+ * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
+ *
+ * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
+ * or "pll0_aux_clk" if false.
+ */
+int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
+{
+ struct regmap *cfgchip;
+ struct clk *usb0_psc_clk, *clk;
+ struct clk_hw *parent;
+
+ cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
+ if (IS_ERR(cfgchip))
+ cfgchip = syscon_regmap_lookup_by_pdevname("syscon");
+ if (IS_ERR(cfgchip))
+ return PTR_ERR(cfgchip);
+
+ usb0_psc_clk = clk_get_sys("musb-da8xx", NULL);
+ if (IS_ERR(usb0_psc_clk))
+ return PTR_ERR(usb0_psc_clk);
+
+ clk = da8xx_usb0_phy_clk_register("usb0_phy_clk", "usb_refclkin",
+ "pll0_aux_clk", usb0_psc_clk, cfgchip);
+ if (IS_ERR(clk)) {
+ clk_put(usb0_psc_clk);
+ return PTR_ERR(clk);
+ }
+
+ parent = clk_hw_get_parent_by_index(__clk_get_hw(clk),
+ use_usb_refclkin ? 0 : 1);
+ if (parent)
+ clk_set_parent(clk, parent->clk);
+ else
+ pr_warn("%s: Failed to find parent clock\n", __func__);
+
+ return clk_register_clkdev(clk, "usb20_phy", "da8xx-usb-phy");
+}
+
+/**
+ * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
+ *
+ * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
+ * or "usb0_phy_clk" if false.
+ */
+int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
+{
+ struct regmap *cfgchip;
+ struct clk *clk;
+ struct clk_hw *parent;
+
+ cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
+ if (IS_ERR(cfgchip))
+ cfgchip = syscon_regmap_lookup_by_pdevname("syscon");
+ if (IS_ERR(cfgchip))
+ return PTR_ERR(cfgchip);
+
+ clk = da8xx_usb1_phy_clk_register("usb1_phy_clk", "usb0_phy_clk",
+ "usb_refclkin", cfgchip);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ parent = clk_hw_get_parent_by_index(__clk_get_hw(clk),
+ use_usb_refclkin ? 1 : 0);
+ if (parent)
+ clk_set_parent(clk, parent->clk);
+ else
+ pr_warn("%s: Failed to find parent clock\n", __func__);
+
+ return clk_register_clkdev(clk, "usb11_phy", "da8xx-usb-phy");
+}
+#endif
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread
* Re: [PATCH v5 29/44] ARM: da8xx: add new USB PHY clock init using common clock framework
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>
0 siblings, 1 reply; 121+ messages in thread
From: Sekhar Nori @ 2018-01-18 15:14 UTC (permalink / raw)
To: David Lechner, linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Kevin Hilman, Adam Ford, linux-kernel
On Monday 08 January 2018 07:47 AM, David Lechner wrote:
> +int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
> +{
> + struct regmap *cfgchip;
> + struct clk *usb0_psc_clk, *clk;
> + struct clk_hw *parent;
> +
> + cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
Am I right in understanding that this API is only called for non-DT
boot? If yes, do we really need the lookup by compatible?
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 121+ messages in thread
* [PATCH v5 35/44] ARM: da850: Remove legacy clock init
2018-01-08 2:16 [PATCH v5 00/44] ARM: davinci: convert to common clock framework David Lechner
` (27 preceding siblings ...)
2018-01-08 2:17 ` [PATCH v5 29/44] ARM: da8xx: add new USB PHY " David Lechner
@ 2018-01-08 2:17 ` David Lechner
28 siblings, 0 replies; 121+ messages in thread
From: David Lechner @ 2018-01-08 2:17 UTC (permalink / raw)
To: linux-clk, devicetree, linux-arm-kernel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Sekhar Nori, Kevin Hilman, Adam Ford, linux-kernel,
David Lechner
This removes the unused legacy clock init code from
arch/arm/mach-davinci/da850.c.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/da850.c | 638 +-----------------------------------------
1 file changed, 1 insertion(+), 637 deletions(-)
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 4804096..a482026 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -37,559 +37,12 @@
#include "mux.h"
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#include "psc.h"
-#endif
-
#define DA850_PLL1_BASE 0x01e1a000
#define DA850_TIMER64P2_BASE 0x01f0c000
#define DA850_TIMER64P3_BASE 0x01f0d000
#define DA850_REF_FREQ 24000000
-#ifndef CONFIG_COMMON_CLK
-static int da850_set_armrate(struct clk *clk, unsigned long rate);
-static int da850_round_armrate(struct clk *clk, unsigned long rate);
-static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);
-
-static struct pll_data pll0_data = {
- .num = 1,
- .phys_base = DA8XX_PLL0_BASE,
- .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
-};
-
-static struct clk ref_clk = {
- .name = "ref_clk",
- .rate = DA850_REF_FREQ,
- .set_rate = davinci_simple_set_rate,
-};
-
-static struct clk pll0_clk = {
- .name = "pll0",
- .parent = &ref_clk,
- .pll_data = &pll0_data,
- .flags = CLK_PLL,
- .set_rate = da850_set_pll0rate,
-};
-
-static struct clk pll0_aux_clk = {
- .name = "pll0_aux_clk",
- .parent = &pll0_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll0_sysclk1 = {
- .name = "pll0_sysclk1",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-static struct clk pll0_sysclk2 = {
- .name = "pll0_sysclk2",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV2,
-};
-
-static struct clk pll0_sysclk3 = {
- .name = "pll0_sysclk3",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV3,
- .set_rate = davinci_set_sysclk_rate,
- .maxrate = 100000000,
-};
-
-static struct clk pll0_sysclk4 = {
- .name = "pll0_sysclk4",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll0_sysclk5 = {
- .name = "pll0_sysclk5",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll0_sysclk6 = {
- .name = "pll0_sysclk6",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV6,
-};
-
-static struct clk pll0_sysclk7 = {
- .name = "pll0_sysclk7",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV7,
-};
-
-static struct pll_data pll1_data = {
- .num = 2,
- .phys_base = DA850_PLL1_BASE,
- .flags = PLL_HAS_POSTDIV,
-};
-
-static struct clk pll1_clk = {
- .name = "pll1",
- .parent = &ref_clk,
- .pll_data = &pll1_data,
- .flags = CLK_PLL,
-};
-
-static struct clk pll1_aux_clk = {
- .name = "pll1_aux_clk",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclk2 = {
- .name = "pll1_sysclk2",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
- .name = "pll1_sysclk3",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV3,
-};
-
-static int da850_async3_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
-
- if (parent == &pll0_sysclk2) {
- val &= ~CFGCHIP3_ASYNC3_CLKSRC;
- } else if (parent == &pll1_sysclk2) {
- val |= CFGCHIP3_ASYNC3_CLKSRC;
- } else {
- pr_err("Bad parent on async3 clock mux\n");
- return -EINVAL;
- }
-
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
-
- return 0;
-}
-
-static struct clk async3_clk = {
- .name = "async3",
- .parent = &pll1_sysclk2,
- .set_parent = da850_async3_set_parent,
-};
-
-static struct clk i2c0_clk = {
- .name = "i2c0",
- .parent = &pll0_aux_clk,
-};
-
-static struct clk timerp64_0_clk = {
- .name = "timer0",
- .parent = &pll0_aux_clk,
-};
-
-static struct clk timerp64_1_clk = {
- .name = "timer1",
- .parent = &pll0_aux_clk,
-};
-
-static struct clk arm_rom_clk = {
- .name = "arm_rom",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_ARM_RAM_ROM,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc0_clk = {
- .name = "tpcc0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_TPCC,
- .flags = ALWAYS_ENABLED | CLK_PSC,
-};
-
-static struct clk tptc0_clk = {
- .name = "tptc0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_TPTC0,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk tptc1_clk = {
- .name = "tptc1",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_TPTC1,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc1_clk = {
- .name = "tpcc1",
- .parent = &pll0_sysclk2,
- .lpsc = DA850_LPSC1_TPCC1,
- .gpsc = 1,
- .flags = CLK_PSC | ALWAYS_ENABLED,
-};
-
-static struct clk tptc2_clk = {
- .name = "tptc2",
- .parent = &pll0_sysclk2,
- .lpsc = DA850_LPSC1_TPTC2,
- .gpsc = 1,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk pruss_clk = {
- .name = "pruss",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_PRUSS,
-};
-
-static struct clk uart0_clk = {
- .name = "uart0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_UART0,
-};
-
-static struct clk uart1_clk = {
- .name = "uart1",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_UART1,
- .gpsc = 1,
-};
-
-static struct clk uart2_clk = {
- .name = "uart2",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_UART2,
- .gpsc = 1,
-};
-
-static struct clk aintc_clk = {
- .name = "aintc",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC0_AINTC,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_GPIO,
- .gpsc = 1,
-};
-
-static struct clk i2c1_clk = {
- .name = "i2c1",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_I2C,
- .gpsc = 1,
-};
-
-static struct clk emif3_clk = {
- .name = "emif3",
- .parent = &pll0_sysclk5,
- .lpsc = DA8XX_LPSC1_EMIF3C,
- .gpsc = 1,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk arm_clk = {
- .name = "arm",
- .parent = &pll0_sysclk6,
- .lpsc = DA8XX_LPSC0_ARM,
- .flags = ALWAYS_ENABLED,
- .set_rate = da850_set_armrate,
- .round_rate = da850_round_armrate,
-};
-
-static struct clk rmii_clk = {
- .name = "rmii",
- .parent = &pll0_sysclk7,
-};
-
-static struct clk emac_clk = {
- .name = "emac",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_CPGMAC,
- .gpsc = 1,
-};
-
-/*
- * In order to avoid adding the emac_clk to the clock lookup table twice (and
- * screwing up the linked list in the process) create a separate clock for
- * mdio inheriting the rate from emac_clk.
- */
-static struct clk mdio_clk = {
- .name = "mdio",
- .parent = &emac_clk,
-};
-
-static struct clk mcasp_clk = {
- .name = "mcasp",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_McASP0,
- .gpsc = 1,
-};
-
-static struct clk mcbsp0_clk = {
- .name = "mcbsp0",
- .parent = &async3_clk,
- .lpsc = DA850_LPSC1_McBSP0,
- .gpsc = 1,
-};
-
-static struct clk mcbsp1_clk = {
- .name = "mcbsp1",
- .parent = &async3_clk,
- .lpsc = DA850_LPSC1_McBSP1,
- .gpsc = 1,
-};
-
-static struct clk lcdc_clk = {
- .name = "lcdc",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_LCDC,
- .gpsc = 1,
-};
-
-static struct clk mmcsd0_clk = {
- .name = "mmcsd0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
- .name = "mmcsd1",
- .parent = &pll0_sysclk2,
- .lpsc = DA850_LPSC1_MMC_SD1,
- .gpsc = 1,
-};
-
-static struct clk aemif_clk = {
- .name = "aemif",
- .parent = &pll0_sysclk3,
- .lpsc = DA8XX_LPSC0_EMIF25,
- .flags = ALWAYS_ENABLED,
-};
-
-/*
- * In order to avoid adding the aemif_clk to the clock lookup table twice (and
- * screwing up the linked list in the process) create a separate clock for
- * nand inheriting the rate from aemif_clk.
- */
-static struct clk aemif_nand_clk = {
- .name = "nand",
- .parent = &aemif_clk,
-};
-
-static struct clk usb11_clk = {
- .name = "usb11",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_USB11,
- .gpsc = 1,
-};
-
-static struct clk usb20_clk = {
- .name = "usb20",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_USB20,
- .gpsc = 1,
-};
-
-static struct clk cppi41_clk = {
- .name = "cppi41",
- .parent = &usb20_clk,
-};
-
-static struct clk spi0_clk = {
- .name = "spi0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_SPI0,
-};
-
-static struct clk spi1_clk = {
- .name = "spi1",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_SPI1,
- .gpsc = 1,
-};
-
-static struct clk vpif_clk = {
- .name = "vpif",
- .parent = &pll0_sysclk2,
- .lpsc = DA850_LPSC1_VPIF,
- .gpsc = 1,
-};
-
-static struct clk sata_clk = {
- .name = "sata",
- .parent = &pll0_sysclk2,
- .lpsc = DA850_LPSC1_SATA,
- .gpsc = 1,
- .flags = PSC_FORCE,
-};
-
-static struct clk dsp_clk = {
- .name = "dsp",
- .parent = &pll0_sysclk1,
- .domain = DAVINCI_GPSC_DSPDOMAIN,
- .lpsc = DA8XX_LPSC0_GEM,
- .flags = PSC_LRST | PSC_FORCE,
-};
-
-static struct clk ehrpwm_clk = {
- .name = "ehrpwm",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_PWM,
- .gpsc = 1,
-};
-
-static struct clk ehrpwm0_clk = {
- .name = "ehrpwm0",
- .parent = &ehrpwm_clk,
-};
-
-static struct clk ehrpwm1_clk = {
- .name = "ehrpwm1",
- .parent = &ehrpwm_clk,
-};
-
-#define DA8XX_EHRPWM_TBCLKSYNC BIT(12)
-
-static void ehrpwm_tblck_enable(struct clk *clk)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
- val |= DA8XX_EHRPWM_TBCLKSYNC;
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-}
-
-static void ehrpwm_tblck_disable(struct clk *clk)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
- val &= ~DA8XX_EHRPWM_TBCLKSYNC;
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-}
-
-static struct clk ehrpwm_tbclk = {
- .name = "ehrpwm_tbclk",
- .parent = &ehrpwm_clk,
- .clk_enable = ehrpwm_tblck_enable,
- .clk_disable = ehrpwm_tblck_disable,
-};
-
-static struct clk ehrpwm0_tbclk = {
- .name = "ehrpwm0_tbclk",
- .parent = &ehrpwm_tbclk,
-};
-
-static struct clk ehrpwm1_tbclk = {
- .name = "ehrpwm1_tbclk",
- .parent = &ehrpwm_tbclk,
-};
-
-static struct clk ecap_clk = {
- .name = "ecap",
- .parent = &async3_clk,
- .lpsc = DA8XX_LPSC1_ECAP,
- .gpsc = 1,
-};
-
-static struct clk ecap0_clk = {
- .name = "ecap0_clk",
- .parent = &ecap_clk,
-};
-
-static struct clk ecap1_clk = {
- .name = "ecap1_clk",
- .parent = &ecap_clk,
-};
-
-static struct clk ecap2_clk = {
- .name = "ecap2_clk",
- .parent = &ecap_clk,
-};
-
-static struct clk_lookup da850_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll0", &pll0_clk),
- CLK(NULL, "pll0_aux", &pll0_aux_clk),
- CLK(NULL, "pll0_sysclk1", &pll0_sysclk1),
- CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
- CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
- CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
- CLK(NULL, "pll0_sysclk5", &pll0_sysclk5),
- CLK(NULL, "pll0_sysclk6", &pll0_sysclk6),
- CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "async3", &async3_clk),
- CLK("i2c_davinci.1", NULL, &i2c0_clk),
- CLK(NULL, "timer0", &timerp64_0_clk),
- CLK("davinci-wdt", NULL, &timerp64_1_clk),
- CLK(NULL, "arm_rom", &arm_rom_clk),
- CLK(NULL, "tpcc0", &tpcc0_clk),
- CLK(NULL, "tptc0", &tptc0_clk),
- CLK(NULL, "tptc1", &tptc1_clk),
- CLK(NULL, "tpcc1", &tpcc1_clk),
- CLK(NULL, "tptc2", &tptc2_clk),
- CLK("pruss_uio", "pruss", &pruss_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK(NULL, "aintc", &aintc_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK("i2c_davinci.2", NULL, &i2c1_clk),
- CLK(NULL, "emif3", &emif3_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "rmii", &rmii_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &mdio_clk),
- CLK("davinci-mcasp.0", NULL, &mcasp_clk),
- CLK("davinci-mcbsp.0", NULL, &mcbsp0_clk),
- CLK("davinci-mcbsp.1", NULL, &mcbsp1_clk),
- CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
- CLK("da830-mmc.0", NULL, &mmcsd0_clk),
- CLK("da830-mmc.1", NULL, &mmcsd1_clk),
- CLK("ti-aemif", NULL, &aemif_clk),
- CLK("davinci-nand.0", "aemif", &aemif_nand_clk),
- CLK("ohci-da8xx", NULL, &usb11_clk),
- CLK("musb-da8xx", NULL, &usb20_clk),
- CLK("cppi41-dmaengine", NULL, &cppi41_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK("vpif", NULL, &vpif_clk),
- CLK("ahci_da850", "fck", &sata_clk),
- CLK("davinci-rproc.0", NULL, &dsp_clk),
- CLK(NULL, NULL, &ehrpwm_clk),
- CLK("ehrpwm.0", "fck", &ehrpwm0_clk),
- CLK("ehrpwm.1", "fck", &ehrpwm1_clk),
- CLK(NULL, NULL, &ehrpwm_tbclk),
- CLK("ehrpwm.0", "tbclk", &ehrpwm0_tbclk),
- CLK("ehrpwm.1", "tbclk", &ehrpwm1_tbclk),
- CLK(NULL, NULL, &ecap_clk),
- CLK("ecap.0", "fck", &ecap0_clk),
- CLK("ecap.1", "fck", &ecap1_clk),
- CLK("ecap.2", "fck", &ecap2_clk),
- CLK(NULL, NULL, NULL),
-};
-#endif
-
/*
* Device specific mux setup
*
@@ -964,8 +417,6 @@ static struct map_desc da850_io_desc[] = {
},
};
-static u32 da850_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
-
/* Contents of JTAG ID register used to identify exact cpu type */
static struct davinci_id da850_ids[] = {
{
@@ -1175,93 +626,11 @@ int da850_register_cpufreq(char *async_clk)
return platform_device_register(&da850_cpufreq_device);
}
-
-#ifndef CONFIG_COMMON_CLK
-static int da850_round_armrate(struct clk *clk, unsigned long rate)
-{
- int ret = 0, diff;
- unsigned int best = (unsigned int) -1;
- struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
- struct cpufreq_frequency_table *pos;
-
- rate /= 1000; /* convert to kHz */
-
- cpufreq_for_each_entry(pos, table) {
- diff = pos->frequency - rate;
- if (diff < 0)
- diff = -diff;
-
- if (diff < best) {
- best = diff;
- ret = pos->frequency;
- }
- }
-
- return ret * 1000;
-}
-
-static int da850_set_armrate(struct clk *clk, unsigned long index)
-{
- struct clk *pllclk = &pll0_clk;
-
- return clk_set_rate(pllclk, index);
-}
-
-static int da850_set_pll0rate(struct clk *clk, unsigned long rate)
-{
- struct pll_data *pll = clk->pll_data;
- struct cpufreq_frequency_table *freq;
- unsigned int prediv, mult, postdiv;
- struct da850_opp *opp = NULL;
- int ret;
-
- rate /= 1000;
-
- for (freq = da850_freq_table;
- freq->frequency != CPUFREQ_TABLE_END; freq++) {
- /* rate is in Hz, freq->frequency is in KHz */
- if (freq->frequency == rate) {
- opp = (struct da850_opp *)freq->driver_data;
- break;
- }
- }
-
- if (!opp)
- return -EINVAL;
-
- prediv = opp->prediv;
- mult = opp->mult;
- postdiv = opp->postdiv;
-
- ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
- if (WARN_ON(ret))
- return ret;
-
- return 0;
-}
-#endif /* CONFIG_COMMON_CLK */
#else
int __init da850_register_cpufreq(char *async_clk)
{
return 0;
}
-
-#ifndef CONFIG_COMMON_CLK
-static int da850_set_armrate(struct clk *clk, unsigned long rate)
-{
- return -EINVAL;
-}
-
-static int da850_set_pll0rate(struct clk *clk, unsigned long armrate)
-{
- return -EINVAL;
-}
-
-static int da850_round_armrate(struct clk *clk, unsigned long rate)
-{
- return clk->rate;
-}
-#endif /* CONFIG_COMMON_CLK */
#endif
/* VPIF resource, platform data */
@@ -1363,8 +732,6 @@ static const struct davinci_soc_info davinci_soc_info_da850 = {
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
.ids = da850_ids,
.ids_num = ARRAY_SIZE(da850_ids),
- .psc_bases = da850_psc_bases,
- .psc_bases_num = ARRAY_SIZE(da850_psc_bases),
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
.pinmux_pins = da850_pins,
.pinmux_pins_num = ARRAY_SIZE(da850_pins),
@@ -1405,7 +772,6 @@ void __init da850_init(void)
void __init da850_init_time(void)
{
-#ifdef CONFIG_COMMON_CLK
void __iomem *pll0, *pll1, *psc0, *psc1;
struct clk *clk;
struct clk_hw *parent;
@@ -1441,8 +807,6 @@ void __init da850_init_time(void)
ilog2(CFGCHIP1_TBCLKSYNC), 0, NULL);
clk_register_clkdev(clk, "tbclk", "ehrpwm.0");
clk_register_clkdev(clk, "tbclk", "ehrpwm.1");
-#else
- davinci_clk_init(da850_clks);
-#endif
+
davinci_timer_init();
}
--
2.7.4
^ permalink raw reply related [flat|nested] 121+ messages in thread