This series converts mach-davinci to use the common clock framework.
The series works like this, the first 19 patches create new clock drivers
using the common clock framework. There are basically 3 groups of clocks -
PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each have
unique init data, which is the reason for so many patches.
Then, starting with "ARM: da830: add new clock init using common clock",
we get the mach code ready for the switch by adding the code needed for
the new clock drivers and adding #ifndef CONFIG_COMMON_CLK around the
legacy clocks so that we can switch easily between the old and the new.
"ARM: davinci: switch to common clock framework" actually flips the switch
to start using the new clock drivers. Then the next 8 patches remove all
of the old clock code.
The final three patches add device tree clock support to the one SoC that
supports it.
v6 changes (also see individual patches for details):
- All of the device tree bindings are changed
- All of the clock drivers are changed significantly
- Fixed issues brought up during review of v5
- "ARM: davinci: move davinci_clk_init() to init_time" is removed from this
series and submitted separately
v5 changes:
- Basically, this is an entirely new series
- Patches are broken up into bite-sized pieces
- Converted PSC clock driver to use regmap
- Restored "force" flag for certain DA850 clocks
- Added device tree bindings
- Moved more of the clock init to drivers/clk
- Fixed frequency scaling (maybe*)
* I have frequency scaling using cpufreq-dt, so I know the clocks are doing
what they need to do to make this work, but I haven't figured out how to
test davinci-cpufreq driver yet. (Patches to make cpufreq-dt work will be
sent separately after this series has landed.)
Dependencies:
This series applies on top of linux-davinci/master plus the following patches:
- [1] "clk: fix reentrancy of clk_enable() on UP systems" (in clk-next)
- [2] "clk: add helper functions for managing clk_onecell_data"
- [3] "clk: divider: read-only divider can propagate rate change"
- [4],[5],[6],[7],[8],[9] series "ARM: davinci: common clock prep work"
You can find a working branch with everything included in the "common-clk-v6"
branch of https://github.com/dlech/ev3dev-kernel.git.
[1]: https://patchwork.kernel.org/patch/10145933/
[2]: https://patchwork.kernel.org/patch/10145873/
[3]: https://patchwork.kernel.org/patch/10146829/
[4]: https://patchwork.kernel.org/patch/10176241/
[5]: https://patchwork.kernel.org/patch/10176249/
[6]: https://patchwork.kernel.org/patch/10176245/
[7]: https://patchwork.kernel.org/patch/10176251/
[8]: https://patchwork.kernel.org/patch/10176243/
[9]: https://patchwork.kernel.org/patch/10176247/
Testing/debugging for the uninitiated:
I only have one device to test with, which is based on da850, so I will
have to rely on others to do some testing here. Since we are dealing with
clocks, if something isn't working, you most likely won't see output on
the serial port. To figure out what is going on, you need to enable...
CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y
and add "earlyprintk clk_ignore_unused" to the kernel command line options.
You may need to select a different UART for this depending on your board. I
think UART1 is the default in the kernel configuration.
On da850 devices comment out the lines:
else
clk_set_parent(clk, parent->clk);
in da850.c or, if using device tree, comment out the lines:
assigned-clocks = <&async3_clk>;
assigned-clock-parents = <&pll1_sysclk 2>;
in da850.dtsi when doing earlyprintk, otherwise the UART1 and UART2 clock
source will change during boot and cause garbled output after a point.
David Lechner (41):
dt-bindings: clock: Add new bindings for TI Davinci PLL clocks
clk: davinci: New driver for davinci PLL clocks
clk: davinci: Add platform information for TI DA830 PLL
clk: davinci: Add platform information for TI DA850 PLL
clk: davinci: Add platform information for TI DM355 PLL
clk: davinci: Add platform information for TI DM365 PLL
clk: davinci: Add platform information for TI DM644x PLL
clk: davinci: Add platform information for TI DM646x PLL
dt-bindings: clock: New bindings for TI Davinci PSC
clk: davinci: New driver for davinci PSC clocks
clk: davinci: Add platform information for TI DA830 PSC
clk: davinci: Add platform information for TI DA850 PSC
clk: davinci: Add platform information for TI DM355 PSC
clk: davinci: Add platform information for TI DM365 PSC
clk: davinci: Add platform information for TI DM644x PSC
clk: davinci: Add platform information for TI DM646x PSC
dt-bindings: clock: Add bindings for DA8XX CFGCHIP clocks
clk: davinci: New driver for TI DA8XX CFGCHIP clocks
clk: davinci: New driver for TI DA8XX USB PHY clocks
ARM: da830: add new clock init using common clock framework
ARM: da850: add new clock init using common clock framework
ARM: dm355: add new clock init using common clock framework
ARM: dm365: add new clock init using common clock framework
ARM: dm644x: add new clock init using common clock framework
ARM: dm646x: add new clock init using common clock framework
ARM: da8xx: add new USB PHY clock init using common clock framework
ARM: da8xx: add new sata_refclk init using common clock framework
ARM: davinci: remove CONFIG_DAVINCI_RESET_CLOCKS
ARM: davinci_all_defconfig: remove CONFIG_DAVINCI_RESET_CLOCKS
ARM: davinci: switch to common clock framework
ARM: da830: Remove legacy clock init
ARM: da850: Remove legacy clock init
ARM: dm355: Remove legacy clock init
ARM: dm365: Remove legacy clock init
ARM: dm644x: Remove legacy clock init
ARM: dm646x: Remove legacy clock init
ARM: da8xx: Remove legacy clock init
ARM: davinci: remove legacy clocks
ARM: davinci: add device tree support to timer
ARM: da8xx-dt: switch to device tree clocks
ARM: dts: da850: Add clocks
.../bindings/clock/ti/davinci/da8xx-cfgchip.txt | 93 +++
.../devicetree/bindings/clock/ti/davinci/pll.txt | 96 +++
.../devicetree/bindings/clock/ti/davinci/psc.txt | 66 ++
MAINTAINERS | 7 +
arch/arm/Kconfig | 2 +-
arch/arm/boot/dts/da850.dtsi | 162 ++++
arch/arm/configs/davinci_all_defconfig | 1 -
arch/arm/mach-davinci/Kconfig | 13 +-
arch/arm/mach-davinci/Makefile | 4 +-
arch/arm/mach-davinci/clock.c | 745 -------------------
arch/arm/mach-davinci/clock.h | 76 --
arch/arm/mach-davinci/common.c | 3 -
arch/arm/mach-davinci/da830.c | 440 +----------
arch/arm/mach-davinci/da850.c | 685 ++---------------
arch/arm/mach-davinci/da8xx-dt.c | 61 +-
arch/arm/mach-davinci/davinci.h | 4 +
arch/arm/mach-davinci/devices-da8xx.c | 43 +-
arch/arm/mach-davinci/devices.c | 1 -
arch/arm/mach-davinci/dm355.c | 386 +---------
arch/arm/mach-davinci/dm365.c | 472 +-----------
arch/arm/mach-davinci/dm644x.c | 318 +-------
arch/arm/mach-davinci/dm646x.c | 353 +--------
arch/arm/mach-davinci/include/mach/clock.h | 3 -
arch/arm/mach-davinci/include/mach/common.h | 8 -
arch/arm/mach-davinci/psc.c | 137 ----
arch/arm/mach-davinci/psc.h | 12 -
arch/arm/mach-davinci/time.c | 19 +-
arch/arm/mach-davinci/usb-da8xx.c | 256 ++-----
drivers/clk/Makefile | 1 +
drivers/clk/davinci/Makefile | 22 +
drivers/clk/davinci/da8xx-cfgchip.c | 305 ++++++++
drivers/clk/davinci/da8xx-usb-phy-clk.c | 312 ++++++++
drivers/clk/davinci/pll-da830.c | 51 ++
drivers/clk/davinci/pll-da850.c | 163 +++++
drivers/clk/davinci/pll-dm355.c | 66 ++
drivers/clk/davinci/pll-dm365.c | 110 +++
drivers/clk/davinci/pll-dm644x.c | 67 ++
drivers/clk/davinci/pll-dm646x.c | 63 ++
drivers/clk/davinci/pll.c | 813 +++++++++++++++++++++
drivers/clk/davinci/pll.h | 118 +++
drivers/clk/davinci/psc-da830.c | 85 +++
drivers/clk/davinci/psc-da850.c | 109 +++
drivers/clk/davinci/psc-dm355.c | 74 ++
drivers/clk/davinci/psc-dm365.c | 79 ++
drivers/clk/davinci/psc-dm644x.c | 68 ++
drivers/clk/davinci/psc-dm646x.c | 62 ++
drivers/clk/davinci/psc.c | 298 ++++++++
drivers/clk/davinci/psc.h | 88 +++
include/linux/clk/davinci.h | 37 +
49 files changed, 3683 insertions(+), 3774 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/psc.txt
delete mode 100644 arch/arm/mach-davinci/clock.c
delete mode 100644 arch/arm/mach-davinci/psc.c
create mode 100644 drivers/clk/davinci/Makefile
create mode 100644 drivers/clk/davinci/da8xx-cfgchip.c
create mode 100644 drivers/clk/davinci/da8xx-usb-phy-clk.c
create mode 100644 drivers/clk/davinci/pll-da830.c
create mode 100644 drivers/clk/davinci/pll-da850.c
create mode 100644 drivers/clk/davinci/pll-dm355.c
create mode 100644 drivers/clk/davinci/pll-dm365.c
create mode 100644 drivers/clk/davinci/pll-dm644x.c
create mode 100644 drivers/clk/davinci/pll-dm646x.c
create mode 100644 drivers/clk/davinci/pll.c
create mode 100644 drivers/clk/davinci/pll.h
create mode 100644 drivers/clk/davinci/psc-da830.c
create mode 100644 drivers/clk/davinci/psc-da850.c
create mode 100644 drivers/clk/davinci/psc-dm355.c
create mode 100644 drivers/clk/davinci/psc-dm365.c
create mode 100644 drivers/clk/davinci/psc-dm644x.c
create mode 100644 drivers/clk/davinci/psc-dm646x.c
create mode 100644 drivers/clk/davinci/psc.c
create mode 100644 drivers/clk/davinci/psc.h
create mode 100644 include/linux/clk/davinci.h
--
2.7.4
This adds a new binding for the PLL IP blocks in the mach-davinci
family of processors. Currently, only da850 has device tree support
but these bindings can also work for other SoCs in this family just
by adding new compatible strings.
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 <[email protected]>
---
v6 changes:
- Added clock-names property
- Added ti,clkmode-square-wave property
- Added pllout child node
- Added obsclk child node
- Expanded examples
.../devicetree/bindings/clock/ti/davinci/pll.txt | 96 ++++++++++++++++++++++
1 file changed, 96 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..36998e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
@@ -0,0 +1,96 @@
+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: phandles corresponding to the clock names
+- clock-names: names of the clock sources - depends on compatible string
+ - for "ti,da850-pll0", shall be "clksrc", "extclksrc"
+ - for "ti,da850-pll1", shall be "clksrc"
+
+Optional properties:
+- ti,clkmode-square-wave: Indicates that the the board is supplying a square
+ wave input on the OSCIN pin instead of using a crystal oscillator.
+ This property is only valid when compatible = "ti,da850-pll0".
+
+
+Optional child nodes:
+
+pllout
+ Describes the main PLL clock output (before POSTDIV). The node name must
+ be "pllout".
+
+ Required properties:
+ - #clock-cells: shall be 0
+
+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 index parameter for the clock cell.
+
+ Required properties:
+ - #clock-cells: shall be 1
+
+auxclk
+ Describes the AUXCLK output of the PLL. The node name must be "auxclk".
+ This child node is only valid when compatible = "ti,da850-pll0".
+
+ Required properties:
+ - #clock-cells: shall be 0
+
+obsclk
+ Describes the OBSCLK output of the PLL. The node name must be "obsclk".
+
+ Required properties:
+ - #clock-cells: shall be 0
+
+
+Examples:
+
+ pll0: clock-controller@11000 {
+ compatible = "ti,da850-pll0";
+ reg = <0x11000 0x1000>;
+ clocks = <&ref_clk>, <&pll1_sysclk 3>;
+ clock-names = "clksrc", "extclksrc";
+ ti,clkmode-square-wave;
+
+ pll0_pllout: pllout {
+ #clock-cells = <0>;
+ };
+
+ pll0_sysclk: sysclk {
+ #clock-cells = <1>;
+ };
+
+ pll0_auxclk: auxclk {
+ #clock-cells = <0>;
+ };
+
+ pll0_obsclk: obsclk {
+ #clock-cells = <0>;
+ };
+ };
+
+ pll1: clock-controller@21a000 {
+ compatible = "ti,da850-pll1";
+ reg = <0x21a000 0x1000>;
+ clocks = <&ref_clk>;
+ clock-names = "clksrc";
+
+ pll0_sysclk: sysclk {
+ #clock-cells = <1>;
+ };
+
+ pll0_obsclk: obsclk {
+ #clock-cells = <0>;
+ };
+ };
+
+Also see:
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
--
2.7.4
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 <[email protected]>
---
v6 changes:
- Added R: Sekhar Nori <[email protected]> to MAINTAINERS
- Split main PLL clock into oscdiv, prediv, pllout, postdiv and pllen clocks
- Added min/max rate checking for pllout in set_rate
- Added min/max PLLM value checking for pllout in set_rate
- Fixed sysclk set_rate (checking GOSTAT and setting GOSET)
- Added *_clk_info structs for passing controller-specific info
- Added quirks for optional PREDIV and POSTDIV registers
- Added quirk for DM355 broken PREDIV register
- Added quirk for DM365 2x PLLM register
- Handle unlocking PLL registers via CFGCHIP
- Use pr_fmt macro
MAINTAINERS | 7 +
drivers/clk/Makefile | 1 +
drivers/clk/davinci/Makefile | 5 +
drivers/clk/davinci/pll.c | 813 +++++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/pll.h | 118 +++++++
5 files changed, 944 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 95c3fa1..55e0f64 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13552,6 +13552,13 @@ 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 <[email protected]>
+R: Sekhar Nori <[email protected]>
+S: Maintained
+F: Documentation/devicetree/bindings/clock/ti/davinci/
+F: drivers/clk/davinci/
+
TI DAVINCI SERIES GPIO DRIVER
M: Keerthy <[email protected]>
L: [email protected]
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..cef78a1
--- /dev/null
+++ b/drivers/clk/davinci/pll.c
@@ -0,0 +1,813 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock driver for TI Davinci SoCs
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ *
+ * Based on arch/arm/mach-davinci/clock.c
+ * Copyright (C) 2006-2007 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ */
+
+#define pr_fmt(fmt) "%s: " fmt "\n", __func__
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/notifier.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+#define MAX_NAME_SIZE 20
+#define OSCIN_CLK_NAME "oscin"
+
+#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)
+
+/* shared by most *DIV registers */
+#define DIV_RATIO_SHIFT 0
+#define DIV_RATIO_WIDTH 5
+#define DIV_ENABLE_SHIFT 15
+
+#define PLLCMD_GOSET BIT(0)
+#define PLLSTAT_GOSTAT BIT(0)
+
+#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 (aka PLLOUT)
+ * @hw: clk_hw for the pll
+ * @base: Base memory address
+ * @pllm_min: The minimum allowable PLLM[PLLM] value
+ * @pllm_max: The maxiumum allowable PLLM[PLLM] value
+ * @pllm_mask: Bitmask for PLLM[PLLM] value
+ */
+struct davinci_pll_clk {
+ struct clk_hw hw;
+ void __iomem *base;
+ u32 pllm_min;
+ u32 pllm_max;
+ u32 pllm_mask;
+};
+
+#define to_davinci_pll_clk(_hw) \
+ container_of((_hw), struct davinci_pll_clk, hw)
+
+static unsigned long davinci_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+ unsigned long rate = parent_rate;
+ u32 mult;
+
+ mult = readl(pll->base + PLLM) & pll->pllm_mask;
+ rate *= mult + 1;
+
+ return rate;
+}
+
+static int davinci_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+ struct clk_hw *parent = req->best_parent_hw;
+ unsigned long parent_rate = req->best_parent_rate;
+ unsigned long rate = req->rate;
+ unsigned long best_rate, r;
+ u32 mult;
+
+ /* there is a limited range of valid outputs (see datasheet) */
+ if (rate < req->min_rate)
+ return -EINVAL;
+
+ rate = min(rate, req->max_rate);
+ mult = rate / parent_rate;
+ best_rate = parent_rate * mult;
+
+ /* easy case when there is no PREDIV */
+ if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
+ if (best_rate < req->min_rate)
+ return -EINVAL;
+
+ if (mult < pll->pllm_min || mult > pll->pllm_max)
+ return -EINVAL;
+
+ req->rate = best_rate;
+
+ return 0;
+ }
+
+ /* see if the PREDIV clock can help us */
+ best_rate = 0;
+
+ for (mult = pll->pllm_min; mult <= pll->pllm_max; mult++) {
+ parent_rate = clk_hw_round_rate(parent, rate / mult);
+ r = parent_rate * mult;
+ if (r < req->min_rate)
+ continue;
+ if (r > rate || r > req->max_rate)
+ break;
+ if (r > best_rate) {
+ best_rate = r;
+ req->rate = best_rate;
+ req->best_parent_rate = parent_rate;
+ if (best_rate == rate)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+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;
+
+ mult = rate / parent_rate;
+ writel(mult - 1, pll->base + PLLM);
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry);
+#else
+#define davinci_pll_debug_init NULL
+#endif
+
+static const struct clk_ops davinci_pll_ops = {
+ .recalc_rate = davinci_pll_recalc_rate,
+ .determine_rate = davinci_pll_determine_rate,
+ .set_rate = davinci_pll_set_rate,
+ .debug_init = davinci_pll_debug_init,
+};
+
+/* PLLM works differently on DM365 */
+static unsigned long dm365_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct davinci_pll_clk *pll = to_davinci_pll_clk(hw);
+ unsigned long rate = parent_rate;
+ u32 mult;
+
+ mult = readl(pll->base + PLLM) & pll->pllm_mask;
+ rate *= mult * 2;
+
+ return rate;
+}
+
+static const struct clk_ops dm365_pll_ops = {
+ .recalc_rate = dm365_pll_recalc_rate,
+ .debug_init = davinci_pll_debug_init,
+};
+
+/**
+ * davinci_pll_div_register - common *DIV clock implementation
+ * @name: the clock name
+ * @parent_name: the parent clock name
+ * @reg: the *DIV register
+ * @fixed: if true, the divider is a fixed value
+ * @flags: bitmap of CLK_* flags from clock-provider.h
+ */
+static struct clk *davinci_pll_div_register(const char *name,
+ const char *parent_name,
+ void __iomem *reg,
+ bool fixed, u32 flags)
+{
+ const char * const *parent_names = parent_name ? &parent_name : NULL;
+ int num_parents = parent_name ? 1 : 0;
+ const struct clk_ops *divider_ops = &clk_divider_ops;
+ struct clk_gate *gate;
+ struct clk_divider *divider;
+ struct clk *clk;
+
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ gate->reg = reg;
+ gate->bit_idx = DIV_ENABLE_SHIFT;
+
+ divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+ if (!divider) {
+ kfree(gate);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ divider->reg = reg;
+ divider->shift = DIV_RATIO_SHIFT;
+ divider->width = DIV_RATIO_WIDTH;
+
+ if (fixed) {
+ divider->flags |= CLK_DIVIDER_READ_ONLY;
+ divider_ops = &clk_divider_ro_ops;
+ }
+
+ clk = clk_register_composite(NULL, name, parent_names, num_parents,
+ NULL, NULL, ÷r->hw, divider_ops,
+ &gate->hw, &clk_gate_ops, flags);
+ if (IS_ERR(clk)) {
+ kfree(divider);
+ kfree(gate);
+ }
+
+ return clk;
+}
+
+struct davinci_pllen_clk {
+ struct clk_hw hw;
+ void __iomem *base;
+};
+
+#define to_davinci_pllen_clk(_hw) \
+ container_of((_hw), struct davinci_pllen_clk, hw)
+
+static const struct clk_ops davinci_pllen_ops = {
+ /* this clocks just uses the clock notification feature */
+};
+
+/*
+ * The PLL has to be switched into bypass mode while we are chaning the rate,
+ * so we do that on the PLLEN clock since it is the end of the line. This will
+ * switch to bypass before any of the parent clocks (PREDIV, PLL, POSTDIV) are
+ * changed and will switch back to the PLL after the changes have been made.
+ */
+static int davinci_pllen_rate_change(struct notifier_block *nb,
+ unsigned long flags, void *data)
+{
+ struct clk_notifier_data *cnd = data;
+ struct clk_hw *hw = __clk_get_hw(cnd->clk);
+ struct davinci_pllen_clk *pll = to_davinci_pllen_clk(hw);
+ u32 ctrl;
+
+ ctrl = readl(pll->base + PLLCTL);
+
+ if (flags == PRE_RATE_CHANGE) {
+ /* 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);
+ } else {
+ udelay(PLL_RESET_TIME);
+
+ /* Bring PLL out of reset */
+ ctrl |= PLLCTL_PLLRST;
+ writel(ctrl, pll->base + PLLCTL);
+
+ udelay(PLL_LOCK_TIME);
+
+ /* Remove PLL from bypass mode */
+ ctrl |= PLLCTL_PLLEN;
+ writel(ctrl, pll->base + PLLCTL);
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block davinci_pllen_notifier = {
+ .notifier_call = davinci_pllen_rate_change,
+};
+
+/**
+ * davinci_pll_clk_register - Register a PLL clock
+ * @info: The device-specific clock info
+ * @parent_name: The parent clock name
+ * @base: The PLL's memory region
+ *
+ * This creates a series of clocks that represent the PLL.
+ *
+ * OSCIN > [PREDIV >] PLL > [POSTDIV >] PLLEN
+ *
+ * - OSCIN is the parent clock (on secondary PLL, may come from primary PLL)
+ * - PREDIV and POSTDIV are optional (depends on the PLL controller)
+ * - PLL is the PLL output (aka PLLOUT)
+ * - PLLEN is the bypass multiplexer
+ *
+ * Returns: The PLLOUT clock or a negative error code.
+ */
+struct clk *davinci_pll_clk_register(const struct davinci_pll_clk_info *info,
+ const char *parent_name,
+ void __iomem *base)
+{
+ char prediv_name[MAX_NAME_SIZE];
+ char pllout_name[MAX_NAME_SIZE];
+ char postdiv_name[MAX_NAME_SIZE];
+ char pllen_name[MAX_NAME_SIZE];
+ struct clk_init_data init;
+ struct davinci_pll_clk *pllout;
+ struct davinci_pllen_clk *pllen;
+ struct clk *pllout_clk, *clk;
+
+ if (info->flags & PLL_HAS_OSCIN) {
+ clk = clk_register_fixed_factor(NULL, OSCIN_CLK_NAME,
+ parent_name, 0, 1, 1);
+ if (IS_ERR(clk))
+ return clk;
+
+ parent_name = OSCIN_CLK_NAME;
+ }
+
+ if (info->flags & PLL_HAS_PREDIV) {
+ bool fixed = info->flags & PLL_PREDIV_FIXED_DIV;
+ u32 flags = 0;
+
+ snprintf(prediv_name, MAX_NAME_SIZE, "%s_prediv", info->name);
+
+ if (info->flags & PLL_PREDIV_ALWAYS_ENABLED)
+ flags |= CLK_IS_CRITICAL;
+
+ /* Some? DM355 chips don't correctly report the PREDIV value */
+ if (info->flags & PLL_PREDIV_FIXED8)
+ clk = clk_register_fixed_factor(NULL, prediv_name,
+ parent_name, flags, 1, 8);
+ else
+ clk = davinci_pll_div_register(prediv_name, parent_name,
+ base + PREDIV, fixed, flags);
+ if (IS_ERR(clk))
+ return clk;
+
+ parent_name = prediv_name;
+ }
+
+ /* Unlock writing to PLL registers */
+ if (info->unlock_reg) {
+ struct regmap *cfgchip;
+
+ cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
+ if (IS_ERR(cfgchip))
+ pr_warn("Failed to get CFGCHIP (%ld)", PTR_ERR(cfgchip));
+ else
+ regmap_write_bits(cfgchip, info->unlock_reg,
+ info->unlock_mask, 0);
+ }
+
+ pllout = kzalloc(sizeof(*pllout), GFP_KERNEL);
+ if (!pllout)
+ return ERR_PTR(-ENOMEM);
+
+ snprintf(pllout_name, MAX_NAME_SIZE, "%s_pllout", info->name);
+
+ init.name = pllout_name;
+ if (info->flags & PLL_PLLM_2X)
+ init.ops = &dm365_pll_ops;
+ else
+ init.ops = &davinci_pll_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = 0;
+
+ if (info->flags & PLL_HAS_PREDIV)
+ init.flags |= CLK_SET_RATE_PARENT;
+
+ pllout->hw.init = &init;
+ pllout->base = base;
+ pllout->pllm_mask = info->pllm_mask;
+ pllout->pllm_min = info->pllm_min;
+ pllout->pllm_max = info->pllm_max;
+
+ pllout_clk = clk_register(NULL, &pllout->hw);
+ if (IS_ERR(pllout_clk)) {
+ kfree(pllout);
+ return pllout_clk;
+ }
+
+ clk_hw_set_rate_range(&pllout->hw, info->pllout_min_rate,
+ info->pllout_max_rate);
+
+ parent_name = pllout_name;
+
+ if (info->flags & PLL_HAS_POSTDIV) {
+ bool fixed = info->flags & PLL_POSTDIV_FIXED_DIV;
+ u32 flags = CLK_SET_RATE_PARENT;
+
+ snprintf(postdiv_name, MAX_NAME_SIZE, "%s_postdiv", info->name);
+
+ if (info->flags & PLL_POSTDIV_ALWAYS_ENABLED)
+ flags |= CLK_IS_CRITICAL;
+
+ clk = davinci_pll_div_register(postdiv_name, parent_name,
+ base + POSTDIV, fixed, flags);
+ if (IS_ERR(clk))
+ return clk;
+
+ parent_name = postdiv_name;
+ }
+
+ pllen = kzalloc(sizeof(*pllout), GFP_KERNEL);
+ if (!pllen)
+ return ERR_PTR(-ENOMEM);
+
+ snprintf(pllen_name, MAX_NAME_SIZE, "%s_pllen", info->name);
+
+ init.name = pllen_name;
+ init.ops = &davinci_pllen_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = CLK_SET_RATE_PARENT;
+
+ pllen->hw.init = &init;
+ pllen->base = base;
+
+ clk = clk_register(NULL, &pllen->hw);
+ if (IS_ERR(clk)) {
+ kfree(pllen);
+ return clk;
+ }
+
+ clk_notifier_register(clk, &davinci_pllen_notifier);
+
+ return pllout_clk;
+}
+
+/**
+ * davinci_pll_auxclk_register - Register bypass clock (AUXCLK)
+ * @name: The clock name
+ * @base: The PLL memory region
+ */
+struct clk *davinci_pll_auxclk_register(const char *name,
+ void __iomem *base)
+{
+ return clk_register_gate(NULL, name, OSCIN_CLK_NAME, 0, base + CKEN,
+ CKEN_AUXEN_SHIFT, 0, NULL);
+}
+
+/**
+ * davinci_pll_sysclkbp_clk_register - Register bypass divider clock (SYSCLKBP)
+ * @name: The clock name
+ * @base: The PLL memory region
+ */
+struct clk *davinci_pll_sysclkbp_clk_register(const char *name,
+ void __iomem *base)
+{
+ return clk_register_divider(NULL, name, OSCIN_CLK_NAME, 0, base + BPDIV,
+ DIV_RATIO_SHIFT, DIV_RATIO_WIDTH,
+ CLK_DIVIDER_READ_ONLY, NULL);
+}
+
+/**
+ * davinci_pll_obsclk_register - Register oscillator divider clock (OBSCLK)
+ * @info: The clock info
+ * @base: The PLL memory region
+ */
+struct clk *
+davinci_pll_obsclk_register(const struct davinci_pll_obsclk_info *info,
+ void __iomem *base)
+{
+ struct clk_mux *mux;
+ struct clk_gate *gate;
+ struct clk_divider *divider;
+ struct clk *clk;
+ u32 oscdiv;
+
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ mux->reg = base + OCSEL;
+ mux->table = info->table;
+ mux->mask = info->ocsrc_mask;
+
+ 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->shift = DIV_RATIO_SHIFT;
+ divider->width = DIV_RATIO_WIDTH;
+
+ /* make sure divider is enabled just in case bootloader disabled it */
+ oscdiv = readl(base + OSCDIV);
+ oscdiv |= BIT(DIV_ENABLE_SHIFT);
+ writel(oscdiv, base + OSCDIV);
+
+ clk = clk_register_composite(NULL, info->name, info->parent_names,
+ info->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;
+}
+
+/* The PLL SYSCLKn clocks have a mechanism for synchronizing rate changes. */
+static int davinci_pll_sysclk_rate_change(struct notifier_block *nb,
+ unsigned long flags, void *data)
+{
+ struct clk_notifier_data *cnd = data;
+ struct clk_hw *hw = __clk_get_hw(clk_get_parent(cnd->clk));
+ struct davinci_pllen_clk *pll = to_davinci_pllen_clk(hw);
+ u32 pllcmd, pllstat;
+
+ switch (flags) {
+ case POST_RATE_CHANGE:
+ /* apply the changes */
+ pllcmd = readl(pll->base + PLLCMD);
+ pllcmd |= PLLCMD_GOSET;
+ writel(pllcmd, pll->base + PLLCMD);
+ /* fallthrough */
+ case PRE_RATE_CHANGE:
+ /* Wait until for outstanding changes to take effect */
+ do {
+ pllstat = readl(pll->base + PLLSTAT);
+ } while (pllstat & PLLSTAT_GOSTAT);
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block davinci_pll_sysclk_notifier = {
+ .notifier_call = davinci_pll_sysclk_rate_change,
+};
+
+/**
+ * davinci_pll_sysclk_register - Register divider clocks (SYSCLKn)
+ * @info: The clock info
+ * @base: The PLL memory region
+ */
+struct clk *
+davinci_pll_sysclk_register(const struct davinci_pll_sysclk_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 = DIV_ENABLE_SHIFT;
+
+ divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+ if (!divider) {
+ kfree(gate);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ divider->reg = base + reg;
+ divider->shift = DIV_RATIO_SHIFT;
+ divider->width = info->ratio_width;
+ divider->flags = 0;
+
+ if (info->flags & SYSCLK_FIXED_DIV) {
+ divider->flags |= CLK_DIVIDER_READ_ONLY;
+ divider_ops = &clk_divider_ro_ops;
+ }
+
+ /* Only the ARM clock can change the parent PLL rate */
+ if (info->flags & SYSCLK_ARM_RATE)
+ flags |= CLK_SET_RATE_PARENT;
+
+ if (info->flags & SYSCLK_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);
+ }
+
+ clk_notifier_register(clk, &davinci_pll_sysclk_notifier);
+
+ return clk;
+}
+
+#ifdef CONFIG_OF
+void of_davinci_pll_init(struct device_node *node,
+ const struct davinci_pll_clk_info *info,
+ const struct davinci_pll_obsclk_info *obsclk_info,
+ const struct davinci_pll_sysclk_info *div_info,
+ u8 max_sysclk_id)
+{
+ struct device_node *child;
+ const char *parent_name;
+ void __iomem *base;
+ struct clk *clk;
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("ioremap failed");
+ return;
+ }
+
+ if (info->flags & PLL_HAS_OSCIN)
+ parent_name = of_clk_get_parent_name(node, 0);
+ else
+ parent_name = OSCIN_CLK_NAME;
+
+ clk = davinci_pll_clk_register(info, parent_name, base);
+ if (IS_ERR(clk)) {
+ pr_err("failed to register %s (%ld)", info->name, PTR_ERR(clk));
+ return;
+ }
+
+ child = of_get_child_by_name(node, "pllout");
+ if (of_device_is_available(child))
+ of_clk_add_provider(child, of_clk_src_simple_get, clk);
+ of_node_put(child);
+
+ child = of_get_child_by_name(node, "sysclk");
+ if (of_device_is_available(child)) {
+ struct clk_onecell_data *clk_data;
+
+ clk_data = clk_alloc_onecell_data(max_sysclk_id + 1);
+ if (!clk_data)
+ return;
+
+ for (; div_info->name; div_info++) {
+ clk = davinci_pll_sysclk_register(div_info, base);
+ if (IS_ERR(clk))
+ pr_warn("failed to register %s (%ld)",
+ div_info->name, PTR_ERR(clk));
+ else
+ clk_data->clks[div_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 (of_device_is_available(child)) {
+ char child_name[MAX_NAME_SIZE];
+
+ snprintf(child_name, MAX_NAME_SIZE, "%s_auxclk", info->name);
+
+ clk = davinci_pll_auxclk_register(child_name, base);
+ if (IS_ERR(clk))
+ pr_warn("failed to register %s (%ld)", child_name,
+ PTR_ERR(clk));
+ else
+ of_clk_add_provider(child, of_clk_src_simple_get, clk);
+ }
+ of_node_put(child);
+
+ child = of_get_child_by_name(node, "obsclk");
+ if (of_device_is_available(child)) {
+ if (obsclk_info)
+ clk = davinci_pll_obsclk_register(obsclk_info, base);
+ else
+ clk = ERR_PTR(-EINVAL);
+
+ if (IS_ERR(clk))
+ pr_warn("failed to register obsclk (%ld)", PTR_ERR(clk));
+ else
+ of_clk_add_provider(child, of_clk_src_simple_get, clk);
+ }
+ of_node_put(child);
+}
+#endif
+
+#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;
+}
+#endif
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
new file mode 100644
index 0000000..eff688c
--- /dev/null
+++ b/drivers/clk/davinci/pll.h
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for TI Davinci PSC controllers
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#ifndef __CLK_DAVINCI_PLL_H___
+#define __CLK_DAVINCI_PLL_H___
+
+#include <linux/bitops.h>
+#include <linux/types.h>
+
+#define PLL_HAS_OSCIN BIT(0) /* register OSCIN clock */
+#define PLL_HAS_PREDIV BIT(1) /* has prediv before PLL */
+#define PLL_PREDIV_ALWAYS_ENABLED BIT(2) /* don't clear DEN bit */
+#define PLL_PREDIV_FIXED_DIV BIT(3) /* fixed divider value */
+#define PLL_HAS_POSTDIV BIT(4) /* has postdiv after PLL */
+#define PLL_POSTDIV_ALWAYS_ENABLED BIT(5) /* don't clear DEN bit */
+#define PLL_POSTDIV_FIXED_DIV BIT(6) /* fixed divider value */
+#define PLL_HAS_EXTCLKSRC BIT(7) /* has selectable bypass */
+#define PLL_PLLM_2X BIT(8) /* PLLM value is 2x (DM365) */
+#define PLL_PREDIV_FIXED8 BIT(9) /* DM355 quirk */
+
+/** davinci_pll_clk_info - controller-specific PLL info
+ * @name: The name of the PLL
+ * @unlock_reg: Option CFGCHIP register for unlocking PLL
+ * @unlock_mask: Bitmask used with @unlock_reg
+ * @pllm_mask: Bitmask for PLLM[PLLM] value
+ * @pllm_min: Minimum allowable value for PLLM[PLLM]
+ * @pllm_max: Maximum allowable value for PLLM[PLLM]
+ * @pllout_min_rate: Minimum allowable rate for PLLOUT
+ * @pllout_max_rate: Maximum allowable rate for PLLOUT
+ * @flags: Bitmap of PLL_* flags.
+ */
+struct davinci_pll_clk_info {
+ const char *name;
+ u32 unlock_reg;
+ u32 unlock_mask;
+ u32 pllm_mask;
+ u32 pllm_min;
+ u32 pllm_max;
+ unsigned long pllout_min_rate;
+ unsigned long pllout_max_rate;
+ u32 flags;
+};
+
+#define SYSCLK_ARM_RATE BIT(0) /* Controls ARM rate */
+#define SYSCLK_ALWAYS_ENABLED BIT(1) /* Or bad things happen */
+#define SYSCLK_FIXED_DIV BIT(2) /* Fixed divider */
+
+/** davinci_pll_sysclk_info - SYSCLKn-specific info
+ * @name: The name of the clock
+ * @parent_name: The name of the parent clock
+ * @id: "n" in "SYSCLKn"
+ * @ratio_width: Width (in bits) of RATIO in PLLDIVn register
+ * @flags: Bitmap of SYSCLK_* flags.
+ */
+struct davinci_pll_sysclk_info {
+ const char *name;
+ const char *parent_name;
+ u32 id;
+ u32 ratio_width;
+ u32 flags;
+};
+
+#define SYSCLK(i, n, p, w, f) \
+{ \
+ .name = #n, \
+ .parent_name = #p, \
+ .id = (i), \
+ .ratio_width = (w), \
+ .flags = (f), \
+}
+
+/** davinci_pll_obsclk_info - OBSCLK-specific info
+ * @name: The name of the clock
+ * @parent_names: Array of names of the parent clocks
+ * @num_parents: Length of @parent_names
+ * @table: Array of values to write to OCSEL[OCSRC] cooresponding to
+ * @parent_names
+ * @ocsrc_mask: Bitmask for OCSEL[OCSRC]
+ */
+struct davinci_pll_obsclk_info {
+ const char *name;
+ const char * const *parent_names;
+ u8 num_parents;
+ u32 *table;
+ u32 ocsrc_mask;
+};
+
+struct clk;
+
+struct clk *davinci_pll_clk_register(const struct davinci_pll_clk_info *info,
+ const char *parent_name,
+ void __iomem *base);
+struct clk *davinci_pll_auxclk_register(const char *name,
+ void __iomem *base);
+struct clk *davinci_pll_sysclkbp_clk_register(const char *name,
+ void __iomem *base);
+struct clk *
+davinci_pll_obsclk_register(const struct davinci_pll_obsclk_info *info,
+ void __iomem *base);
+struct clk *
+davinci_pll_sysclk_register(const struct davinci_pll_sysclk_info *info,
+ void __iomem *base);
+
+#ifdef CONFIG_OF
+struct device_node;
+
+void of_davinci_pll_init(struct device_node *node,
+ const struct davinci_pll_clk_info *info,
+ const struct davinci_pll_obsclk_info *obsclk_info,
+ const struct davinci_pll_sysclk_info *div_info,
+ u8 max_sysclk_id);
+#endif
+
+#endif /* __CLK_DAVINCI_PLL_H___ */
--
2.7.4
This adds platform-specific declarations for the PLL clocks on TI
DM644x based systems.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- Added dm644x_pll{1,2}_info with controller-specific information
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm644x.c | 67 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 69 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..0c9b80f
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm644x.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM644X
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/bitops.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const struct davinci_pll_clk_info dm644x_pll1_info __initconst = {
+ .name = "pll1",
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 1,
+ .pllm_max = 32,
+ .pllout_min_rate = 400000000,
+ .pllout_max_rate = 600000000, /* 810MHz @ 1.3V, -810 only */
+ .flags = PLL_HAS_OSCIN | PLL_HAS_POSTDIV,
+};
+
+static const struct davinci_pll_sysclk_info dm644x_pll1_sysclk_info[] __initconst = {
+ SYSCLK(1, pll1_sysclk1, pll1_pllen, 4, SYSCLK_FIXED_DIV),
+ SYSCLK(2, pll1_sysclk2, pll1_pllen, 4, SYSCLK_FIXED_DIV),
+ SYSCLK(3, pll1_sysclk3, pll1_pllen, 4, SYSCLK_FIXED_DIV),
+ SYSCLK(5, pll1_sysclk5, pll1_pllen, 4, SYSCLK_FIXED_DIV),
+ { }
+};
+
+static const struct davinci_pll_clk_info dm644x_pll2_info __initconst = {
+ .name = "pll2",
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 1,
+ .pllm_max = 32,
+ .pllout_min_rate = 400000000,
+ .pllout_max_rate = 900000000,
+ .flags = PLL_HAS_POSTDIV | PLL_POSTDIV_FIXED_DIV,
+};
+
+static const struct davinci_pll_sysclk_info dm644x_pll2_sysclk_info[] __initconst = {
+ SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, 0),
+ SYSCLK(2, pll2_sysclk2, pll2_pllen, 4, 0),
+ { }
+};
+
+void __init dm644x_pll_clk_init(void __iomem *pll1, void __iomem *pll2)
+{
+ const struct davinci_pll_sysclk_info *info;
+
+ davinci_pll_clk_register(&dm644x_pll1_info, "ref_clk", pll1);
+
+ for (info = dm644x_pll1_sysclk_info; info->name; info++)
+ davinci_pll_sysclk_register(info, pll1);
+
+ davinci_pll_auxclk_register("pll1_auxclk", pll1);
+
+ davinci_pll_sysclkbp_clk_register("pll1_sysclkbp", pll1);
+
+ davinci_pll_clk_register(&dm644x_pll2_info, "oscin", pll2);
+
+ for (info = dm644x_pll2_sysclk_info; info->name; info++)
+ davinci_pll_sysclk_register(info, pll2);
+
+ davinci_pll_sysclkbp_clk_register("pll2_sysclkbp", 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
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 <[email protected]>
---
v6 changes:
- added clocks and clock-names properties
- expanded examples
.../devicetree/bindings/clock/ti/davinci/psc.txt | 66 ++++++++++++++++++++++
1 file changed, 66 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..0c2d2bd
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/davinci/psc.txt
@@ -0,0 +1,66 @@
+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
+- clocks: phandles to clocks corresponding to the clock-names property
+- clock-names: list of parent clock names - depends on compatible value
+ - for "ti,da850-psc0", shall be "pll0_sysclk1", "pll0_sysclk2",
+ "pll0_sysclk4", "pll0_sysclk6", "async1"
+ - for "ti,da850-psc1", shall be "pll0_sysclk2", "pll0_sysclk4", "async3"
+
+Optional properties:
+- #reset-cells: from reset binding; shall be set to 1 - only applicable when
+ at least one local domain provides a local reset.
+
+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>;
+ clocks = <&pll0_sysclk 1>, <&pll0_sysclk 2>,
+ <&pll0_sysclk 4>, <&pll0_sysclk 6>, <&async1_clk>;
+ clock_names = "pll0_sysclk1", "pll0_sysclk2",
+ "pll0_sysclk4", "pll0_sysclk6", "async1";
+ };
+ psc1: clock-controller@227000 {
+ compatible = "ti,da850-psc1";
+ reg = <0x227000 0x1000>;
+ #clock-cells = <1>;
+ clocks = <&pll0_sysclk 2>, <&pll0_sysclk 4>, <&async3_clk>;
+ clock_names = "pll0_sysclk2", "pll0_sysclk4", "async3";
+ };
+
+ /* 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
This adds platform-specific declarations for the PLL clocks on TI DA850/
OMAP-L138/AM18XX SoCs.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- Added da850_pll{0,1}_info with controller-specific information
- Added OBSCLK data
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-da850.c | 163 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 165 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..a94e1a6
--- /dev/null
+++ b/drivers/clk/davinci/pll-da850.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DA850/OMAP-L138/AM18XX
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/of.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+#define OCSEL_OCSRC_OSCIN 0x14
+#define OCSEL_OCSRC_PLL0_SYSCLK(n) (0x16 + (n))
+#define OCSEL_OCSRC_PLL1_OBSCLK 0x1e
+#define OCSEL_OCSRC_PLL1_SYSCLK(n) (0x16 + (n))
+
+static const struct davinci_pll_clk_info da850_pll0_info __initconst = {
+ .name = "pll0",
+ .unlock_reg = CFGCHIP(0),
+ .unlock_mask = CFGCHIP0_PLL_MASTER_LOCK,
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 4,
+ .pllm_max = 32,
+ .pllout_min_rate = 300000000,
+ .pllout_max_rate = 600000000,
+ .flags = PLL_HAS_OSCIN | PLL_HAS_PREDIV | PLL_HAS_POSTDIV |
+ PLL_HAS_EXTCLKSRC,
+};
+
+/*
+ * NB: Technically, the clocks flagged as SYSCLK_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_sysclk_info da850_pll0_sysclk_info[] __initconst = {
+ SYSCLK(1, pll0_sysclk1, pll0_pllen, 5, SYSCLK_FIXED_DIV),
+ SYSCLK(2, pll0_sysclk2, pll0_pllen, 5, SYSCLK_FIXED_DIV),
+ SYSCLK(3, pll0_sysclk3, pll0_pllen, 5, 0),
+ SYSCLK(4, pll0_sysclk4, pll0_pllen, 5, SYSCLK_FIXED_DIV),
+ SYSCLK(5, pll0_sysclk5, pll0_pllen, 5, 0),
+ SYSCLK(6, pll0_sysclk6, pll0_pllen, 5, SYSCLK_ARM_RATE | SYSCLK_FIXED_DIV),
+ SYSCLK(7, pll0_sysclk7, pll0_pllen, 5, 0),
+ { }
+};
+
+static const char * const da850_pll0_obsclk_parent_names[] __initconst = {
+ "oscin",
+ "pll0_sysclk1",
+ "pll0_sysclk2",
+ "pll0_sysclk3",
+ "pll0_sysclk4",
+ "pll0_sysclk5",
+ "pll0_sysclk6",
+ "pll0_sysclk7",
+ "pll1_obsclk",
+};
+
+static u32 da850_pll0_obsclk_table[] = {
+ OCSEL_OCSRC_OSCIN,
+ OCSEL_OCSRC_PLL0_SYSCLK(1),
+ OCSEL_OCSRC_PLL0_SYSCLK(2),
+ OCSEL_OCSRC_PLL0_SYSCLK(3),
+ OCSEL_OCSRC_PLL0_SYSCLK(4),
+ OCSEL_OCSRC_PLL0_SYSCLK(5),
+ OCSEL_OCSRC_PLL0_SYSCLK(6),
+ OCSEL_OCSRC_PLL0_SYSCLK(7),
+ OCSEL_OCSRC_PLL1_OBSCLK,
+};
+
+static const struct davinci_pll_obsclk_info da850_pll0_obsclk_info __initconst = {
+ .name = "pll0_obsclk",
+ .parent_names = da850_pll0_obsclk_parent_names,
+ .num_parents = ARRAY_SIZE(da850_pll0_obsclk_parent_names),
+ .table = da850_pll0_obsclk_table,
+ .ocsrc_mask = GENMASK(4, 0),
+};
+
+static const struct davinci_pll_clk_info da850_pll1_info __initconst = {
+ .name = "pll1",
+ .unlock_reg = CFGCHIP(3),
+ .unlock_mask = CFGCHIP3_PLL1_MASTER_LOCK,
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 4,
+ .pllm_max = 32,
+ .pllout_min_rate = 300000000,
+ .pllout_max_rate = 600000000,
+ .flags = PLL_HAS_POSTDIV,
+};
+
+static const struct davinci_pll_sysclk_info da850_pll1_sysclk_info[] __initconst = {
+ SYSCLK(1, pll1_sysclk1, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(2, pll1_sysclk2, pll1_pllen, 5, 0),
+ SYSCLK(3, pll1_sysclk3, pll1_pllen, 5, 0),
+ { }
+};
+
+static const char * const da850_pll1_obsclk_parent_names[] __initconst = {
+ "oscin",
+ "pll1_sysclk1",
+ "pll1_sysclk2",
+ "pll1_sysclk3",
+};
+
+static u32 da850_pll1_obsclk_table[] = {
+ OCSEL_OCSRC_OSCIN,
+ OCSEL_OCSRC_PLL1_SYSCLK(1),
+ OCSEL_OCSRC_PLL1_SYSCLK(2),
+ OCSEL_OCSRC_PLL1_SYSCLK(3),
+};
+
+static const struct davinci_pll_obsclk_info da850_pll1_obsclk_info __initconst = {
+ .name = "pll1_obsclk",
+ .parent_names = da850_pll1_obsclk_parent_names,
+ .num_parents = ARRAY_SIZE(da850_pll1_obsclk_parent_names),
+ .table = da850_pll1_obsclk_table,
+ .ocsrc_mask = GENMASK(4, 0),
+};
+
+void __init da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1)
+{
+ const struct davinci_pll_sysclk_info *info;
+
+ davinci_pll_clk_register(&da850_pll0_info, "ref_clk", pll0);
+
+ davinci_pll_auxclk_register("pll0_auxclk", pll0);
+
+ for (info = da850_pll0_sysclk_info; info->name; info++)
+ davinci_pll_sysclk_register(info, pll0);
+
+ davinci_pll_obsclk_register(&da850_pll0_obsclk_info, pll0);
+
+ davinci_pll_clk_register(&da850_pll1_info, "oscin", pll1);
+
+ for (info = da850_pll1_sysclk_info; info->name; info++)
+ davinci_pll_sysclk_register(info, pll1);
+
+ davinci_pll_obsclk_register(&da850_pll1_obsclk_info, pll1);
+}
+
+#ifdef CONFIG_OF
+static void __init of_da850_pll0_auxclk_init(struct device_node *node)
+{
+ of_davinci_pll_init(node, &da850_pll0_info, &da850_pll0_obsclk_info,
+ da850_pll0_sysclk_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, &da850_pll1_info, &da850_pll1_obsclk_info,
+ da850_pll1_sysclk_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
This adds platform-specific declarations for the PLL clocks on TI
DM365 based systems.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- Added dm365_pll{1,2}_info with controller-specific information
- Changed OBSCLK data
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm365.c | 110 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 112 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..1be7785
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm365.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM365
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/bitops.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+#define OCSEL_OCSRC_ENABLE 0
+
+static const struct davinci_pll_clk_info dm365_pll1_info __initconst = {
+ .name = "pll1",
+ .pllm_mask = GENMASK(9, 0),
+ .pllm_min = 1,
+ .pllm_max = 1023,
+ .flags = PLL_HAS_OSCIN | PLL_HAS_PREDIV | PLL_HAS_POSTDIV |
+ PLL_POSTDIV_ALWAYS_ENABLED | PLL_PLLM_2X,
+};
+
+static const struct davinci_pll_sysclk_info dm365_pll1_sysclk_info[] __initconst = {
+ SYSCLK(1, pll1_sysclk1, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(2, pll1_sysclk2, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(3, pll1_sysclk3, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(4, pll1_sysclk4, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(5, pll1_sysclk5, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(6, pll1_sysclk6, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(7, pll1_sysclk7, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(8, pll1_sysclk8, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(9, pll1_sysclk9, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ { }
+};
+
+/*
+ * This is a bit of a hack to make OCSEL[OCSRC] on DM365 look like OCSEL[OCSRC]
+ * on DA850. On DM365, OCSEL[OCSRC] is just an enable/disable bit instead of a
+ * multiplexer. By modeling it as a single parent mux clock, the clock code will
+ * still do the right thing in this case.
+ */
+static const char * const dm365_pll_obsclk_parent_names[] __initconst = {
+ "oscin",
+};
+
+static u32 dm365_pll_obsclk_table[] = {
+ OCSEL_OCSRC_ENABLE,
+};
+
+static const struct davinci_pll_obsclk_info dm365_pll1_obsclk_info __initconst = {
+ .name = "pll1_obsclk",
+ .parent_names = dm365_pll_obsclk_parent_names,
+ .num_parents = ARRAY_SIZE(dm365_pll_obsclk_parent_names),
+ .table = dm365_pll_obsclk_table,
+ .ocsrc_mask = BIT(4),
+};
+
+static const struct davinci_pll_clk_info dm365_pll2_info __initconst = {
+ .name = "pll2",
+ .pllm_mask = GENMASK(9, 0),
+ .pllm_min = 1,
+ .pllm_max = 1023,
+ .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV | PLL_POSTDIV_ALWAYS_ENABLED |
+ PLL_PLLM_2X,
+};
+
+static const struct davinci_pll_sysclk_info dm365_pll2_sysclk_info[] __initconst = {
+ SYSCLK(1, pll2_sysclk1, pll2_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(2, pll2_sysclk2, pll2_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(3, pll2_sysclk3, pll2_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(4, pll2_sysclk4, pll2_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(5, pll2_sysclk5, pll2_pllen, 5, SYSCLK_ALWAYS_ENABLED),
+ { }
+};
+
+static const struct davinci_pll_obsclk_info dm365_pll2_obsclk_info __initconst = {
+ .name = "pll2_obsclk",
+ .parent_names = dm365_pll_obsclk_parent_names,
+ .num_parents = ARRAY_SIZE(dm365_pll_obsclk_parent_names),
+ .table = dm365_pll_obsclk_table,
+ .ocsrc_mask = BIT(4),
+};
+
+void __init dm365_pll_clk_init(void __iomem *pll1, void __iomem *pll2)
+{
+ const struct davinci_pll_sysclk_info *info;
+
+ davinci_pll_clk_register(&dm365_pll1_info, "ref_clk", pll1);
+
+ davinci_pll_auxclk_register("pll1_auxclk", pll1);
+
+ davinci_pll_sysclkbp_clk_register("pll1_sysclkbp", pll1);
+
+ davinci_pll_obsclk_register(&dm365_pll1_obsclk_info, pll1);
+
+ for (info = dm365_pll1_sysclk_info; info->name; info++)
+ davinci_pll_sysclk_register(info, pll1);
+
+ davinci_pll_clk_register(&dm365_pll2_info, "oscin", pll2);
+
+ davinci_pll_auxclk_register("pll2_auxclk", pll2);
+
+ davinci_pll_obsclk_register(&dm365_pll2_obsclk_info, pll2);
+
+ for (info = dm365_pll2_sysclk_info; info->name; info++)
+ davinci_pll_sysclk_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
This adds platform-specific declarations for the PSC clocks on TI DA830/
OMAP-L137/AM17XX SoCs.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-da830.c | 85 +++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 2 +
3 files changed, 88 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..df551fa
--- /dev/null
+++ b/drivers/clk/davinci/psc-da830.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DA830/OMAP-L137/AM17XX
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV1(spi0_clkdev, NULL, "spi_davinci.0");
+LPSC_CLKDEV1(mmcsd_clkdev, NULL, "da830-mmc.0");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+
+static const struct davinci_psc_clk_info da830_psc0_info[] __initconst = {
+ LPSC(0, 0, tpcc, 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, aemif, pll0_sysclk3, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(4, 0, spi0, pll0_sysclk2, spi0_clkdev, 0),
+ LPSC(5, 0, mmcsd, pll0_sysclk2, mmcsd_clkdev, 0),
+ LPSC(6, 0, aintc, pll0_sysclk4, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, arm_rom, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(8, 0, secu_mgr, pll0_sysclk4, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(9, 0, uart0, pll0_sysclk2, uart0_clkdev, 0),
+ LPSC(10, 0, scr0_ss, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(11, 0, scr1_ss, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(12, 0, scr2_ss, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(13, 0, pruss, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(14, 0, arm, pll0_sysclk6, NULL, LPSC_ALWAYS_ENABLED),
+ { }
+};
+
+LPSC_CLKDEV2(usb0_clkdev, NULL, "musb-da8xx",
+ NULL, "cppi41-dmaengine");
+LPSC_CLKDEV1(usb1_clkdev, NULL, "ohci-da8xx");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
+ "fck", "davinci_mdio.0");
+LPSC_CLKDEV1(mcasp0_clkdev, NULL, "davinci-mcasp.0");
+LPSC_CLKDEV1(mcasp1_clkdev, NULL, "davinci-mcasp.1");
+LPSC_CLKDEV1(mcasp2_clkdev, NULL, "davinci-mcasp.2");
+LPSC_CLKDEV1(spi1_clkdev, NULL, "spi_davinci.1");
+LPSC_CLKDEV1(i2c1_clkdev, NULL, "i2c_davinci.2");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(uart2_clkdev, NULL, "serial8250.2");
+LPSC_CLKDEV1(lcdc_clkdev, "fck", "da8xx_lcdc.0");
+LPSC_CLKDEV2(pwm_clkdev, "fck", "ehrpwm.0",
+ "fck", "ehrpwm.1");
+LPSC_CLKDEV3(ecap_clkdev, "fck", "ecap.0",
+ "fck", "ecap.1",
+ "fck", "ecap.2");
+LPSC_CLKDEV2(eqep_clkdev, NULL, "eqep.0",
+ NULL, "eqep.1");
+
+static const struct davinci_psc_clk_info da830_psc1_info[] __initconst = {
+ LPSC(1, 0, usb0, pll0_sysclk2, usb0_clkdev, 0),
+ LPSC(2, 0, usb1, pll0_sysclk4, usb1_clkdev, 0),
+ LPSC(3, 0, gpio, pll0_sysclk4, gpio_clkdev, 0),
+ LPSC(5, 0, emac, pll0_sysclk4, emac_clkdev, 0),
+ LPSC(6, 0, emif3, pll0_sysclk5, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, mcasp0, pll0_sysclk2, mcasp0_clkdev, 0),
+ LPSC(8, 0, mcasp1, pll0_sysclk2, mcasp1_clkdev, 0),
+ LPSC(9, 0, mcasp2, pll0_sysclk2, mcasp2_clkdev, 0),
+ LPSC(10, 0, spi1, pll0_sysclk2, spi1_clkdev, 0),
+ LPSC(11, 0, i2c1, pll0_sysclk4, i2c1_clkdev, 0),
+ LPSC(12, 0, uart1, pll0_sysclk2, uart1_clkdev, 0),
+ LPSC(13, 0, uart2, pll0_sysclk2, uart2_clkdev, 0),
+ LPSC(16, 0, lcdc, pll0_sysclk2, lcdc_clkdev, 0),
+ LPSC(17, 0, pwm, pll0_sysclk2, pwm_clkdev, 0),
+ LPSC(20, 0, ecap, pll0_sysclk2, ecap_clkdev, 0),
+ LPSC(21, 0, eqep, pll0_sysclk2, eqep_clkdev, 0),
+ { }
+};
+
+void __init da830_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
+{
+ davinci_psc_register_clocks(da830_psc0_info, psc0);
+ davinci_psc_register_clocks(da830_psc1_info, psc1);
+}
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
The common clock framework will take care of disabling unused clocks when
we switch from the legacy davinci clocks and having this enabled will
cause compile errors after we switch, so remove it now.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- none
arch/arm/mach-davinci/Kconfig | 12 ------------
arch/arm/mach-davinci/common.c | 1 -
arch/arm/mach-davinci/include/mach/common.h | 6 ------
3 files changed, 19 deletions(-)
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index 05c3eecf..ba9912b 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -231,18 +231,6 @@ config DAVINCI_MUX_WARNINGS
to change the pin multiplexing setup. When there are no warnings
printed, it's safe to deselect DAVINCI_MUX for your product.
-config DAVINCI_RESET_CLOCKS
- bool "Reset unused clocks during boot"
- depends on ARCH_DAVINCI
- help
- Say Y if you want to reset unused clocks during boot.
- This option saves power, but assumes all drivers are
- using the clock framework. Broken drivers that do not
- yet use clock framework may not work with this option.
- If you are booting from another operating system, you
- probably do not want this option enabled until your
- device drivers work properly.
-
endmenu
endif
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index bcb6a7b..e03f95c 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -118,5 +118,4 @@ void __init davinci_common_init(const struct davinci_soc_info *soc_info)
void __init davinci_init_late(void)
{
davinci_cpufreq_init();
- davinci_clk_disable_unused();
}
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index f0d5e858..c86a058 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -82,12 +82,6 @@ extern void davinci_common_init(const struct davinci_soc_info *soc_info);
extern void davinci_init_ide(void);
void davinci_init_late(void);
-#ifdef CONFIG_DAVINCI_RESET_CLOCKS
-int davinci_clk_disable_unused(void);
-#else
-static inline int davinci_clk_disable_unused(void) { return 0; }
-#endif
-
#ifdef CONFIG_CPU_FREQ
int davinci_cpufreq_init(void);
#else
--
2.7.4
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 <[email protected]>
---
v6 changes:
- use GENMASK
- add quirk flag for FORCE bit
- add quirk flag for propagating set_rate
- fix writing to PDSTAT instead of PDCTL
- remove unused doc comment parameter
- change davinci_psc_register_clocks() to handle registering clkdev entries
drivers/clk/davinci/Makefile | 2 +
drivers/clk/davinci/psc.c | 298 +++++++++++++++++++++++++++++++++++++++++++
drivers/clk/davinci/psc.h | 88 +++++++++++++
3 files changed, 388 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..6d969c4
--- /dev/null
+++ b/drivers/clk/davinci/psc.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for TI Davinci PSC controllers
+ *
+ * Copyright (C) 2017 David Lechner <[email protected]>
+ *
+ * Based on: drivers/clk/keystone/gate.c
+ * Copyright (C) 2013 Texas Instruments.
+ * Murali Karicheri <[email protected]>
+ * Santosh Shilimkar <[email protected]>
+ *
+ * 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 GENMASK(5, 0)
+#define MDSTAT_MCKOUT BIT(12)
+#define PDSTAT_STATE_MASK GENMASK(4, 0)
+#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, ptstat;
+
+ regmap_write_bits(psc->regmap, MDCTL(psc->lpsc), MDSTAT_STATE_MASK,
+ next_state);
+
+ if (psc->flags & LPSC_FORCE)
+ regmap_write_bits(psc->regmap, MDCTL(psc->lpsc), MDCTL_FORCE,
+ MDCTL_FORCE);
+
+ regmap_read(psc->regmap, PDSTAT(psc->pd), &pdstat);
+ if ((pdstat & PDSTAT_STATE_MASK) == 0) {
+ regmap_write_bits(psc->regmap, PDCTL(psc->pd), PDCTL_NEXT,
+ 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
+ * @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 = 0;
+
+ if (flags & LPSC_ALWAYS_ENABLED)
+ init.flags |= CLK_IS_CRITICAL;
+
+ if (flags & LPSC_ARM_RATE)
+ init.flags |= CLK_SET_RATE_PARENT;
+
+ 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,
+};
+
+/**
+ * __davinci_psc_register_clocks - Register array of PSC clocks
+ * @info: Array of clock-specific data
+ * @base: The memory mapped region of the PSC IP block
+ * @clk_data: Optional location for storing clocks (for device tree usage)
+ *
+ * If provided, @clk_data is provided, it will be populated with clocks. If it
+ * is NULL, that means we are not using device tree, so clkdev entries are
+ * registered instead.
+ */
+int __davinci_psc_register_clocks(const struct davinci_psc_clk_info *info,
+ void __iomem *base,
+ struct clk_onecell_data *clk_data)
+{
+ struct regmap *regmap;
+
+ regmap = regmap_init_mmio(NULL, base, &davinci_psc_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ for (; info->name; info++) {
+ const struct davinci_psc_clkdev_info *cdevs = info->cdevs;
+ 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;
+ }
+
+ if (clk_data) {
+ clk_data->clks[info->lpsc] = clk;
+ } else if (cdevs) {
+ for (; cdevs->con_id || cdevs->dev_id; cdevs++)
+ clk_register_clkdev(clk, cdevs->con_id,
+ cdevs->dev_id);
+ }
+ }
+
+ return 0;
+}
+
+int davinci_psc_register_clocks(const struct davinci_psc_clk_info *info,
+ void __iomem *base)
+{
+ return __davinci_psc_register_clocks(info, base, NULL);
+}
+
+#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 = clk_alloc_onecell_data(num_clks);
+ if (!clk_data)
+ return;
+
+ __davinci_psc_register_clocks(info, base, clk_data);
+
+ 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..ae02daa
--- /dev/null
+++ b/drivers/clk/davinci/psc.h
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for TI Davinci PSC controllers
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#ifndef __CLK_DAVINCI_PSC_H__
+#define __CLK_DAVINCI_PSC_H__
+
+#include <linux/clk-provider.h>
+#include <linux/types.h>
+
+/* PSC quirk flags */
+#define LPSC_ALWAYS_ENABLED BIT(0) /* never disable this clock */
+#define LPSC_ARM_RATE BIT(1) /* propagate set_rate to PLL */
+#define LPSC_FORCE BIT(2) /* requires MDCTL FORCE bit */
+#define LPSC_LOCAL_RESET BIT(3) /* acts as reset provider */
+
+struct davinci_psc_clkdev_info {
+ const char *con_id;
+ const char *dev_id;
+};
+
+#define LPSC_CLKDEV(c, d) { \
+ .con_id = (c), \
+ .dev_id = (d) \
+}
+
+#define LPSC_CLKDEV1(n, c, d) \
+static const struct davinci_psc_clkdev_info n[] __initconst = { \
+ LPSC_CLKDEV((c), (d)), \
+ { } \
+}
+
+#define LPSC_CLKDEV2(n, c1, d1, c2, d2) \
+static const struct davinci_psc_clkdev_info n[] __initconst = { \
+ LPSC_CLKDEV((c1), (d1)), \
+ LPSC_CLKDEV((c2), (d2)), \
+ { } \
+}
+
+#define LPSC_CLKDEV3(n, c1, d1, c2, d2, c3, d3) \
+static const struct davinci_psc_clkdev_info n[] __initconst = { \
+ LPSC_CLKDEV((c1), (d1)), \
+ LPSC_CLKDEV((c2), (d2)), \
+ LPSC_CLKDEV((c3), (d3)), \
+ { } \
+}
+
+/**
+ * davinci_psc_clk_info - LPSC module-specific clock information
+ * @name: the clock name
+ * @parent: the parent clock name
+ * @cdevs: optional array of clkdev lookup table info
+ * @lpsc: the local module domain id (LPSC)
+ * @pd: the power domain id
+ * @flags: bitmask of LPSC_* flags
+ */
+struct davinci_psc_clk_info {
+ const char *name;
+ const char *parent;
+ const struct davinci_psc_clkdev_info *cdevs;
+ u32 lpsc;
+ u32 pd;
+ unsigned long flags;
+};
+
+#define LPSC(l, d, n, p, c, f) \
+{ \
+ .name = #n, \
+ .parent = #p, \
+ .cdevs = (c), \
+ .lpsc = (l), \
+ .pd = (d), \
+ .flags = (f), \
+}
+
+int davinci_psc_register_clocks(const struct davinci_psc_clk_info *info,
+ void __iomem *base);
+
+#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
This adds platform-specific declarations for the PSC clocks on TI DA850/
OMAP-L138/AM18XX SoCs.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-da850.c | 109 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 111 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..df36e1c
--- /dev/null
+++ b/drivers/clk/davinci/psc-da850.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DA850/OMAP-L138/AM18XX
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV2(emifa_clkdev, NULL, "ti-aemif",
+ "aemif", "davinci-nand.0");
+LPSC_CLKDEV1(spi0_clkdev, NULL, "spi_davinci.0");
+LPSC_CLKDEV1(mmcsd0_clkdev, NULL, "da830-mmc.0");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+/* REVISIT: used dev_id instead of con_id */
+LPSC_CLKDEV1(arm_clkdev, "arm", NULL);
+LPSC_CLKDEV1(dsp_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, emifa_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),
+ { }
+};
+
+LPSC_CLKDEV2(usb0_clkdev, NULL, "musb-da8xx",
+ NULL, "cppi41-dmaengine");
+LPSC_CLKDEV1(usb1_clkdev, NULL, "ohci-da8xx");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
+ "fck", "davinci_mdio.0");
+LPSC_CLKDEV1(mcasp0_clkdev, NULL, "davinci-mcasp.0");
+LPSC_CLKDEV1(sata_clkdev, "fck", "ahci_da850");
+LPSC_CLKDEV1(vpif_clkdev, NULL, "vpif");
+LPSC_CLKDEV1(spi1_clkdev, NULL, "spi_davinci.1");
+LPSC_CLKDEV1(i2c1_clkdev, NULL, "i2c_davinci.2");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(uart2_clkdev, NULL, "serial8250.2");
+LPSC_CLKDEV1(mcbsp0_clkdev, NULL, "davinci-mcbsp.0");
+LPSC_CLKDEV1(mcbsp1_clkdev, NULL, "davinci-mcbsp.1");
+LPSC_CLKDEV1(lcdc_clkdev, "fck", "da8xx_lcdc.0");
+LPSC_CLKDEV2(ehrpwm_clkdev, "fck", "ehrpwm.0",
+ "fck", "ehrpwm.1");
+LPSC_CLKDEV1(mmcsd1_clkdev, NULL, "da830-mmc.1");
+LPSC_CLKDEV3(ecap_clkdev, "fck", "ecap.0",
+ "fck", "ecap.1",
+ "fck", "ecap.2");
+
+static const struct davinci_psc_clk_info da850_psc1_info[] __initconst = {
+ LPSC(0, 0, tpcc1, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(1, 0, usb0, pll0_sysclk2, usb0_clkdev, 0),
+ LPSC(2, 0, usb1, pll0_sysclk4, usb1_clkdev, 0),
+ LPSC(3, 0, gpio, pll0_sysclk4, gpio_clkdev, 0),
+ LPSC(5, 0, emac, pll0_sysclk4, emac_clkdev, 0),
+ LPSC(6, 0, ddr, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, mcasp0, async3, mcasp0_clkdev, 0),
+ LPSC(8, 0, sata, pll0_sysclk2, sata_clkdev, LPSC_FORCE),
+ LPSC(9, 0, vpif, pll0_sysclk2, vpif_clkdev, 0),
+ LPSC(10, 0, spi1, async3, spi1_clkdev, 0),
+ LPSC(11, 0, i2c1, pll0_sysclk4, i2c1_clkdev, 0),
+ LPSC(12, 0, uart1, async3, uart1_clkdev, 0),
+ LPSC(13, 0, uart2, async3, uart2_clkdev, 0),
+ LPSC(14, 0, mcbsp0, async3, mcbsp0_clkdev, 0),
+ LPSC(15, 0, mcbsp1, async3, mcbsp1_clkdev, 0),
+ LPSC(16, 0, lcdc, pll0_sysclk2, lcdc_clkdev, 0),
+ LPSC(17, 0, ehrpwm, async3, ehrpwm_clkdev, 0),
+ LPSC(18, 0, mmcsd1, pll0_sysclk2, mmcsd1_clkdev, 0),
+ LPSC(20, 0, ecap, async3, ecap_clkdev, 0),
+ LPSC(21, 0, tptc2, pll0_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ { }
+};
+
+void __init da850_psc_clk_init(void __iomem *psc0, void __iomem *psc1)
+{
+ davinci_psc_register_clocks(da850_psc0_info, psc0);
+ davinci_psc_register_clocks(da850_psc1_info, psc1);
+}
+
+#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
This adds platform-specific declarations for the PLL clocks on TI
DM646x based systems.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- Added dm646x_pll{1,2}_info with controller-specific information
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm646x.c | 63 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 65 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..2d58d11
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm646x.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM646X
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const struct davinci_pll_clk_info dm646x_pll1_info __initconst = {
+ .name = "pll1",
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 14,
+ .pllm_max = 32,
+ .flags = PLL_HAS_OSCIN,
+};
+
+static const struct davinci_pll_sysclk_info dm646x_pll1_sysclk_info[] __initconst = {
+ SYSCLK(1, pll1_sysclk1, pll1_pllen, 4, SYSCLK_FIXED_DIV),
+ SYSCLK(2, pll1_sysclk2, pll1_pllen, 4, SYSCLK_FIXED_DIV),
+ SYSCLK(3, pll1_sysclk3, pll1_pllen, 4, SYSCLK_FIXED_DIV),
+ SYSCLK(4, pll1_sysclk4, pll1_pllen, 4, 0),
+ SYSCLK(5, pll1_sysclk5, pll1_pllen, 4, 0),
+ SYSCLK(6, pll1_sysclk6, pll1_pllen, 4, 0),
+ SYSCLK(8, pll1_sysclk8, pll1_pllen, 4, 0),
+ SYSCLK(9, pll1_sysclk9, pll1_pllen, 4, 0),
+ { }
+};
+
+static const struct davinci_pll_clk_info dm646x_pll2_info __initconst = {
+ .name = "pll2",
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 14,
+ .pllm_max = 32,
+ .flags = 0,
+};
+
+static const struct davinci_pll_sysclk_info dm646x_pll2_sysclk_info[] __initconst = {
+ SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, 0),
+ { }
+};
+
+void __init dm646x_pll_clk_init(void __iomem *pll1, void __iomem *pll2)
+{
+ const struct davinci_pll_sysclk_info *info;
+
+ davinci_pll_clk_register(&dm646x_pll1_info, "ref_clk", pll1);
+
+ for (info = dm646x_pll1_sysclk_info; info->name; info++)
+ davinci_pll_sysclk_register(info, pll1);
+
+ davinci_pll_sysclkbp_clk_register("pll1_sysclkbp", pll1);
+
+ davinci_pll_auxclk_register("pll1_auxclk", pll1);
+
+ davinci_pll_clk_register(&dm646x_pll2_info, "oscin", pll2);
+
+ for (info = dm646x_pll2_sysclk_info; info->name; info++)
+ davinci_pll_sysclk_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
This adds the new SATA REFCLK clock init in mach-davinci/devices-da8xx.c
using the new common clock framework drivers.
The #ifdefs are needed to prevent compile errors until the entire
ARCH_DAVINCI is converted.
Also, the #includes are sorted since we are adding some here.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- none (can you believe it?)
arch/arm/mach-davinci/devices-da8xx.c | 36 ++++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 44cda0a..1a06b09 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -10,26 +10,31 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
+#include <linux/ahci_platform.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/dma-contiguous.h>
+#include <linux/dmaengine.h>
#include <linux/init.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
-#include <linux/dma-contiguous.h>
-#include <linux/serial_8250.h>
-#include <linux/ahci_platform.h>
-#include <linux/clk.h>
#include <linux/reboot.h>
-#include <linux/dmaengine.h>
+#include <linux/serial_8250.h>
-#include <mach/cputype.h>
#include <mach/common.h>
-#include <mach/time.h>
+#include <mach/cputype.h>
#include <mach/da8xx.h>
-#include <mach/clock.h>
+#include <mach/time.h>
+
+#include "asp.h"
#include "cpuidle.h"
#include "sram.h"
+#ifndef CONFIG_COMMON_CLK
+#include <mach/clock.h>
#include "clock.h"
-#include "asp.h"
+#endif
#define DA8XX_TPCC_BASE 0x01c00000
#define DA8XX_TPTC0_BASE 0x01c08000
@@ -1041,6 +1046,7 @@ int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect)
}
#ifdef CONFIG_ARCH_DAVINCI_DA850
+#ifndef CONFIG_COMMON_CLK
static struct clk sata_refclk = {
.name = "sata_refclk",
.set_rate = davinci_simple_set_rate,
@@ -1062,6 +1068,18 @@ int __init da850_register_sata_refclk(int rate)
return 0;
}
+#else
+int __init da850_register_sata_refclk(int rate)
+{
+ struct clk *clk;
+
+ clk = clk_register_fixed_rate(NULL, "sata_refclk", NULL, 0, rate);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ return clk_register_clkdev(clk, "refclk", "ahci_da850");
+}
+#endif
static struct resource da850_sata_resources[] = {
{
--
2.7.4
This adds platform-specific declarations for the PLL clocks on TI DA830/
OMAP-L137/AM17XX SoCs.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- Added da830_pll_info with controller-specific information
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-da830.c | 51 +++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 14 +++++++++++
3 files changed, 66 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..548eb73
--- /dev/null
+++ b/drivers/clk/davinci/pll-da830.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DA830/OMAP-L137/AM17XX
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/bitops.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const struct davinci_pll_clk_info da830_pll_info __initconst = {
+ .name = "pll0",
+ .pllm_mask = GENMASK(4, 0),
+ .pllm_min = 4,
+ .pllm_max = 32,
+ .pllout_min_rate = 300000000,
+ .pllout_max_rate = 600000000,
+ .flags = PLL_HAS_OSCIN | PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
+};
+
+/*
+ * NB: Technically, the clocks flagged as SYSCLK_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_sysclk_info da830_pll_sysclk_info[] __initconst = {
+ SYSCLK(2, pll0_sysclk2, pll0_pllen, 5, SYSCLK_FIXED_DIV),
+ SYSCLK(3, pll0_sysclk3, pll0_pllen, 5, 0),
+ SYSCLK(4, pll0_sysclk4, pll0_pllen, 5, SYSCLK_FIXED_DIV),
+ SYSCLK(5, pll0_sysclk5, pll0_pllen, 5, 0),
+ SYSCLK(6, pll0_sysclk6, pll0_pllen, 5, SYSCLK_FIXED_DIV),
+ SYSCLK(7, pll0_sysclk7, pll0_pllen, 5, 0),
+ { }
+};
+
+void __init da830_pll_clk_init(void __iomem *pll)
+{
+ const struct davinci_pll_sysclk_info *info;
+
+ davinci_pll_clk_register(&da830_pll_info, "ref_clk", pll);
+
+ davinci_pll_auxclk_register("pll0_auxclk", pll);
+
+ for (info = da830_pll_sysclk_info; info->name; info++)
+ davinci_pll_sysclk_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 <[email protected]>
+ */
+#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
This adds platform-specific declarations for the PSC clocks on TI
DM355 based systems.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm355.c | 74 +++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 76 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..1074be4
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm355.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM355
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV1(vpss_master_clkdev, "master", "vpss");
+LPSC_CLKDEV1(vpss_slave_clkdev, "slave", "vpss");
+LPSC_CLKDEV1(spi1_clkdev, NULL, "spi_davinci.1");
+LPSC_CLKDEV1(mmcsd1_clkdev, NULL, "dm6441-mmc.1");
+LPSC_CLKDEV1(mcbsp1_clkdev, NULL, "davinci-mcbsp.1");
+LPSC_CLKDEV1(usb_clkdev, "usb", NULL);
+LPSC_CLKDEV1(spi2_clkdev, NULL, "spi_davinci.2");
+LPSC_CLKDEV1(aemif_clkdev, "aemif", NULL);
+LPSC_CLKDEV1(mmcsd0_clkdev, NULL, "dm6441-mmc.0");
+LPSC_CLKDEV1(mcbsp0_clkdev, NULL, "davinci-mcbsp.0");
+LPSC_CLKDEV1(i2c_clkdev, NULL, "i2c_davinci.1");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(uart2_clkdev, NULL, "serial8250.2");
+LPSC_CLKDEV1(spi0_clkdev, NULL, "spi_davinci.0");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV1(timer0_clkdev, "timer0", NULL);
+LPSC_CLKDEV1(timer2_clkdev, NULL, "davinci-wdt");
+LPSC_CLKDEV1(vpss_dac_clkdev, "vpss_dac", NULL);
+
+static const struct davinci_psc_clk_info dm355_psc_info[] __initconst = {
+ LPSC(0, 0, vpss_master, pll1_sysclk4, vpss_master_clkdev, 0),
+ LPSC(1, 0, vpss_slave, pll1_sysclk4, vpss_slave_clkdev, 0),
+ LPSC(5, 0, timer3, pll1_auxclk, NULL, 0),
+ LPSC(6, 0, spi1, pll1_sysclk2, spi1_clkdev, 0),
+ LPSC(7, 0, mmcsd1, pll1_sysclk2, mmcsd1_clkdev, 0),
+ LPSC(8, 0, asp1, pll1_sysclk2, NULL, 0),
+ LPSC(9, 0, usb, pll1_sysclk2, usb_clkdev, 0),
+ LPSC(10, 0, pwm3, pll1_auxclk, NULL, 0),
+ LPSC(11, 0, spi2, pll1_sysclk2, spi2_clkdev, 0),
+ LPSC(12, 0, rto, pll1_auxclk, NULL, 0),
+ LPSC(14, 0, aemif, pll1_sysclk2, aemif_clkdev, 0),
+ LPSC(15, 0, mmcsd0, pll1_sysclk2, mmcsd0_clkdev, 0),
+ LPSC(17, 0, asp0, pll1_sysclk2, NULL, 0),
+ LPSC(18, 0, i2c, pll1_auxclk, i2c_clkdev, 0),
+ LPSC(19, 0, uart0, pll1_auxclk, uart0_clkdev, 0),
+ LPSC(20, 0, uart1, pll1_auxclk, uart1_clkdev, 0),
+ LPSC(21, 0, uart2, pll1_sysclk2, uart2_clkdev, 0),
+ LPSC(22, 0, spi0, pll1_sysclk2, spi0_clkdev, 0),
+ LPSC(23, 0, pwm0, pll1_auxclk, NULL, 0),
+ LPSC(24, 0, pwm1, pll1_auxclk, NULL, 0),
+ LPSC(25, 0, pwm2, pll1_auxclk, NULL, 0),
+ LPSC(26, 0, gpio, pll1_sysclk2, gpio_clkdev, 0),
+ LPSC(27, 0, timer0, pll1_auxclk, timer0_clkdev, 0),
+ LPSC(28, 0, timer1, pll1_auxclk, NULL, 0),
+ /* REVISIT: why can't this be disabled? */
+ LPSC(29, 0, timer2, pll1_auxclk, timer2_clkdev,
+ LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, arm, pll1_sysclk1, NULL,
+ LPSC_ALWAYS_ENABLED),
+ LPSC(40, 0, mjcp, pll1_sysclk1, NULL, 0),
+ LPSC(41, 0, vpss_dac, pll1_sysclk3, vpss_dac_clkdev, 0),
+ { }
+};
+
+void __init dm355_psc_clk_init(void __iomem *psc)
+{
+ davinci_psc_register_clocks(dm355_psc_info, psc);
+}
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
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 <[email protected]>
---
v6 changes:
- rename stuff to match changes in "clk: davinci: New driver for TI DA8XX USB
PHY clocks"
- take advantage of syscon lookup changes in "mfd: syscon: Add syscon_register()
function"
arch/arm/mach-davinci/usb-da8xx.c | 78 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 77 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index fb31f6e..b960609 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,70 @@ 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 *fck_clk, *clk;
+ struct clk_hw *parent;
+
+ cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
+ if (IS_ERR(cfgchip))
+ return PTR_ERR(cfgchip);
+
+ fck_clk = clk_get_sys("musb-da8xx", NULL);
+ if (IS_ERR(fck_clk))
+ return PTR_ERR(fck_clk);
+
+ clk = da8xx_cfgchip_register_usb0_clk48(cfgchip, fck_clk);
+ if (IS_ERR(clk)) {
+ clk_put(fck_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, "usb0_clk48", "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))
+ return PTR_ERR(cfgchip);
+
+ clk = da8xx_cfgchip_register_usb1_clk48(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, "usb1_clk48", "da8xx-usb-phy");
+}
+#endif
--
2.7.4
This adds the new board-specific 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 <[email protected]>
---
v6 changes:
- add blank lines between function calls
arch/arm/mach-davinci/dm365.c | 43 ++++++++++++++++++++++++++++++++-----------
1 file changed, 32 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 1e3df9d..ff79bb0 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,21 @@ 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
This adds platform-specific declarations for the PLL clocks on TI
DM355 based systems.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- Added dm355_pll{1,2}_info with controller-specific information
- Add empty lines between function calls
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/pll-dm355.c | 66 +++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 68 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..ac93c52
--- /dev/null
+++ b/drivers/clk/davinci/pll-dm355.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PLL clock descriptions for TI DM355
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/bitops.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pll.h"
+
+static const struct davinci_pll_clk_info dm355_pll1_info __initconst = {
+ .name = "pll1",
+ .pllm_mask = GENMASK(7, 0),
+ .pllm_min = 92,
+ .pllm_max = 184,
+ .flags = PLL_HAS_OSCIN | PLL_HAS_PREDIV | PLL_PREDIV_ALWAYS_ENABLED |
+ PLL_PREDIV_FIXED8 | PLL_HAS_POSTDIV |
+ PLL_POSTDIV_ALWAYS_ENABLED | PLL_POSTDIV_FIXED_DIV,
+};
+
+static const struct davinci_pll_sysclk_info dm355_pll1_sysclk_info[] __initconst = {
+ SYSCLK(1, pll1_sysclk1, pll1, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(2, pll1_sysclk2, pll1, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(3, pll1_sysclk3, pll1, 5, SYSCLK_ALWAYS_ENABLED),
+ SYSCLK(4, pll1_sysclk4, pll1, 5, SYSCLK_ALWAYS_ENABLED),
+ { }
+};
+
+static const struct davinci_pll_clk_info dm355_pll2_info __initconst = {
+ .name = "pll2",
+ .pllm_mask = GENMASK(7, 0),
+ .pllm_min = 92,
+ .pllm_max = 184,
+ .flags = PLL_HAS_PREDIV | PLL_PREDIV_ALWAYS_ENABLED | PLL_HAS_POSTDIV |
+ PLL_POSTDIV_ALWAYS_ENABLED | PLL_POSTDIV_FIXED_DIV,
+};
+
+static const struct davinci_pll_sysclk_info dm355_pll2_sysclk_info[] __initconst = {
+ SYSCLK(1, pll2_sysclk1, pll2, 5, SYSCLK_FIXED_DIV),
+ SYSCLK(2, pll2_sysclk2, pll2, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED),
+ { }
+};
+
+void __init dm355_pll_clk_init(void __iomem *pll1, void __iomem *pll2)
+{
+ const struct davinci_pll_sysclk_info *info;
+
+ davinci_pll_clk_register(&dm355_pll1_info, "ref_clk", pll1);
+
+ for (info = dm355_pll1_sysclk_info; info->name; info++)
+ davinci_pll_sysclk_register(info, pll1);
+
+ davinci_pll_auxclk_register("pll1_auxclk", pll1);
+
+ davinci_pll_sysclkbp_clk_register("pll1_sysclkbp", pll1);
+
+ davinci_pll_clk_register(&dm355_pll2_info, "oscin", pll2);
+
+ for (info = dm355_pll2_sysclk_info; info->name; info++)
+ davinci_pll_sysclk_register(info, pll2);
+
+ davinci_pll_sysclkbp_clk_register("pll2_sysclkbp", 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
This removes CONFIG_DAVINCI_RESET_CLOCKS. The option has been removed from
the kernel.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- none
arch/arm/configs/davinci_all_defconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 026154c..94d8946 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -31,7 +31,6 @@ CONFIG_MACH_MITYOMAPL138=y
CONFIG_MACH_OMAPL138_HAWKBOARD=y
CONFIG_DAVINCI_MUX_DEBUG=y
CONFIG_DAVINCI_MUX_WARNINGS=y
-CONFIG_DAVINCI_RESET_CLOCKS=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_CMA=y
--
2.7.4
This adds the new board-specific 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 <[email protected]>
---
v6 changes:
- add blank lines between function calls
arch/arm/mach-davinci/dm355.c | 49 +++++++++++++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index f294804..2c19739 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,27 @@ 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
This adds the new board-specific 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 <[email protected]>
---
v6 changes:
- add blank lines between function calls
arch/arm/mach-davinci/dm646x.c | 44 ++++++++++++++++++++++++++++++++++--------
1 file changed, 36 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 109ab1f..ee07e41 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,29 @@ 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
This adds the new board-specific 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 <[email protected]>
---
v6 changes:
- add blank lines between function calls
arch/arm/mach-davinci/dm644x.c | 38 ++++++++++++++++++++++++++++++--------
1 file changed, 30 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index b409801..5b5de85 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,21 @@ 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
This adds the new board-specific 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 <[email protected]>
---
v6 changes:
- add blank lines between function calls
- include da8xx_register_cfgchip()
arch/arm/mach-davinci/da830.c | 49 +++++++++++++++++++++++++++++++++++++------
1 file changed, 43 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 39de5a6..0b6d0f3 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,7 +1231,36 @@ 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);
+
+ da8xx_register_cfgchip();
+
+ 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
da8xx_register_cfgchip();
davinci_clk_init(da830_clks);
+#endif
davinci_timer_init();
}
--
2.7.4
This adds the new board-specific 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.
Also clean up the #includes since we are adding some here.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- add blank lines between function calls
- include da8xx_register_cfgchip()
- add async1 and async2 clock domains
arch/arm/mach-davinci/da850.c | 79 +++++++++++++++++++++++++++++++++++++------
1 file changed, 69 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 5c86d77..0fdf647 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -11,37 +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/platform_device.h>
-#include <linux/cpufreq.h>
#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_device.h>
#include <linux/regmap.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
+#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);
@@ -581,6 +588,7 @@ static struct clk_lookup da850_clks[] = {
CLK("ecap.2", "fck", &ecap2_clk),
CLK(NULL, NULL, NULL),
};
+#endif
/*
* Device specific mux setup
@@ -1168,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;
@@ -1230,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;
@@ -1250,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 */
@@ -1381,6 +1393,52 @@ void __init da850_init(void)
void __init da850_init_time(void)
{
+#ifdef CONFIG_COMMON_CLK
+ void __iomem *pll0, *pll1, *psc0, *psc1;
+ struct regmap *cfgchip;
+ 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);
+
+ cfgchip = da8xx_register_cfgchip();
+ if (WARN(IS_ERR(cfgchip), "failed to register CFGCHIP syscon"))
+ return;
+
+ clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA850_REF_FREQ);
+
+ da850_pll_clk_init(pll0, pll1);
+
+ da8xx_cfgchip_register_div4p5(cfgchip);
+
+ da8xx_cfgchip_register_async1(cfgchip);
+
+ clk = clk_register_fixed_factor(NULL, "async2", "pll0_auxclk", 0, 1, 1);
+ clk_register_clkdev(clk, NULL, "i2c_davinci.1");
+ clk_register_clkdev(clk, "timer0", NULL);
+ clk_register_clkdev(clk, NULL, "davinci-wdt");
+
+ clk = da8xx_cfgchip_register_async3(cfgchip);
+
+ /* 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, "rmii", "pll0_sysclk7", 0, 1, 1);
+ clk_register_clkdev(clk, "rmii", NULL);
+
+ clk = da8xx_cfgchip_register_tbclk(cfgchip);
+ clk_register_clkdev(clk, "tbclk", "ehrpwm.0");
+ clk_register_clkdev(clk, "tbclk", "ehrpwm.1");
+#else
struct regmap *cfgchip;
cfgchip = da8xx_register_cfgchip();
@@ -1392,5 +1450,6 @@ void __init da850_init_time(void)
regmap_write_bits(cfgchip, CFGCHIP(3), CFGCHIP3_PLL1_MASTER_LOCK, 0);
davinci_clk_init(da850_clks);
+#endif
davinci_timer_init();
}
--
2.7.4
This adds platform-specific declarations for the PSC clocks on TI
DM644x based systems.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm644x.c | 68 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 70 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..c3a84e7
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm644x.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM644x
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV1(vpss_master_clkdev, "master", "vpss");
+LPSC_CLKDEV1(vpss_slave_clkdev, "slave", "vpss");
+LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
+ "fck", "davinci_mdio.0");
+LPSC_CLKDEV1(usb_clkdev, "usb", NULL);
+LPSC_CLKDEV1(ide_clkdev, NULL, "palm_bk3710");
+LPSC_CLKDEV1(aemif_clkdev, "aemif", NULL);
+LPSC_CLKDEV1(mmcsd_clkdev, NULL, "dm6441-mmc.0");
+LPSC_CLKDEV1(asp0_clkdev, NULL, "davinci-mcbsp");
+LPSC_CLKDEV1(i2c_clkdev, NULL, "i2c_davinci.1");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(uart2_clkdev, NULL, "serial8250.2");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV1(timer0_clkdev, "timer0", NULL);
+LPSC_CLKDEV1(timer2_clkdev, NULL, "davinci-wdt");
+
+static const struct davinci_psc_clk_info dm644x_psc_info[] __initconst = {
+ LPSC(0, 0, vpss_master, pll1_sysclk3, vpss_master_clkdev, 0),
+ LPSC(1, 0, vpss_slave, pll1_sysclk3, vpss_slave_clkdev, 0),
+ LPSC(6, 0, emac, pll1_sysclk5, emac_clkdev, 0),
+ LPSC(9, 0, usb, pll1_sysclk5, usb_clkdev, 0),
+ LPSC(10, 0, ide, pll1_sysclk5, ide_clkdev, 0),
+ LPSC(11, 0, vlynq, pll1_sysclk5, NULL, 0),
+ LPSC(14, 0, aemif, pll1_sysclk5, aemif_clkdev, 0),
+ LPSC(15, 0, mmcsd, pll1_sysclk5, mmcsd_clkdev, 0),
+ LPSC(17, 0, asp0, pll1_sysclk5, asp0_clkdev, 0),
+ LPSC(18, 0, i2c, pll1_auxclk, i2c_clkdev, 0),
+ LPSC(19, 0, uart0, pll1_auxclk, uart0_clkdev, 0),
+ LPSC(20, 0, uart1, pll1_auxclk, uart1_clkdev, 0),
+ LPSC(21, 0, uart2, pll1_auxclk, uart2_clkdev, 0),
+ LPSC(22, 0, spi, pll1_sysclk5, NULL, 0),
+ LPSC(23, 0, pwm0, pll1_auxclk, NULL, 0),
+ LPSC(24, 0, pwm1, pll1_auxclk, NULL, 0),
+ LPSC(25, 0, pwm2, pll1_auxclk, NULL, 0),
+ LPSC(26, 0, gpio, pll1_sysclk5, gpio_clkdev, 0),
+ LPSC(27, 0, timer0, pll1_auxclk, timer0_clkdev, 0),
+ LPSC(28, 0, timer1, pll1_auxclk, NULL, 0),
+ /* REVISIT: why can't this be disabled? */
+ LPSC(29, 0, timer2, pll1_auxclk, timer2_clkdev,
+ LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, arm, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ /* REVISIT how to disable? */
+ LPSC(39, 1, dsp, pll1_sysclk1, NULL, LPSC_ALWAYS_ENABLED),
+ /* REVISIT how to disable? */
+ LPSC(40, 1, vicp, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ { }
+};
+
+void __init dm644x_psc_clk_init(void __iomem *psc)
+{
+ davinci_psc_register_clocks(dm644x_psc_info, psc);
+}
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
This adds a new binding for the clocks present in the CFGCHIP syscon
registers in TI DA8XX SoCs.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- combine "dt-bindings: clock: Add bindings for DA8XX CFGCHIP gate clocks",
"dt-bindings: clock: Add binding for TI DA8XX CFGCHIP mux clocks" and
"dt-bindings: clock: Add bindings for TI DA8XX USB PHY clocks" into a single
file containing all CFGCHIP clocks bindings
- added compatible = "ti,da830-div4p5ena"
- added compatible = "ti,da850-async1-clksrc"
- renamed other compatible strings
- changed and added some clk-names strings
- USB PHY clocks are combined into a single node with #clock-cells = <1>
.../bindings/clock/ti/davinci/da8xx-cfgchip.txt | 93 ++++++++++++++++++++++
1 file changed, 93 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt
diff --git a/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt b/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt
new file mode 100644
index 0000000..1e03dce
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt
@@ -0,0 +1,93 @@
+Binding for TI DA8XX/OMAP-L13X/AM17XX/AM18XX CFGCHIP 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.
+
+All of the clock nodes described below must be child nodes of a CFGCHIP node
+(compatible = "ti,da830-cfgchip").
+
+USB PHY clocks
+--------------
+Required properties:
+- compatible: shall be "ti,da830-usb-phy-clocks".
+- #clock-cells: from common clock binding; shall be set to 1.
+- clocks: phandles to the parent clocks corresponding to clock-names
+- clock-names: shall be "fck", "usb_refclkin", "auxclk"
+
+This node provides two clocks. The clock at index 0 is the USB 2.0 PHY 48MHz
+clock and the clock at index 1 is the USB 1.1 PHY 48MHz clock.
+
+eHRPWM Time Base Clock (TBCLK)
+------------------------------
+Required properties:
+- compatible: shall be "ti,da830-tbclksync".
+- #clock-cells: from common clock binding; shall be set to 0.
+- clocks: phandle to the parent clock
+- clock-names: shall be "fck"
+
+PLL DIV4.5 divider
+------------------
+Required properties:
+- compatible: shall be "ti,da830-div4p5ena".
+- #clock-cells: from common clock binding; shall be set to 0.
+- clocks: phandle to the parent clock
+- clock-names: shall be "pll0_pllout"
+
+EMIFA clock source (ASYNC1)
+---------------------------
+Required properties:
+- compatible: shall be "ti,da850-async1-clksrc".
+- #clock-cells: from common clock binding; shall be set to 0.
+- clocks: phandles to the parent clocks corresponding to clock-names
+- clock-names: shall be "pll0_sysclk3", "div4.5"
+
+ASYNC3 clock source
+-------------------
+Required properties:
+- compatible: shall be "ti,da850-async3-clksrc".
+- #clock-cells: from common clock binding; shall be set to 0.
+- clocks: phandles to the parent clocks corresponding to clock-names
+- clock-names: shall be "pll0_sysclk2", "pll1_sysclk2"
+
+Examples:
+
+ cfgchip: syscon@1417c {
+ compatible = "ti,da830-cfgchip", "syscon", "simple-mfd";
+ reg = <0x1417c 0x14>;
+
+ usb_phy_clk: usb-phy-clocks {
+ compatible = "ti,da830-usb-phy-clocks";
+ #clock-cells = <1>;
+ clocks = <&psc1 1>, <&usb_refclkin>, <&pll0_auxclk>;
+ clock-names = "fck", "usb_refclkin", "auxclk";
+ };
+ ehrpwm_tbclk: ehrpwm_tbclk {
+ compatible = "ti,da830-tbclksync";
+ #clock-cells = <0>;
+ clocks = <&psc1 17>;
+ clock-names = "fck";
+ };
+ div4p5_clk: div4.5 {
+ compatible = "ti,da830-div4p5ena";
+ #clock-cells = <0>;
+ clocks = <&pll0_pllout>;
+ clock-names = "pll0_pllout";
+ };
+ async1_clk: async1 {
+ compatible = "ti,da850-async1-clksrc";
+ #clock-cells = <0>;
+ clocks = <&pll0_sysclk 3>, <&div4p5_clk>;
+ clock-names = "pll0_sysclk3", "div4.5";
+ };
+ async3_clk: async3 {
+ compatible = "ti,da850-async3-clksrc";
+ #clock-cells = <0>;
+ clocks = <&pll0_sysclk 2>, <&pll1_sysclk 2>;
+ clock-names = "pll0_sysclk2", "pll1_sysclk2";
+ };
+ };
+
+Also see:
+- Documentation/devicetree/bindings/clock/clock-bindings.txt
+
--
2.7.4
This adds platform-specific declarations for the PSC clocks on TI
DM646x based systems.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm646x.c | 62 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 64 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..bdb9db7
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm646x.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM646x
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV1(ide_clkdev, NULL, "palm_bk3710");
+LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
+ "fck", "davinci_mdio.0");
+LPSC_CLKDEV1(aemif_clkdev, "aemif", NULL);
+LPSC_CLKDEV1(mcasp0_clkdev, NULL, "davinci-mcasp.0");
+LPSC_CLKDEV1(mcasp1_clkdev, NULL, "davinci-mcasp.1");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(uart2_clkdev, NULL, "serial8250.2");
+LPSC_CLKDEV1(i2c_clkdev, NULL, "i2c_davinci.1");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV1(timer0_clkdev, "timer0", NULL);
+
+static const struct davinci_psc_clk_info dm646x_psc_info[] __initconst = {
+ LPSC(0, 0, arm, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ /* REVISIT how to disable? */
+ LPSC(1, 0, dsp, pll1_sysclk1, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(4, 0, edma_cc, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(5, 0, edma_tc0, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(6, 0, edma_tc1, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(7, 0, edma_tc2, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(8, 0, edma_tc3, pll1_sysclk2, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(10, 0, ide, pll1_sysclk4, ide_clkdev, 0),
+ LPSC(14, 0, emac, pll1_sysclk3, emac_clkdev, 0),
+ LPSC(16, 0, vpif0, ref_clk, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(17, 0, vpif1, ref_clk, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(21, 0, aemif, pll1_sysclk3, aemif_clkdev, LPSC_ALWAYS_ENABLED),
+ LPSC(22, 0, mcasp0, pll1_sysclk3, mcasp0_clkdev, 0),
+ LPSC(23, 0, mcasp1, pll1_sysclk3, mcasp1_clkdev, 0),
+ LPSC(26, 0, uart0, aux_clkin, uart0_clkdev, 0),
+ LPSC(27, 0, uart1, aux_clkin, uart1_clkdev, 0),
+ LPSC(28, 0, uart2, aux_clkin, uart2_clkdev, 0),
+ /* REVIST: disabling hangs system */
+ LPSC(29, 0, pwm0, pll1_sysclk3, NULL, LPSC_ALWAYS_ENABLED),
+ /* REVIST: disabling hangs system */
+ LPSC(30, 0, pwm1, pll1_sysclk3, NULL, LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, i2c, pll1_sysclk3, i2c_clkdev, 0),
+ LPSC(33, 0, gpio, pll1_sysclk3, gpio_clkdev, 0),
+ LPSC(34, 0, timer0, pll1_sysclk3, timer0_clkdev, 0),
+ LPSC(35, 0, timer1, pll1_sysclk3, NULL, 0),
+ { }
+};
+
+void __init dm646x_psc_clk_init(void __iomem *psc)
+{
+ davinci_psc_register_clocks(dm646x_psc_info, psc);
+}
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
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 <[email protected]>
---
v6 changes:
- rename clocks to usb{0,1}_clk48
- rename USB 2.0 PSC clock to "fck"
- simplify {s,g}et_parent implementations
- use pr_fmt macro
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/da8xx-usb-phy-clk.c | 312 ++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 6 +
3 files changed, 319 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..8dba40c
--- /dev/null
+++ b/drivers/clk/davinci/da8xx-usb-phy-clk.c
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * da8xx-usb-phy-clk - TI DaVinci DA8xx USB PHY clocks driver
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt "\n", __func__
+
+#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_clk48 {
+ struct clk_hw hw;
+ struct clk *fck;
+ struct regmap *regmap;
+};
+
+#define to_da8xx_usb0_clk48(_hw) \
+ container_of((_hw), struct da8xx_usb0_clk48, hw)
+
+static int da8xx_usb0_clk48_prepare(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *clk = to_da8xx_usb0_clk48(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->fck);
+}
+
+static void da8xx_usb0_clk48_unprepare(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *clk = to_da8xx_usb0_clk48(hw);
+
+ clk_unprepare(clk->fck);
+}
+
+static int da8xx_usb0_clk48_enable(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *clk = to_da8xx_usb0_clk48(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->fck);
+
+ /* 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->fck);
+
+ return ret;
+}
+
+static void da8xx_usb0_clk48_disable(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *clk = to_da8xx_usb0_clk48(hw);
+ unsigned int val;
+
+ val = CFGCHIP2_PHYPWRDN;
+ regmap_write_bits(clk->regmap, CFGCHIP(2), val, val);
+}
+
+static int da8xx_usb0_clk48_is_enabled(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *clk = to_da8xx_usb0_clk48(hw);
+ unsigned int val;
+
+ regmap_read(clk->regmap, CFGCHIP(2), &val);
+
+ return !!(val & CFGCHIP2_PHYCLKGD);
+}
+
+static unsigned long da8xx_usb0_clk48_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct da8xx_usb0_clk48 *clk = to_da8xx_usb0_clk48(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_clk48_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ return 48000000;
+}
+
+static int da8xx_usb0_clk48_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct da8xx_usb0_clk48 *clk = to_da8xx_usb0_clk48(hw);
+
+ return regmap_write_bits(clk->regmap, CFGCHIP(2),
+ CFGCHIP2_USB2PHYCLKMUX,
+ index ? CFGCHIP2_USB2PHYCLKMUX : 0);
+}
+
+static u8 da8xx_usb0_clk48_get_parent(struct clk_hw *hw)
+{
+ struct da8xx_usb0_clk48 *clk = to_da8xx_usb0_clk48(hw);
+ unsigned int val;
+
+ regmap_read(clk->regmap, CFGCHIP(2), &val);
+
+ return (val & CFGCHIP2_USB2PHYCLKMUX) ? 1 : 0;
+}
+
+static const struct clk_ops da8xx_usb0_clk48_ops = {
+ .prepare = da8xx_usb0_clk48_prepare,
+ .unprepare = da8xx_usb0_clk48_unprepare,
+ .enable = da8xx_usb0_clk48_enable,
+ .disable = da8xx_usb0_clk48_disable,
+ .is_enabled = da8xx_usb0_clk48_is_enabled,
+ .recalc_rate = da8xx_usb0_clk48_recalc_rate,
+ .round_rate = da8xx_usb0_clk48_round_rate,
+ .set_parent = da8xx_usb0_clk48_set_parent,
+ .get_parent = da8xx_usb0_clk48_get_parent,
+};
+
+/**
+ * da8xx_cfgchip_register_usb0_clk48 - Register a new USB 2.0 PHY clock
+ * @regmap: The CFGCHIP regmap
+ * @fck_clk: The USB 2.0 PSC clock
+ */
+struct clk *da8xx_cfgchip_register_usb0_clk48(struct regmap *regmap,
+ struct clk *fck_clk)
+{
+ const char * const parent_names[] = { "usb_refclkin", "pll0_auxclk" };
+ struct da8xx_usb0_clk48 *clk;
+ struct clk_init_data init;
+
+ clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+ if (!clk)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = "usb0_clk48";
+ init.ops = &da8xx_usb0_clk48_ops;
+ init.parent_names = parent_names;
+ init.num_parents = 2;
+
+ clk->hw.init = &init;
+ clk->fck = fck_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;
+};
+
+#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);
+
+ return regmap_write_bits(clk->regmap, CFGCHIP(2),
+ CFGCHIP2_USB1PHYCLKMUX,
+ index ? CFGCHIP2_USB1PHYCLKMUX : 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);
+
+ return (val & CFGCHIP2_USB1PHYCLKMUX) ? 1 : 0;
+}
+
+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_cfgchip_register_usb1_clk48 - Register a new USB 1.1 PHY clock
+ * @regmap: The CFGCHIP regmap
+ */
+struct clk *da8xx_cfgchip_register_usb1_clk48(struct regmap *regmap)
+{
+ const char * const parent_names[] = { "usb0_clk48", "usb_refclkin" };
+ 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 = "usb1_clk48";
+ 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 of_da8xx_usb_phy_clk_init(struct device_node *np)
+{
+ struct clk_onecell_data *clk_data;
+ struct regmap *regmap;
+ struct clk *fck_clk, *clk;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap)) {
+ pr_err("No regmap for syscon parent (%ld)", PTR_ERR(regmap));
+ return;
+ }
+
+ fck_clk = of_clk_get_by_name(np, "fck");
+ if (IS_ERR(fck_clk)) {
+ pr_err("Missing fck clock (%ld)", PTR_ERR(fck_clk));
+ return;
+ }
+
+ clk_data = clk_alloc_onecell_data(2);
+ if (!clk_data) {
+ clk_put(fck_clk);
+ return;
+ }
+
+ clk = da8xx_cfgchip_register_usb0_clk48(regmap, fck_clk);
+ if (IS_ERR(clk)) {
+ pr_warn("Failed to register usb0_clk48 (%ld)", PTR_ERR(clk));
+ clk_put(fck_clk);
+ } else {
+ clk_data->clks[0] = clk;
+ }
+
+ clk = da8xx_cfgchip_register_usb1_clk48(regmap);
+ if (IS_ERR(clk))
+ pr_warn("Failed to register usb1_clk48 (%ld)", PTR_ERR(clk));
+ else
+ clk_data->clks[1] = clk;
+
+ of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+}
+
+CLK_OF_DECLARE(da8xx_usb_phy_clk, "ti,da830-usb-phy-clocks",
+ of_da8xx_usb_phy_clk_init);
+#endif
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index 54ea3ff..04b48b3 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);
@@ -27,5 +30,8 @@ struct clk *da8xx_cfgchip_register_tbclk(struct regmap *regmap);
struct clk *da8xx_cfgchip_register_div4p5(struct regmap *regmap);
struct clk *da8xx_cfgchip_register_async1(struct regmap *regmap);
struct clk *da8xx_cfgchip_register_async3(struct regmap *regmap);
+struct clk *da8xx_cfgchip_register_usb0_clk48(struct regmap *regmap,
+ struct clk *usb0_psc_clk);
+struct clk *da8xx_cfgchip_register_usb1_clk48(struct regmap *regmap);
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
This adds platform-specific declarations for the PSC clocks on TI
DM365 based systems.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- change how clkdev lookups are declared
drivers/clk/davinci/Makefile | 1 +
drivers/clk/davinci/psc-dm365.c | 79 +++++++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 1 +
3 files changed, 81 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..dd6eb1d
--- /dev/null
+++ b/drivers/clk/davinci/psc-dm365.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PSC clock descriptions for TI DaVinci DM365
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "psc.h"
+
+LPSC_CLKDEV1(vpss_slave_clkdev, "slave", "vpss");
+LPSC_CLKDEV1(spi1_clkdev, NULL, "spi_davinci.1");
+LPSC_CLKDEV1(mmcsd1_clkdev, NULL, "da830-mmc.1");
+LPSC_CLKDEV1(asp0_clkdev, NULL, "davinci-mcbsp");
+LPSC_CLKDEV1(usb_clkdev, "usb", NULL);
+LPSC_CLKDEV1(spi2_clkdev, NULL, "spi_davinci.2");
+LPSC_CLKDEV1(aemif_clkdev, "aemif", NULL);
+LPSC_CLKDEV1(mmcsd0_clkdev, NULL, "da830-mmc.0");
+LPSC_CLKDEV1(i2c_clkdev, NULL, "i2c_davinci.1");
+LPSC_CLKDEV1(uart0_clkdev, NULL, "serial8250.0");
+LPSC_CLKDEV1(uart1_clkdev, NULL, "serial8250.1");
+LPSC_CLKDEV1(spi0_clkdev, NULL, "spi_davinci.0");
+/* REVISIT: gpio-davinci.c should be modified to drop con_id */
+LPSC_CLKDEV1(gpio_clkdev, "gpio", NULL);
+LPSC_CLKDEV1(timer0_clkdev, "timer0", NULL);
+LPSC_CLKDEV1(timer2_clkdev, NULL, "davinci-wdt");
+LPSC_CLKDEV1(spi3_clkdev, NULL, "spi_davinci.3");
+LPSC_CLKDEV1(spi4_clkdev, NULL, "spi_davinci.4");
+LPSC_CLKDEV2(emac_clkdev, NULL, "davinci_emac.1",
+ "fck", "davinci_mdio.0");
+LPSC_CLKDEV1(voice_codec_clkdev, NULL, "davinci_voicecodec");
+LPSC_CLKDEV1(vpss_dac_clkdev, "vpss_dac", NULL);
+LPSC_CLKDEV1(vpss_master_clkdev, "master", "vpss");
+
+static const struct davinci_psc_clk_info dm365_psc_info[] __initconst = {
+ LPSC(1, 0, vpss_slave, pll1_sysclk5, vpss_slave_clkdev, 0),
+ LPSC(5, 0, timer3, pll1_auxclk, NULL, 0),
+ LPSC(6, 0, spi1, pll1_sysclk4, spi1_clkdev, 0),
+ LPSC(7, 0, mmcsd1, pll1_sysclk4, mmcsd1_clkdev, 0),
+ LPSC(8, 0, asp0, pll1_sysclk4, asp0_clkdev, 0),
+ LPSC(9, 0, usb, pll1_auxclk, usb_clkdev, 0),
+ LPSC(10, 0, pwm3, pll1_auxclk, NULL, 0),
+ LPSC(11, 0, spi2, pll1_sysclk4, spi2_clkdev, 0),
+ LPSC(12, 0, rto, pll1_sysclk4, NULL, 0),
+ LPSC(14, 0, aemif, pll1_sysclk4, aemif_clkdev, 0),
+ LPSC(15, 0, mmcsd0, pll1_sysclk8, mmcsd0_clkdev, 0),
+ LPSC(18, 0, i2c, pll1_auxclk, i2c_clkdev, 0),
+ LPSC(19, 0, uart0, pll1_auxclk, uart0_clkdev, 0),
+ LPSC(20, 0, uart1, pll1_sysclk4, uart1_clkdev, 0),
+ LPSC(22, 0, spi0, pll1_sysclk4, spi0_clkdev, 0),
+ LPSC(23, 0, pwm0, pll1_auxclk, NULL, 0),
+ LPSC(24, 0, pwm1, pll1_auxclk, NULL, 0),
+ LPSC(25, 0, pwm2, pll1_auxclk, NULL, 0),
+ LPSC(26, 0, gpio, pll1_sysclk4, gpio_clkdev, 0),
+ LPSC(27, 0, timer0, pll1_auxclk, timer0_clkdev, 0),
+ LPSC(28, 0, timer1, pll1_auxclk, NULL, 0),
+ /* REVISIT: why can't this be disabled? */
+ LPSC(29, 0, timer2, pll1_auxclk, timer2_clkdev,
+ LPSC_ALWAYS_ENABLED),
+ LPSC(31, 0, arm, pll2_sysclk2, NULL,
+ LPSC_ALWAYS_ENABLED),
+ LPSC(38, 0, spi3, pll1_sysclk4, spi3_clkdev, 0),
+ LPSC(39, 0, spi4, pll1_auxclk, spi4_clkdev, 0),
+ LPSC(40, 0, emac, pll2_sysclk4, emac_clkdev, 0),
+ LPSC(44, 1, voice_codec, pll1_sysclk3, voice_codec_clkdev, 0),
+ LPSC(46, 1, vpss_dac, pll1_sysclk3, vpss_dac_clkdev, 0),
+ LPSC(47, 0, vpss_master, pll1_sysclk5, vpss_master_clkdev, 0),
+ LPSC(50, 0, mjcp, pll1_sysclk3, NULL, 0),
+ { }
+};
+
+void __init dm365_psc_clk_init(void __iomem *psc)
+{
+ davinci_psc_register_clocks(dm365_psc_info, psc);
+}
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
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 <[email protected]>
---
v6 changes:
- added DIV4.5 and ASYNC1 clocks
- refactored code to be more generic
- added functions for registering clocks from board files (no longer device
tree only)
- use pr_fmt macro
drivers/clk/davinci/Makefile | 2 +
drivers/clk/davinci/da8xx-cfgchip.c | 305 ++++++++++++++++++++++++++++++++++++
include/linux/clk/davinci.h | 5 +
3 files changed, 312 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..21dedb4
--- /dev/null
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for DA8xx/AM17xx/AM18xx/OMAP-L13x CFGCHIP
+ *
+ * Copyright (C) 2018 David Lechner <[email protected]>
+ */
+
+#define pr_fmt(fmt) "%s: " fmt "\n", __func__
+
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define DA8XX_GATE_CLOCK_IS_DIV4P5 BIT(1)
+
+struct da8xx_cfgchip_gate_clk_info {
+ const char *name;
+ u32 cfgchip;
+ u32 bit;
+ u32 flags;
+};
+
+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 unsigned long da8xx_cfgchip_div4p5_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ /* this clock divides by 4.5 */
+ return parent_rate * 2 / 9;
+}
+
+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 const struct clk_ops da8xx_cfgchip_div4p5_clk_ops = {
+ .enable = da8xx_cfgchip_gate_clk_enable,
+ .disable = da8xx_cfgchip_gate_clk_disable,
+ .is_enabled = da8xx_cfgchip_gate_clk_is_enabled,
+ .recalc_rate = da8xx_cfgchip_div4p5_recalc_rate,
+};
+
+static struct clk * __init
+da8xx_cfgchip_gate_clk_register(const struct da8xx_cfgchip_gate_clk_info *info,
+ const char *parent_name,
+ struct regmap *regmap)
+{
+ struct da8xx_cfgchip_gate_clk *gate;
+ struct clk_init_data init;
+
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = info->name;
+ if (info->flags & DA8XX_GATE_CLOCK_IS_DIV4P5)
+ init.ops = &da8xx_cfgchip_div4p5_clk_ops;
+ else
+ 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;
+
+ gate->hw.init = &init;
+ gate->regmap = regmap;
+ gate->reg = info->cfgchip;
+ gate->mask = info->bit;
+
+ return clk_register(NULL, &gate->hw);
+}
+
+static const struct da8xx_cfgchip_gate_clk_info da8xx_tbclksync_info __initconst = {
+ .name = "ehrpwm_tbclk",
+ .cfgchip = CFGCHIP(1),
+ .bit = CFGCHIP1_TBCLKSYNC,
+};
+
+struct clk * __init da8xx_cfgchip_register_tbclk(struct regmap *regmap)
+{
+ return da8xx_cfgchip_gate_clk_register(&da8xx_tbclksync_info, "ehrpwm",
+ regmap);
+}
+
+static const struct da8xx_cfgchip_gate_clk_info da8xx_div4p5ena_info __initconst = {
+ .name = "div4.5",
+ .cfgchip = CFGCHIP(3),
+ .bit = CFGCHIP3_DIV45PENA,
+ .flags = DA8XX_GATE_CLOCK_IS_DIV4P5,
+};
+
+struct clk * __init da8xx_cfgchip_register_div4p5(struct regmap *regmap)
+{
+ return da8xx_cfgchip_gate_clk_register(&da8xx_div4p5ena_info,
+ "pll0_pllout", regmap);
+}
+
+#ifdef CONFIG_OF
+static void __init
+of_da8xx_cfgchip_gate_clk_init(struct device_node *np,
+ const struct da8xx_cfgchip_gate_clk_info *info)
+{
+ const char *parent_name;
+ struct regmap *regmap;
+ struct clk *clk;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap)) {
+ pr_err("no regmap for syscon parent of %s (%lu)", np->full_name,
+ PTR_ERR(regmap));
+ return;
+ }
+
+ clk = da8xx_cfgchip_gate_clk_register(info, parent_name, regmap);
+ if (IS_ERR(clk)) {
+ pr_err("failed to register %s (%lu)", np->full_name,
+ PTR_ERR(clk));
+ return;
+ }
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static void __init da8xx_tbclksync_init(struct device_node *np)
+{
+ of_da8xx_cfgchip_gate_clk_init(np, &da8xx_tbclksync_info);
+}
+CLK_OF_DECLARE(da8xx_tbclksync, "ti,da830-tbclksync", da8xx_tbclksync_init);
+
+static void __init da8xx_div4p5ena_init(struct device_node *np)
+{
+ of_da8xx_cfgchip_gate_clk_init(np, &da8xx_div4p5ena_info);
+}
+CLK_OF_DECLARE(da8xx_div4p5ena, "ti,da830-div4p5ena", da8xx_div4p5ena_init);
+#endif
+
+struct da8xx_cfgchip_mux_clk_info {
+ const char *name;
+ const char *parent0;
+ const char *parent1;
+ u32 cfgchip;
+ u32 bit;
+};
+
+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 struct clk * __init
+da8xx_cfgchip_mux_clk_register(const struct da8xx_cfgchip_mux_clk_info *info,
+ struct regmap *regmap)
+{
+ const char * const parent_names[] = { info->parent0, info->parent1 };
+ struct da8xx_cfgchip_mux_clk *mux;
+ struct clk_init_data init;
+
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = info->name;
+ init.ops = &da8xx_cfgchip_mux_clk_ops;
+ init.parent_names = parent_names;
+ init.num_parents = 2;
+ init.flags = 0;
+
+ mux->hw.init = &init;
+ mux->regmap = regmap;
+ mux->reg = info->cfgchip;
+ mux->mask = info->bit;
+
+ return clk_register(NULL, &mux->hw);
+}
+
+static const struct da8xx_cfgchip_mux_clk_info da850_async1_info __initconst = {
+ .name = "async1",
+ .parent0 = "pll0_sysclk3",
+ .parent1 = "div4.5",
+ .cfgchip = CFGCHIP(3),
+ .bit = CFGCHIP3_EMA_CLKSRC,
+};
+
+struct clk * __init da8xx_cfgchip_register_async1(struct regmap *cfgchip)
+{
+ return da8xx_cfgchip_mux_clk_register(&da850_async1_info, cfgchip);
+}
+
+static const struct da8xx_cfgchip_mux_clk_info da850_async3_info __initconst = {
+ .name = "async3",
+ .parent0 = "pll0_sysclk2",
+ .parent1 = "pll1_sysclk2",
+ .cfgchip = CFGCHIP(3),
+ .bit = CFGCHIP3_ASYNC3_CLKSRC,
+};
+
+struct clk * __init da8xx_cfgchip_register_async3(struct regmap *cfgchip)
+{
+ return da8xx_cfgchip_mux_clk_register(&da850_async3_info, cfgchip);
+}
+
+#ifdef CONFIG_OF
+static void __init
+of_da8xx_cfgchip_init_mux_clock(struct device_node *np,
+ const struct da8xx_cfgchip_mux_clk_info *info)
+{
+ struct regmap *regmap;
+ struct clk *clk;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap)) {
+ pr_err("no regmap for syscon parent of %s (%ld)", np->full_name,
+ PTR_ERR(regmap));
+ return;
+ }
+
+ clk = da8xx_cfgchip_mux_clk_register(info, regmap);
+ if (IS_ERR(clk)) {
+ pr_err("Failed to register %s (%ld)", np->full_name,
+ PTR_ERR(clk));
+ return;
+ }
+
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static void __init da850_async1_init(struct device_node *np)
+{
+ of_da8xx_cfgchip_init_mux_clock(np, &da850_async1_info);
+}
+CLK_OF_DECLARE(da850_async1, "ti,da850-async1-clksrc", da850_async1_init);
+
+static void __init da850_async3_init(struct device_node *np)
+{
+ of_da8xx_cfgchip_init_mux_clock(np, &da850_async3_info);
+}
+CLK_OF_DECLARE(da850_async3, "ti,da850-async3-clksrc", da850_async3_init);
+#endif
diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
index 3810ea3..54ea3ff 100644
--- a/include/linux/clk/davinci.h
+++ b/include/linux/clk/davinci.h
@@ -23,4 +23,9 @@ 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_cfgchip_register_tbclk(struct regmap *regmap);
+struct clk *da8xx_cfgchip_register_div4p5(struct regmap *regmap);
+struct clk *da8xx_cfgchip_register_async1(struct regmap *regmap);
+struct clk *da8xx_cfgchip_register_async3(struct regmap *regmap);
+
#endif /* __LINUX_CLK_DAVINCI_H__ */
--
2.7.4
This switches ARCH_DAVINCI to use the common clock framework. The legacy
clock code in arch/arm/mach-davinci/ is no longer used. New drivers in
drivers/clk/davinci/ are used instead.
A few macros had to be moved to prevent compile errors.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- clean up indent on Common objects section
arch/arm/Kconfig | 2 +-
arch/arm/mach-davinci/Makefile | 4 ++--
arch/arm/mach-davinci/clock.h | 4 ----
arch/arm/mach-davinci/davinci.h | 4 ++++
arch/arm/mach-davinci/psc.h | 2 --
5 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 51c8df5..3a12f9e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -604,7 +604,7 @@ config ARCH_S3C24XX
config ARCH_DAVINCI
bool "TI DaVinci"
select ARCH_HAS_HOLES_MEMORYMODEL
- select CLKDEV_LOOKUP
+ select COMMON_CLK
select CPU_ARM926T
select GENERIC_ALLOCATOR
select GENERIC_CLOCKEVENTS
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 4e81780..8725d8b 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -5,8 +5,8 @@
#
# Common objects
-obj-y := time.o clock.o serial.o psc.o \
- usb.o common.o sram.o aemif.o
+obj-y := time.o serial.o usb.o \
+ common.o sram.o aemif.o
obj-$(CONFIG_DAVINCI_MUX) += mux.o
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index d7894d5..2d05856 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -12,10 +12,6 @@
#ifndef __ARCH_ARM_DAVINCI_CLOCK_H
#define __ARCH_ARM_DAVINCI_CLOCK_H
-#define DAVINCI_PLL1_BASE 0x01c40800
-#define DAVINCI_PLL2_BASE 0x01c40c00
-#define MAX_PLL 2
-
/* PLL/Reset register offsets */
#define PLLCTL 0x100
#define PLLCTL_PLLEN BIT(0)
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index 270cef8..f5206a6 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -35,6 +35,10 @@
#include <media/davinci/vpbe.h>
#include <media/davinci/vpbe_osd.h>
+#define DAVINCI_PLL1_BASE 0x01c40800
+#define DAVINCI_PLL2_BASE 0x01c40c00
+#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01c41000
+
#define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000
#define SYSMOD_VDAC_CONFIG 0x2c
#define SYSMOD_VIDCLKCTL 0x38
diff --git a/arch/arm/mach-davinci/psc.h b/arch/arm/mach-davinci/psc.h
index 8af9f09..b58707c 100644
--- a/arch/arm/mach-davinci/psc.h
+++ b/arch/arm/mach-davinci/psc.h
@@ -27,8 +27,6 @@
#ifndef __ASM_ARCH_PSC_H
#define __ASM_ARCH_PSC_H
-#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
-
/* Power and Sleep Controller (PSC) Domains */
#define DAVINCI_GPSC_ARMDOMAIN 0
#define DAVINCI_GPSC_DSPDOMAIN 1
--
2.7.4
This removes the unused legacy clock init code from
arch/arm/mach-davinci/dm646x.c.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- none
arch/arm/mach-davinci/dm646x.c | 329 +----------------------------------------
1 file changed, 1 insertion(+), 328 deletions(-)
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index ee07e41..98b076f 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -33,11 +33,6 @@
#include "davinci.h"
#include "mux.h"
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#include "psc.h"
-#endif
-
#define DAVINCI_VPIF_BASE (0x01C12000)
#define VDD3P3V_VID_MASK (BIT_MASK(3) | BIT_MASK(2) | BIT_MASK(1) |\
@@ -52,319 +47,6 @@
#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,
-};
-
-static struct pll_data pll2_data = {
- .num = 2,
- .phys_base = DAVINCI_PLL2_BASE,
-};
-
-static struct clk ref_clk = {
- .name = "ref_clk",
- /* rate is initialized in dm646x_init_time() */
-};
-
-static struct clk aux_clkin = {
- .name = "aux_clkin",
- /* rate is initialized in dm646x_init_time() */
-};
-
-static struct clk pll1_clk = {
- .name = "pll1",
- .parent = &ref_clk,
- .pll_data = &pll1_data,
- .flags = CLK_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
- .name = "pll1_sysclk1",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-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 struct clk pll1_sysclk4 = {
- .name = "pll1_sysclk4",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclk5 = {
- .name = "pll1_sysclk5",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_sysclk6 = {
- .name = "pll1_sysclk6",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV6,
-};
-
-static struct clk pll1_sysclk8 = {
- .name = "pll1_sysclk8",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV8,
-};
-
-static struct clk pll1_sysclk9 = {
- .name = "pll1_sysclk9",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV9,
-};
-
-static struct clk pll1_sysclkbp = {
- .name = "pll1_sysclkbp",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
- .div_reg = BPDIV,
-};
-
-static struct clk pll1_aux_clk = {
- .name = "pll1_aux_clk",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll2_clk = {
- .name = "pll2_clk",
- .parent = &ref_clk,
- .pll_data = &pll2_data,
- .flags = CLK_PLL,
-};
-
-static struct clk pll2_sysclk1 = {
- .name = "pll2_sysclk1",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-static struct clk dsp_clk = {
- .name = "dsp",
- .parent = &pll1_sysclk1,
- .lpsc = DM646X_LPSC_C64X_CPU,
- .usecount = 1, /* REVISIT how to disable? */
-};
-
-static struct clk arm_clk = {
- .name = "arm",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_ARM,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_cc_clk = {
- .name = "edma_cc",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_TPCC,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc0_clk = {
- .name = "edma_tc0",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_TPTC0,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc1_clk = {
- .name = "edma_tc1",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_TPTC1,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc2_clk = {
- .name = "edma_tc2",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_TPTC2,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc3_clk = {
- .name = "edma_tc3",
- .parent = &pll1_sysclk2,
- .lpsc = DM646X_LPSC_TPTC3,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk uart0_clk = {
- .name = "uart0",
- .parent = &aux_clkin,
- .lpsc = DM646X_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
- .name = "uart1",
- .parent = &aux_clkin,
- .lpsc = DM646X_LPSC_UART1,
-};
-
-static struct clk uart2_clk = {
- .name = "uart2",
- .parent = &aux_clkin,
- .lpsc = DM646X_LPSC_UART2,
-};
-
-static struct clk i2c_clk = {
- .name = "I2CCLK",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_I2C,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_GPIO,
-};
-
-static struct clk mcasp0_clk = {
- .name = "mcasp0",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_McASP0,
-};
-
-static struct clk mcasp1_clk = {
- .name = "mcasp1",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_McASP1,
-};
-
-static struct clk aemif_clk = {
- .name = "aemif",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_AEMIF,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk emac_clk = {
- .name = "emac",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_EMAC,
-};
-
-static struct clk pwm0_clk = {
- .name = "pwm0",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_PWM0,
- .usecount = 1, /* REVIST: disabling hangs system */
-};
-
-static struct clk pwm1_clk = {
- .name = "pwm1",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_PWM1,
- .usecount = 1, /* REVIST: disabling hangs system */
-};
-
-static struct clk timer0_clk = {
- .name = "timer0",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
- .name = "timer1",
- .parent = &pll1_sysclk3,
- .lpsc = DM646X_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
- .name = "timer2",
- .parent = &pll1_sysclk3,
- .flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */
-};
-
-
-static struct clk ide_clk = {
- .name = "ide",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_ATA,
-};
-
-static struct clk vpif0_clk = {
- .name = "vpif0",
- .parent = &ref_clk,
- .lpsc = DM646X_LPSC_VPSSMSTR,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk vpif1_clk = {
- .name = "vpif1",
- .parent = &ref_clk,
- .lpsc = DM646X_LPSC_VPSSSLV,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk_lookup dm646x_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "aux", &aux_clkin),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk1),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk4),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk5),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk6),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk8),
- CLK(NULL, "pll1_sysclk", &pll1_sysclk9),
- CLK(NULL, "pll1_sysclk", &pll1_sysclkbp),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "dsp", &dsp_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "edma_cc", &edma_cc_clk),
- CLK(NULL, "edma_tc0", &edma_tc0_clk),
- CLK(NULL, "edma_tc1", &edma_tc1_clk),
- CLK(NULL, "edma_tc2", &edma_tc2_clk),
- CLK(NULL, "edma_tc3", &edma_tc3_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
- CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- CLK("davinci-wdt", NULL, &timer2_clk),
- CLK("palm_bk3710", NULL, &ide_clk),
- CLK(NULL, "vpif0", &vpif0_clk),
- 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,
.ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET,
@@ -803,8 +485,6 @@ static struct davinci_id dm646x_ids[] = {
},
};
-static u32 dm646x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
/*
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
@@ -889,8 +569,6 @@ static const struct davinci_soc_info davinci_soc_info_dm646x = {
.jtag_id_reg = 0x01c40028,
.ids = dm646x_ids,
.ids_num = ARRAY_SIZE(dm646x_ids),
- .psc_bases = dm646x_psc_bases,
- .psc_bases_num = ARRAY_SIZE(dm646x_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
.pinmux_pins = dm646x_pins,
.pinmux_pins_num = ARRAY_SIZE(dm646x_pins),
@@ -961,7 +639,6 @@ 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;
@@ -979,11 +656,7 @@ void __init dm646x_init_time(unsigned long ref_clk_rate,
/* 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
This removes the unused legacy clock init code from
arch/arm/mach-davinci/da830.c.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- rebased
arch/arm/mach-davinci/da830.c | 413 +-----------------------------------------
1 file changed, 1 insertion(+), 412 deletions(-)
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 0b6d0f3..9071ee2 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -26,11 +26,6 @@
#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
@@ -43,404 +38,6 @@
#define DA830_REF_FREQ 24000000
-#ifndef CONFIG_COMMON_CLK
-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 = DA830_REF_FREQ,
-};
-
-static struct clk pll0_clk = {
- .name = "pll0",
- .parent = &ref_clk,
- .pll_data = &pll0_data,
- .flags = CLK_PLL,
-};
-
-static struct clk pll0_aux_clk = {
- .name = "pll0_aux_clk",
- .parent = &pll0_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-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,
-};
-
-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 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 scr0_ss_clk = {
- .name = "scr0_ss",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_SCR0_SS,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk scr1_ss_clk = {
- .name = "scr1_ss",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_SCR1_SS,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk scr2_ss_clk = {
- .name = "scr2_ss",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_SCR2_SS,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk dmax_clk = {
- .name = "dmax",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_PRUSS,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc_clk = {
- .name = "tpcc",
- .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 mmcsd_clk = {
- .name = "mmcsd",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_MMC_SD,
-};
-
-static struct clk uart0_clk = {
- .name = "uart0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_UART0,
-};
-
-static struct clk uart1_clk = {
- .name = "uart1",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_UART1,
- .gpsc = 1,
-};
-
-static struct clk uart2_clk = {
- .name = "uart2",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_UART2,
- .gpsc = 1,
-};
-
-static struct clk spi0_clk = {
- .name = "spi0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC0_SPI0,
-};
-
-static struct clk spi1_clk = {
- .name = "spi1",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_SPI1,
- .gpsc = 1,
-};
-
-static struct clk ecap0_clk = {
- .name = "ecap0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_ECAP,
- .gpsc = 1,
-};
-
-static struct clk ecap1_clk = {
- .name = "ecap1",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_ECAP,
- .gpsc = 1,
-};
-
-static struct clk ecap2_clk = {
- .name = "ecap2",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_ECAP,
- .gpsc = 1,
-};
-
-static struct clk pwm0_clk = {
- .name = "pwm0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_PWM,
- .gpsc = 1,
-};
-
-static struct clk pwm1_clk = {
- .name = "pwm1",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_PWM,
- .gpsc = 1,
-};
-
-static struct clk pwm2_clk = {
- .name = "pwm2",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_PWM,
- .gpsc = 1,
-};
-
-static struct clk eqep0_clk = {
- .name = "eqep0",
- .parent = &pll0_sysclk2,
- .lpsc = DA830_LPSC1_EQEP,
- .gpsc = 1,
-};
-
-static struct clk eqep1_clk = {
- .name = "eqep1",
- .parent = &pll0_sysclk2,
- .lpsc = DA830_LPSC1_EQEP,
- .gpsc = 1,
-};
-
-static struct clk lcdc_clk = {
- .name = "lcdc",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_LCDC,
- .gpsc = 1,
-};
-
-static struct clk mcasp0_clk = {
- .name = "mcasp0",
- .parent = &pll0_sysclk2,
- .lpsc = DA8XX_LPSC1_McASP0,
- .gpsc = 1,
-};
-
-static struct clk mcasp1_clk = {
- .name = "mcasp1",
- .parent = &pll0_sysclk2,
- .lpsc = DA830_LPSC1_McASP1,
- .gpsc = 1,
-};
-
-static struct clk mcasp2_clk = {
- .name = "mcasp2",
- .parent = &pll0_sysclk2,
- .lpsc = DA830_LPSC1_McASP2,
- .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 aemif_clk = {
- .name = "aemif",
- .parent = &pll0_sysclk3,
- .lpsc = DA8XX_LPSC0_EMIF25,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk aintc_clk = {
- .name = "aintc",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC0_AINTC,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk secu_mgr_clk = {
- .name = "secu_mgr",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC0_SECU_MGR,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk emac_clk = {
- .name = "emac",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_CPGMAC,
- .gpsc = 1,
-};
-
-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 usb11_clk = {
- .name = "usb11",
- .parent = &pll0_sysclk4,
- .lpsc = DA8XX_LPSC1_USB11,
- .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,
-};
-
-static struct clk rmii_clk = {
- .name = "rmii",
- .parent = &pll0_sysclk7,
-};
-
-static struct clk_lookup da830_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll0", &pll0_clk),
- CLK(NULL, "pll0_aux", &pll0_aux_clk),
- 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("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, "scr0_ss", &scr0_ss_clk),
- CLK(NULL, "scr1_ss", &scr1_ss_clk),
- CLK(NULL, "scr2_ss", &scr2_ss_clk),
- CLK(NULL, "dmax", &dmax_clk),
- CLK(NULL, "tpcc", &tpcc_clk),
- CLK(NULL, "tptc0", &tptc0_clk),
- CLK(NULL, "tptc1", &tptc1_clk),
- CLK("da830-mmc.0", NULL, &mmcsd_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK(NULL, "ecap0", &ecap0_clk),
- CLK(NULL, "ecap1", &ecap1_clk),
- CLK(NULL, "ecap2", &ecap2_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK("eqep.0", NULL, &eqep0_clk),
- CLK("eqep.1", NULL, &eqep1_clk),
- CLK("da8xx_lcdc.0", "fck", &lcdc_clk),
- CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
- CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
- CLK("davinci-mcasp.2", NULL, &mcasp2_clk),
- CLK("musb-da8xx", NULL, &usb20_clk),
- CLK("cppi41-dmaengine", NULL, &cppi41_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "aintc", &aintc_clk),
- CLK(NULL, "secu_mgr", &secu_mgr_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK("i2c_davinci.2", NULL, &i2c1_clk),
- CLK("ohci-da8xx", NULL, &usb11_clk),
- CLK(NULL, "emif3", &emif3_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "rmii", &rmii_clk),
- CLK(NULL, NULL, NULL),
-};
-#endif
-
/*
* Device specific mux setup
*
@@ -1138,8 +735,6 @@ static struct map_desc da830_io_desc[] = {
},
};
-static u32 da830_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
-
/* Contents of JTAG ID register used to identify exact cpu type */
static struct davinci_id da830_ids[] = {
{
@@ -1208,8 +803,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),
- .psc_bases = da830_psc_bases,
- .psc_bases_num = ARRAY_SIZE(da830_psc_bases),
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
.pinmux_pins = da830_pins,
.pinmux_pins_num = ARRAY_SIZE(da830_pins),
@@ -1231,7 +824,6 @@ void __init da830_init(void)
void __init da830_init_time(void)
{
-#ifdef CONFIG_COMMON_CLK
void __iomem *pll0, *psc0, *psc1;
struct clk *clk;
@@ -1258,9 +850,6 @@ void __init da830_init_time(void)
clk = clk_register_fixed_factor(NULL, "rmii", "pll0_sysclk7", 0, 1, 1);
clk_register_clkdev(clk, "rmii", NULL);
-#else
- da8xx_register_cfgchip();
- davinci_clk_init(da830_clks);
-#endif
+
davinci_timer_init();
}
--
2.7.4
This removes the unused legacy clock init code from
arch/arm/mach-davinci/{devices,usb}-da8xx}.c.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- rebased
arch/arm/mach-davinci/devices-da8xx.c | 29 -----
arch/arm/mach-davinci/usb-da8xx.c | 238 ----------------------------------
2 files changed, 267 deletions(-)
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 1a06b09..75d3a71 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -31,11 +31,6 @@
#include "cpuidle.h"
#include "sram.h"
-#ifndef CONFIG_COMMON_CLK
-#include <mach/clock.h>
-#include "clock.h"
-#endif
-
#define DA8XX_TPCC_BASE 0x01c00000
#define DA8XX_TPTC0_BASE 0x01c08000
#define DA8XX_TPTC1_BASE 0x01c08400
@@ -1046,29 +1041,6 @@ int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect)
}
#ifdef CONFIG_ARCH_DAVINCI_DA850
-#ifndef CONFIG_COMMON_CLK
-static struct clk sata_refclk = {
- .name = "sata_refclk",
- .set_rate = davinci_simple_set_rate,
-};
-
-static struct clk_lookup sata_refclk_lookup =
- CLK("ahci_da850", "refclk", &sata_refclk);
-
-int __init da850_register_sata_refclk(int rate)
-{
- int ret;
-
- sata_refclk.rate = rate;
- ret = clk_register(&sata_refclk);
- if (ret)
- return ret;
-
- clkdev_add(&sata_refclk_lookup);
-
- return 0;
-}
-#else
int __init da850_register_sata_refclk(int rate)
{
struct clk *clk;
@@ -1079,7 +1051,6 @@ int __init da850_register_sata_refclk(int rate)
return clk_register_clkdev(clk, "refclk", "ahci_da850");
}
-#endif
static struct resource da850_sata_resources[] = {
{
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index b960609..a23f88d 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -21,18 +21,9 @@
#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",
.id = -1,
@@ -136,234 +127,6 @@ 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,
-};
-
-static struct clk_lookup usb_refclkin_lookup =
- CLK(NULL, "usb_refclkin", &usb_refclkin);
-
-/**
- * da8xx_register_usb_refclkin - register USB_REFCLKIN clock
- *
- * @rate: The clock rate in Hz
- *
- * This clock is only needed if the board provides an external USB_REFCLKIN
- * signal, in which case it will be used as the parent of usb20_phy_clk and/or
- * usb11_phy_clk.
- */
-int __init da8xx_register_usb_refclkin(int rate)
-{
- int ret;
-
- usb_refclkin.rate = rate;
- ret = clk_register(&usb_refclkin);
- if (ret)
- return ret;
-
- clkdev_add(&usb_refclkin_lookup);
-
- return 0;
-}
-
-static void usb20_phy_clk_enable(struct clk *clk)
-{
- u32 val;
- u32 timeout = 500000; /* 500 msec */
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- /* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
- davinci_clk_enable(usb20_clk);
-
- /*
- * Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
- * host may use the PLL clock without USB 2.0 OTG being used.
- */
- val &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN);
- val |= CFGCHIP2_PHY_PLLON;
-
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- while (--timeout) {
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
- if (val & CFGCHIP2_PHYCLKGD)
- goto done;
- udelay(1);
- }
-
- pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
-done:
- davinci_clk_disable(usb20_clk);
-}
-
-static void usb20_phy_clk_disable(struct clk *clk)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
- val |= CFGCHIP2_PHYPWRDN;
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-}
-
-static int usb20_phy_clk_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- /* Set the mux depending on the parent clock. */
- if (parent == &usb_refclkin) {
- val &= ~CFGCHIP2_USB2PHYCLKMUX;
- } else if (strcmp(parent->name, "pll0_aux_clk") == 0) {
- val |= CFGCHIP2_USB2PHYCLKMUX;
- } else {
- pr_err("Bad parent on USB 2.0 PHY clock\n");
- return -EINVAL;
- }
-
- /* reference frequency also comes from parent clock */
- val &= ~CFGCHIP2_REFFREQ_MASK;
- switch (clk_get_rate(parent)) {
- 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:
- pr_err("Bad parent clock rate on USB 2.0 PHY clock\n");
- return -EINVAL;
- }
-
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- return 0;
-}
-
-static struct clk usb20_phy_clk = {
- .name = "usb0_clk48",
- .clk_enable = usb20_phy_clk_enable,
- .clk_disable = usb20_phy_clk_disable,
- .set_parent = usb20_phy_clk_set_parent,
-};
-
-static struct clk_lookup usb20_phy_clk_lookup =
- CLK("da8xx-usb-phy", "usb0_clk48", &usb20_phy_clk);
-
-/**
- * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
- *
- * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
- * or "pll0_aux" if false.
- */
-int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
-{
- struct clk *parent;
- int ret;
-
- usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
- ret = PTR_ERR_OR_ZERO(usb20_clk);
- if (ret)
- return ret;
-
- parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
- ret = PTR_ERR_OR_ZERO(parent);
- if (ret) {
- clk_put(usb20_clk);
- return ret;
- }
-
- usb20_phy_clk.parent = parent;
- ret = clk_register(&usb20_phy_clk);
- if (!ret)
- clkdev_add(&usb20_phy_clk_lookup);
-
- clk_put(parent);
-
- return ret;
-}
-
-static int usb11_phy_clk_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 val;
-
- val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- /* Set the USB 1.1 PHY clock mux based on the parent clock. */
- if (parent == &usb20_phy_clk) {
- val &= ~CFGCHIP2_USB1PHYCLKMUX;
- } else if (parent == &usb_refclkin) {
- val |= CFGCHIP2_USB1PHYCLKMUX;
- } else {
- pr_err("Bad parent on USB 1.1 PHY clock\n");
- return -EINVAL;
- }
-
- writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- return 0;
-}
-
-static struct clk usb11_phy_clk = {
- .name = "usb1_clk48",
- .set_parent = usb11_phy_clk_set_parent,
-};
-
-static struct clk_lookup usb11_phy_clk_lookup =
- CLK("da8xx-usb-phy", "usb1_clk48", &usb11_phy_clk);
-
-/**
- * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
- *
- * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
- * or "usb0_clk48" if false.
- */
-int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
-{
- struct clk *parent;
- int ret = 0;
-
- if (use_usb_refclkin)
- parent = clk_get(NULL, "usb_refclkin");
- else
- parent = clk_get(&da8xx_usb_phy.dev, "usb0_clk48");
- if (IS_ERR(parent))
- return PTR_ERR(parent);
-
- usb11_phy_clk.parent = parent;
- ret = clk_register(&usb11_phy_clk);
- if (!ret)
- clkdev_add(&usb11_phy_clk_lookup);
-
- clk_put(parent);
-
- return ret;
-}
-#else
/**
* da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
*
@@ -429,4 +192,3 @@ int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
return clk_register_clkdev(clk, "usb1_clk48", "da8xx-usb-phy");
}
-#endif
--
2.7.4
This removes the unused legacy clock init code from
arch/arm/mach-davinci/da850.c.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- rebased
arch/arm/mach-davinci/da850.c | 646 ------------------------------------------
1 file changed, 646 deletions(-)
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 0fdf647..a045f2b 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),
@@ -1393,7 +760,6 @@ void __init da850_init(void)
void __init da850_init_time(void)
{
-#ifdef CONFIG_COMMON_CLK
void __iomem *pll0, *pll1, *psc0, *psc1;
struct regmap *cfgchip;
struct clk *clk;
@@ -1438,18 +804,6 @@ void __init da850_init_time(void)
clk = da8xx_cfgchip_register_tbclk(cfgchip);
clk_register_clkdev(clk, "tbclk", "ehrpwm.0");
clk_register_clkdev(clk, "tbclk", "ehrpwm.1");
-#else
- struct regmap *cfgchip;
- cfgchip = da8xx_register_cfgchip();
- if (WARN(IS_ERR(cfgchip), "failed to register CFGCHIP syscon"))
- return;
-
- /* Unlock writing to PLL registers */
- regmap_write_bits(cfgchip, CFGCHIP(0), CFGCHIP0_PLL_MASTER_LOCK, 0);
- regmap_write_bits(cfgchip, CFGCHIP(3), CFGCHIP3_PLL1_MASTER_LOCK, 0);
-
- davinci_clk_init(da850_clks);
-#endif
davinci_timer_init();
}
--
2.7.4
This removes the unused legacy clock init code from
arch/arm/mach-davinci/dm355.c.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- none
arch/arm/mach-davinci/dm355.c | 357 +-----------------------------------------
1 file changed, 1 insertion(+), 356 deletions(-)
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 2c19739..815f7b0 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -35,11 +35,6 @@
#include "davinci.h"
#include "mux.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)
#define DM355_VENC_BASE (IO_PHYS + 0x70400)
@@ -49,349 +44,6 @@
*/
#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,
- .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
-};
-
-static struct pll_data pll2_data = {
- .num = 2,
- .phys_base = DAVINCI_PLL2_BASE,
- .flags = PLL_HAS_PREDIV,
-};
-
-static struct clk ref_clk = {
- .name = "ref_clk",
- /* FIXME -- crystal rate is board-specific */
- .rate = DM355_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
- .name = "pll1",
- .parent = &ref_clk,
- .flags = CLK_PLL,
- .pll_data = &pll1_data,
-};
-
-static struct clk pll1_aux_clk = {
- .name = "pll1_aux_clk",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
- .name = "pll1_sysclk1",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-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 struct clk pll1_sysclk4 = {
- .name = "pll1_sysclk4",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclkbp = {
- .name = "pll1_sysclkbp",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
- .div_reg = BPDIV
-};
-
-static struct clk vpss_dac_clk = {
- .name = "vpss_dac",
- .parent = &pll1_sysclk3,
- .lpsc = DM355_LPSC_VPSS_DAC,
-};
-
-static struct clk vpss_master_clk = {
- .name = "vpss_master",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_VPSSMSTR,
- .flags = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
- .name = "vpss_slave",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk clkout1_clk = {
- .name = "clkout1",
- .parent = &pll1_aux_clk,
- /* NOTE: clkout1 can be externally gated by muxing GPIO-18 */
-};
-
-static struct clk clkout2_clk = {
- .name = "clkout2",
- .parent = &pll1_sysclkbp,
-};
-
-static struct clk pll2_clk = {
- .name = "pll2",
- .parent = &ref_clk,
- .flags = CLK_PLL,
- .pll_data = &pll2_data,
-};
-
-static struct clk pll2_sysclk1 = {
- .name = "pll2_sysclk1",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-static struct clk pll2_sysclkbp = {
- .name = "pll2_sysclkbp",
- .parent = &pll2_clk,
- .flags = CLK_PLL | PRE_PLL,
- .div_reg = BPDIV
-};
-
-static struct clk clkout3_clk = {
- .name = "clkout3",
- .parent = &pll2_sysclkbp,
- /* NOTE: clkout3 can be externally gated by muxing GPIO-16 */
-};
-
-static struct clk arm_clk = {
- .name = "arm_clk",
- .parent = &pll1_sysclk1,
- .lpsc = DAVINCI_LPSC_ARM,
- .flags = ALWAYS_ENABLED,
-};
-
-/*
- * NOT LISTED below, and not touched by Linux
- * - in SyncReset state by default
- * .lpsc = DAVINCI_LPSC_TPCC,
- * .lpsc = DAVINCI_LPSC_TPTC0,
- * .lpsc = DAVINCI_LPSC_TPTC1,
- * .lpsc = DAVINCI_LPSC_DDR_EMIF, .parent = &sysclk2_clk,
- * .lpsc = DAVINCI_LPSC_MEMSTICK,
- * - in Enabled state by default
- * .lpsc = DAVINCI_LPSC_SYSTEM_SUBSYS,
- * .lpsc = DAVINCI_LPSC_SCR2, // "bus"
- * .lpsc = DAVINCI_LPSC_SCR3, // "bus"
- * .lpsc = DAVINCI_LPSC_SCR4, // "bus"
- * .lpsc = DAVINCI_LPSC_CROSSBAR, // "emulation"
- * .lpsc = DAVINCI_LPSC_CFG27, // "test"
- * .lpsc = DAVINCI_LPSC_CFG3, // "test"
- * .lpsc = DAVINCI_LPSC_CFG5, // "test"
- */
-
-static struct clk mjcp_clk = {
- .name = "mjcp",
- .parent = &pll1_sysclk1,
- .lpsc = DAVINCI_LPSC_IMCOP,
-};
-
-static struct clk uart0_clk = {
- .name = "uart0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
- .name = "uart1",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_UART1,
-};
-
-static struct clk uart2_clk = {
- .name = "uart2",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_UART2,
-};
-
-static struct clk i2c_clk = {
- .name = "i2c",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_I2C,
-};
-
-static struct clk asp0_clk = {
- .name = "asp0",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_McBSP,
-};
-
-static struct clk asp1_clk = {
- .name = "asp1",
- .parent = &pll1_sysclk2,
- .lpsc = DM355_LPSC_McBSP1,
-};
-
-static struct clk mmcsd0_clk = {
- .name = "mmcsd0",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
- .name = "mmcsd1",
- .parent = &pll1_sysclk2,
- .lpsc = DM355_LPSC_MMC_SD1,
-};
-
-static struct clk spi0_clk = {
- .name = "spi0",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_SPI,
-};
-
-static struct clk spi1_clk = {
- .name = "spi1",
- .parent = &pll1_sysclk2,
- .lpsc = DM355_LPSC_SPI1,
-};
-
-static struct clk spi2_clk = {
- .name = "spi2",
- .parent = &pll1_sysclk2,
- .lpsc = DM355_LPSC_SPI2,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk aemif_clk = {
- .name = "aemif",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_AEMIF,
-};
-
-static struct clk pwm0_clk = {
- .name = "pwm0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM0,
-};
-
-static struct clk pwm1_clk = {
- .name = "pwm1",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM1,
-};
-
-static struct clk pwm2_clk = {
- .name = "pwm2",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM2,
-};
-
-static struct clk pwm3_clk = {
- .name = "pwm3",
- .parent = &pll1_aux_clk,
- .lpsc = DM355_LPSC_PWM3,
-};
-
-static struct clk timer0_clk = {
- .name = "timer0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
- .name = "timer1",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
- .name = "timer2",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER2,
- .usecount = 1, /* REVISIT: why can't this be disabled? */
-};
-
-static struct clk timer3_clk = {
- .name = "timer3",
- .parent = &pll1_aux_clk,
- .lpsc = DM355_LPSC_TIMER3,
-};
-
-static struct clk rto_clk = {
- .name = "rto",
- .parent = &pll1_aux_clk,
- .lpsc = DM355_LPSC_RTO,
-};
-
-static struct clk usb_clk = {
- .name = "usb",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_USB,
-};
-
-static struct clk_lookup dm355_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
- CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
- CLK(NULL, "vpss_dac", &vpss_dac_clk),
- CLK("vpss", "master", &vpss_master_clk),
- CLK("vpss", "slave", &vpss_slave_clk),
- CLK(NULL, "clkout1", &clkout1_clk),
- CLK(NULL, "clkout2", &clkout2_clk),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
- CLK(NULL, "clkout3", &clkout3_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "mjcp", &mjcp_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK("davinci-mcbsp.0", NULL, &asp0_clk),
- CLK("davinci-mcbsp.1", NULL, &asp1_clk),
- CLK("dm6441-mmc.0", NULL, &mmcsd0_clk),
- CLK("dm6441-mmc.1", NULL, &mmcsd1_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK("spi_davinci.2", NULL, &spi2_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK(NULL, "pwm3", &pwm3_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- CLK("davinci-wdt", NULL, &timer2_clk),
- CLK(NULL, "timer3", &timer3_clk),
- CLK(NULL, "rto", &rto_clk),
- CLK(NULL, "usb", &usb_clk),
- CLK(NULL, NULL, NULL),
-};
-#endif
-/*----------------------------------------------------------------------*/
-
static u64 dm355_spi0_dma_mask = DMA_BIT_MASK(32);
static struct resource dm355_spi0_resources[] = {
@@ -933,8 +585,6 @@ static struct davinci_id dm355_ids[] = {
},
};
-static u32 dm355_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
/*
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
@@ -1019,8 +669,6 @@ static const struct davinci_soc_info davinci_soc_info_dm355 = {
.jtag_id_reg = 0x01c40028,
.ids = dm355_ids,
.ids_num = ARRAY_SIZE(dm355_ids),
- .psc_bases = dm355_psc_bases,
- .psc_bases_num = ARRAY_SIZE(dm355_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
.pinmux_pins = dm355_pins,
.pinmux_pins_num = ARRAY_SIZE(dm355_pins),
@@ -1053,7 +701,6 @@ 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);
@@ -1071,9 +718,7 @@ void __init dm355_init_time(void)
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
This removes the unused legacy clock init code from
arch/arm/mach-davinci/dm365.c.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- none
arch/arm/mach-davinci/dm365.c | 449 +-----------------------------------------
1 file changed, 1 insertion(+), 448 deletions(-)
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index ff79bb0..69be88a 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -40,11 +40,6 @@
#include "davinci.h"
#include "mux.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
#define DM365_KEYSCAN_BASE 0x01c69400
@@ -60,441 +55,6 @@
#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,
- .flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
-};
-
-static struct pll_data pll2_data = {
- .num = 2,
- .phys_base = DAVINCI_PLL2_BASE,
- .flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
-};
-
-static struct clk ref_clk = {
- .name = "ref_clk",
- .rate = DM365_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
- .name = "pll1",
- .parent = &ref_clk,
- .flags = CLK_PLL,
- .pll_data = &pll1_data,
-};
-
-static struct clk pll1_aux_clk = {
- .name = "pll1_aux_clk",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclkbp = {
- .name = "pll1_sysclkbp",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
- .div_reg = BPDIV
-};
-
-static struct clk clkout0_clk = {
- .name = "clkout0",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
- .name = "pll1_sysclk1",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-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 struct clk pll1_sysclk4 = {
- .name = "pll1_sysclk4",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclk5 = {
- .name = "pll1_sysclk5",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_sysclk6 = {
- .name = "pll1_sysclk6",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV6,
-};
-
-static struct clk pll1_sysclk7 = {
- .name = "pll1_sysclk7",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV7,
-};
-
-static struct clk pll1_sysclk8 = {
- .name = "pll1_sysclk8",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV8,
-};
-
-static struct clk pll1_sysclk9 = {
- .name = "pll1_sysclk9",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV9,
-};
-
-static struct clk pll2_clk = {
- .name = "pll2",
- .parent = &ref_clk,
- .flags = CLK_PLL,
- .pll_data = &pll2_data,
-};
-
-static struct clk pll2_aux_clk = {
- .name = "pll2_aux_clk",
- .parent = &pll2_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk clkout1_clk = {
- .name = "clkout1",
- .parent = &pll2_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll2_sysclk1 = {
- .name = "pll2_sysclk1",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-static struct clk pll2_sysclk2 = {
- .name = "pll2_sysclk2",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV2,
-};
-
-static struct clk pll2_sysclk3 = {
- .name = "pll2_sysclk3",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV3,
-};
-
-static struct clk pll2_sysclk4 = {
- .name = "pll2_sysclk4",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll2_sysclk5 = {
- .name = "pll2_sysclk5",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll2_sysclk6 = {
- .name = "pll2_sysclk6",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV6,
-};
-
-static struct clk pll2_sysclk7 = {
- .name = "pll2_sysclk7",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV7,
-};
-
-static struct clk pll2_sysclk8 = {
- .name = "pll2_sysclk8",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV8,
-};
-
-static struct clk pll2_sysclk9 = {
- .name = "pll2_sysclk9",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV9,
-};
-
-static struct clk vpss_dac_clk = {
- .name = "vpss_dac",
- .parent = &pll1_sysclk3,
- .lpsc = DM365_LPSC_DAC_CLK,
-};
-
-static struct clk vpss_master_clk = {
- .name = "vpss_master",
- .parent = &pll1_sysclk5,
- .lpsc = DM365_LPSC_VPSSMSTR,
- .flags = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
- .name = "vpss_slave",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk arm_clk = {
- .name = "arm_clk",
- .parent = &pll2_sysclk2,
- .lpsc = DAVINCI_LPSC_ARM,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk uart0_clk = {
- .name = "uart0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
- .name = "uart1",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_UART1,
-};
-
-static struct clk i2c_clk = {
- .name = "i2c",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_I2C,
-};
-
-static struct clk mmcsd0_clk = {
- .name = "mmcsd0",
- .parent = &pll1_sysclk8,
- .lpsc = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
- .name = "mmcsd1",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_MMC_SD1,
-};
-
-static struct clk spi0_clk = {
- .name = "spi0",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_SPI,
-};
-
-static struct clk spi1_clk = {
- .name = "spi1",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_SPI1,
-};
-
-static struct clk spi2_clk = {
- .name = "spi2",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_SPI2,
-};
-
-static struct clk spi3_clk = {
- .name = "spi3",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_SPI3,
-};
-
-static struct clk spi4_clk = {
- .name = "spi4",
- .parent = &pll1_aux_clk,
- .lpsc = DM365_LPSC_SPI4,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk aemif_clk = {
- .name = "aemif",
- .parent = &pll1_sysclk4,
- .lpsc = DAVINCI_LPSC_AEMIF,
-};
-
-static struct clk pwm0_clk = {
- .name = "pwm0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM0,
-};
-
-static struct clk pwm1_clk = {
- .name = "pwm1",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM1,
-};
-
-static struct clk pwm2_clk = {
- .name = "pwm2",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM2,
-};
-
-static struct clk pwm3_clk = {
- .name = "pwm3",
- .parent = &ref_clk,
- .lpsc = DM365_LPSC_PWM3,
-};
-
-static struct clk timer0_clk = {
- .name = "timer0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
- .name = "timer1",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
- .name = "timer2",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER2,
- .usecount = 1,
-};
-
-static struct clk timer3_clk = {
- .name = "timer3",
- .parent = &pll1_aux_clk,
- .lpsc = DM365_LPSC_TIMER3,
-};
-
-static struct clk usb_clk = {
- .name = "usb",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_USB,
-};
-
-static struct clk emac_clk = {
- .name = "emac",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_EMAC,
-};
-
-static struct clk voicecodec_clk = {
- .name = "voice_codec",
- .parent = &pll2_sysclk4,
- .lpsc = DM365_LPSC_VOICE_CODEC,
-};
-
-static struct clk asp0_clk = {
- .name = "asp0",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_McBSP1,
-};
-
-static struct clk rto_clk = {
- .name = "rto",
- .parent = &pll1_sysclk4,
- .lpsc = DM365_LPSC_RTO,
-};
-
-static struct clk mjcp_clk = {
- .name = "mjcp",
- .parent = &pll1_sysclk3,
- .lpsc = DM365_LPSC_MJCP,
-};
-
-static struct clk_lookup dm365_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
- CLK(NULL, "clkout0", &clkout0_clk),
- CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
- CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
- CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
- CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
- CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
- CLK(NULL, "pll1_sysclk8", &pll1_sysclk8),
- CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_aux", &pll2_aux_clk),
- CLK(NULL, "clkout1", &clkout1_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
- CLK(NULL, "pll2_sysclk3", &pll2_sysclk3),
- CLK(NULL, "pll2_sysclk4", &pll2_sysclk4),
- CLK(NULL, "pll2_sysclk5", &pll2_sysclk5),
- CLK(NULL, "pll2_sysclk6", &pll2_sysclk6),
- CLK(NULL, "pll2_sysclk7", &pll2_sysclk7),
- CLK(NULL, "pll2_sysclk8", &pll2_sysclk8),
- CLK(NULL, "pll2_sysclk9", &pll2_sysclk9),
- CLK(NULL, "vpss_dac", &vpss_dac_clk),
- CLK("vpss", "master", &vpss_master_clk),
- CLK("vpss", "slave", &vpss_slave_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK("da830-mmc.0", NULL, &mmcsd0_clk),
- CLK("da830-mmc.1", NULL, &mmcsd1_clk),
- CLK("spi_davinci.0", NULL, &spi0_clk),
- CLK("spi_davinci.1", NULL, &spi1_clk),
- CLK("spi_davinci.2", NULL, &spi2_clk),
- CLK("spi_davinci.3", NULL, &spi3_clk),
- CLK("spi_davinci.4", NULL, &spi4_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK(NULL, "pwm3", &pwm3_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- CLK("davinci-wdt", NULL, &timer2_clk),
- CLK(NULL, "timer3", &timer3_clk),
- CLK(NULL, "usb", &usb_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK("davinci_voicecodec", NULL, &voicecodec_clk),
- CLK("davinci-mcbsp", NULL, &asp0_clk),
- CLK(NULL, "rto", &rto_clk),
- CLK(NULL, "mjcp", &mjcp_clk),
- CLK(NULL, NULL, NULL),
-};
-#endif
-/*----------------------------------------------------------------------*/
-
#define INTMUX 0x18
#define EVTMUX 0x1c
@@ -1061,8 +621,6 @@ static struct davinci_id dm365_ids[] = {
},
};
-static u32 dm365_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
static struct davinci_timer_info dm365_timer_info = {
.timers = davinci_timer_instance,
.clockevent_id = T0_BOT,
@@ -1123,8 +681,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = {
.jtag_id_reg = 0x01c40028,
.ids = dm365_ids,
.ids_num = ARRAY_SIZE(dm365_ids),
- .psc_bases = dm365_psc_bases,
- .psc_bases_num = ARRAY_SIZE(dm365_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
.pinmux_pins = dm365_pins,
.pinmux_pins_num = ARRAY_SIZE(dm365_pins),
@@ -1178,7 +734,6 @@ 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);
@@ -1190,9 +745,7 @@ void __init dm365_init_time(void)
dm365_pll_clk_init(pll1, pll2);
dm365_psc_clk_init(psc);
-#else
- davinci_clk_init(dm365_clks);
-#endif
+
davinci_timer_init();
}
--
2.7.4
This adds device tree support to the davinci timer so that when clocks
are moved to device tree, the timer will still work.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- none
arch/arm/mach-davinci/Kconfig | 1 +
arch/arm/mach-davinci/time.c | 17 ++++++++++++++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index ba9912b..da8a039 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -59,6 +59,7 @@ config MACH_DA8XX_DT
default y
depends on ARCH_DAVINCI_DA850
select PINCTRL
+ select TIMER_OF
help
Say y here to include support for TI DaVinci DA850 based using
Flattened Device Tree. More information at Documentation/devicetree
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index bd0c80e..44470e9 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -333,9 +333,9 @@ static struct clock_event_device clockevent_davinci = {
};
-void __init davinci_timer_init(void)
+static int __init of_davinci_timer_init(struct device_node *node)
{
- struct clk *timer_clk;
+ struct clk *timer_clk = NULL;
struct davinci_soc_info *soc_info = &davinci_soc_info;
unsigned int clockevent_id;
unsigned int clocksource_id;
@@ -371,7 +371,10 @@ void __init davinci_timer_init(void)
}
}
- timer_clk = clk_get(NULL, "timer0");
+ if (node)
+ timer_clk = of_clk_get(node, 0);
+ if (IS_ERR_OR_NULL(timer_clk))
+ timer_clk = clk_get(NULL, "timer0");
BUG_ON(IS_ERR(timer_clk));
clk_prepare_enable(timer_clk);
@@ -399,4 +402,12 @@ void __init davinci_timer_init(void)
for (i=0; i< ARRAY_SIZE(timers); i++)
timer32_config(&timers[i]);
+
+ return 0;
+}
+TIMER_OF_DECLARE(davinci_timer, "ti,davinci-timer", of_davinci_timer_init);
+
+void __init davinci_timer_init(void)
+{
+ of_davinci_timer_init(NULL);
}
--
2.7.4
This removes the unused legacy clock code from arch/arm/mach-davinci/.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- none
arch/arm/mach-davinci/clock.c | 745 ----------------------------
arch/arm/mach-davinci/clock.h | 72 ---
arch/arm/mach-davinci/common.c | 2 -
arch/arm/mach-davinci/devices.c | 1 -
arch/arm/mach-davinci/include/mach/clock.h | 3 -
arch/arm/mach-davinci/include/mach/common.h | 2 -
arch/arm/mach-davinci/psc.c | 137 -----
arch/arm/mach-davinci/psc.h | 10 -
arch/arm/mach-davinci/time.c | 2 -
9 files changed, 974 deletions(-)
delete mode 100644 arch/arm/mach-davinci/clock.c
delete mode 100644 arch/arm/mach-davinci/psc.c
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
deleted file mode 100644
index f77a4f7..0000000
--- a/arch/arm/mach-davinci/clock.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * Clock and PLL control for DaVinci devices
- *
- * Copyright (C) 2006-2007 Texas Instruments.
- * Copyright (C) 2008-2009 Deep Root Systems, LLC
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-
-#include <mach/hardware.h>
-
-#include <mach/clock.h>
-#include "psc.h"
-#include <mach/cputype.h>
-#include "clock.h"
-
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-static DEFINE_SPINLOCK(clockfw_lock);
-
-void davinci_clk_enable(struct clk *clk)
-{
- if (clk->parent)
- davinci_clk_enable(clk->parent);
- if (clk->usecount++ == 0) {
- if (clk->flags & CLK_PSC)
- davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
- true, clk->flags);
- else if (clk->clk_enable)
- clk->clk_enable(clk);
- }
-}
-
-void davinci_clk_disable(struct clk *clk)
-{
- if (WARN_ON(clk->usecount == 0))
- return;
- if (--clk->usecount == 0) {
- if (!(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC))
- davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
- false, clk->flags);
- else if (clk->clk_disable)
- clk->clk_disable(clk);
- }
- if (clk->parent)
- davinci_clk_disable(clk->parent);
-}
-
-int davinci_clk_reset(struct clk *clk, bool reset)
-{
- unsigned long flags;
-
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- if (clk->flags & CLK_PSC)
- davinci_psc_reset(clk->gpsc, clk->lpsc, reset);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(davinci_clk_reset);
-
-int davinci_clk_reset_assert(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk) || !clk->reset)
- return -EINVAL;
-
- return clk->reset(clk, true);
-}
-EXPORT_SYMBOL(davinci_clk_reset_assert);
-
-int davinci_clk_reset_deassert(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk) || !clk->reset)
- return -EINVAL;
-
- return clk->reset(clk, false);
-}
-EXPORT_SYMBOL(davinci_clk_reset_deassert);
-
-int clk_enable(struct clk *clk)
-{
- unsigned long flags;
-
- if (!clk)
- return 0;
- else if (IS_ERR(clk))
- return -EINVAL;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- davinci_clk_enable(clk);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
- unsigned long flags;
-
- if (clk == NULL || IS_ERR(clk))
- return;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- davinci_clk_disable(clk);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk))
- return 0;
-
- return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- if (clk == NULL || IS_ERR(clk))
- return 0;
-
- if (clk->round_rate)
- return clk->round_rate(clk, rate);
-
- return clk->rate;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-/* Propagate rate to children */
-static void propagate_rate(struct clk *root)
-{
- struct clk *clk;
-
- list_for_each_entry(clk, &root->children, childnode) {
- if (clk->recalc)
- clk->rate = clk->recalc(clk);
- propagate_rate(clk);
- }
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long flags;
- int ret = -EINVAL;
-
- if (!clk)
- return 0;
- else if (IS_ERR(clk))
- return -EINVAL;
-
- if (clk->set_rate)
- ret = clk->set_rate(clk, rate);
-
- spin_lock_irqsave(&clockfw_lock, flags);
- if (ret == 0) {
- if (clk->recalc)
- clk->rate = clk->recalc(clk);
- propagate_rate(clk);
- }
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
- unsigned long flags;
-
- if (!clk)
- return 0;
- else if (IS_ERR(clk))
- return -EINVAL;
-
- /* Cannot change parent on enabled clock */
- if (WARN_ON(clk->usecount))
- return -EINVAL;
-
- mutex_lock(&clocks_mutex);
- if (clk->set_parent) {
- int ret = clk->set_parent(clk, parent);
-
- if (ret) {
- mutex_unlock(&clocks_mutex);
- return ret;
- }
- }
- clk->parent = parent;
- list_del_init(&clk->childnode);
- list_add(&clk->childnode, &clk->parent->children);
- mutex_unlock(&clocks_mutex);
-
- spin_lock_irqsave(&clockfw_lock, flags);
- if (clk->recalc)
- clk->rate = clk->recalc(clk);
- propagate_rate(clk);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
- if (!clk)
- return NULL;
-
- return clk->parent;
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-int clk_register(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- if (WARN(clk->parent && !clk->parent->rate,
- "CLK: %s parent %s has no rate!\n",
- clk->name, clk->parent->name))
- return -EINVAL;
-
- INIT_LIST_HEAD(&clk->children);
-
- mutex_lock(&clocks_mutex);
- list_add_tail(&clk->node, &clocks);
- if (clk->parent) {
- if (clk->set_parent) {
- int ret = clk->set_parent(clk, clk->parent);
-
- if (ret) {
- mutex_unlock(&clocks_mutex);
- return ret;
- }
- }
- list_add_tail(&clk->childnode, &clk->parent->children);
- }
- mutex_unlock(&clocks_mutex);
-
- /* If rate is already set, use it */
- if (clk->rate)
- return 0;
-
- /* Else, see if there is a way to calculate it */
- if (clk->recalc)
- clk->rate = clk->recalc(clk);
-
- /* Otherwise, default to parent rate */
- else if (clk->parent)
- clk->rate = clk->parent->rate;
-
- return 0;
-}
-EXPORT_SYMBOL(clk_register);
-
-void clk_unregister(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk))
- return;
-
- mutex_lock(&clocks_mutex);
- list_del(&clk->node);
- list_del(&clk->childnode);
- mutex_unlock(&clocks_mutex);
-}
-EXPORT_SYMBOL(clk_unregister);
-
-#ifdef CONFIG_DAVINCI_RESET_CLOCKS
-/*
- * Disable any unused clocks left on by the bootloader
- */
-int __init davinci_clk_disable_unused(void)
-{
- struct clk *ck;
-
- spin_lock_irq(&clockfw_lock);
- list_for_each_entry(ck, &clocks, node) {
- if (ck->usecount > 0)
- continue;
- if (!(ck->flags & CLK_PSC))
- continue;
-
- /* ignore if in Disabled or SwRstDisable states */
- if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc))
- continue;
-
- pr_debug("Clocks: disable unused %s\n", ck->name);
-
- davinci_psc_config(ck->domain, ck->gpsc, ck->lpsc,
- false, ck->flags);
- }
- spin_unlock_irq(&clockfw_lock);
-
- return 0;
-}
-#endif
-
-static unsigned long clk_sysclk_recalc(struct clk *clk)
-{
- u32 v, plldiv;
- struct pll_data *pll;
- unsigned long rate = clk->rate;
-
- /* If this is the PLL base clock, no more calculations needed */
- if (clk->pll_data)
- return rate;
-
- if (WARN_ON(!clk->parent))
- return rate;
-
- rate = clk->parent->rate;
-
- /* Otherwise, the parent must be a PLL */
- if (WARN_ON(!clk->parent->pll_data))
- return rate;
-
- pll = clk->parent->pll_data;
-
- /* If pre-PLL, source clock is before the multiplier and divider(s) */
- if (clk->flags & PRE_PLL)
- rate = pll->input_rate;
-
- if (!clk->div_reg)
- return rate;
-
- v = __raw_readl(pll->base + clk->div_reg);
- if (v & PLLDIV_EN) {
- plldiv = (v & pll->div_ratio_mask) + 1;
- if (plldiv)
- rate /= plldiv;
- }
-
- return rate;
-}
-
-int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
-{
- unsigned v;
- struct pll_data *pll;
- unsigned long input;
- unsigned ratio = 0;
-
- /* If this is the PLL base clock, wrong function to call */
- if (clk->pll_data)
- return -EINVAL;
-
- /* There must be a parent... */
- if (WARN_ON(!clk->parent))
- return -EINVAL;
-
- /* ... the parent must be a PLL... */
- if (WARN_ON(!clk->parent->pll_data))
- return -EINVAL;
-
- /* ... and this clock must have a divider. */
- if (WARN_ON(!clk->div_reg))
- return -EINVAL;
-
- pll = clk->parent->pll_data;
-
- input = clk->parent->rate;
-
- /* If pre-PLL, source clock is before the multiplier and divider(s) */
- if (clk->flags & PRE_PLL)
- input = pll->input_rate;
-
- if (input > rate) {
- /*
- * Can afford to provide an output little higher than requested
- * only if maximum rate supported by hardware on this sysclk
- * is known.
- */
- if (clk->maxrate) {
- ratio = DIV_ROUND_CLOSEST(input, rate);
- if (input / ratio > clk->maxrate)
- ratio = 0;
- }
-
- if (ratio == 0)
- ratio = DIV_ROUND_UP(input, rate);
-
- ratio--;
- }
-
- if (ratio > pll->div_ratio_mask)
- return -EINVAL;
-
- do {
- v = __raw_readl(pll->base + PLLSTAT);
- } while (v & PLLSTAT_GOSTAT);
-
- v = __raw_readl(pll->base + clk->div_reg);
- v &= ~pll->div_ratio_mask;
- v |= ratio | PLLDIV_EN;
- __raw_writel(v, pll->base + clk->div_reg);
-
- v = __raw_readl(pll->base + PLLCMD);
- v |= PLLCMD_GOSET;
- __raw_writel(v, pll->base + PLLCMD);
-
- do {
- v = __raw_readl(pll->base + PLLSTAT);
- } while (v & PLLSTAT_GOSTAT);
-
- return 0;
-}
-EXPORT_SYMBOL(davinci_set_sysclk_rate);
-
-static unsigned long clk_leafclk_recalc(struct clk *clk)
-{
- if (WARN_ON(!clk->parent))
- return clk->rate;
-
- return clk->parent->rate;
-}
-
-int davinci_simple_set_rate(struct clk *clk, unsigned long rate)
-{
- clk->rate = rate;
- return 0;
-}
-
-static unsigned long clk_pllclk_recalc(struct clk *clk)
-{
- u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
- u8 bypass;
- struct pll_data *pll = clk->pll_data;
- unsigned long rate = clk->rate;
-
- ctrl = __raw_readl(pll->base + PLLCTL);
- rate = pll->input_rate = clk->parent->rate;
-
- if (ctrl & PLLCTL_PLLEN) {
- bypass = 0;
- mult = __raw_readl(pll->base + PLLM);
- if (cpu_is_davinci_dm365())
- mult = 2 * (mult & PLLM_PLLM_MASK);
- else
- mult = (mult & PLLM_PLLM_MASK) + 1;
- } else
- bypass = 1;
-
- if (pll->flags & PLL_HAS_PREDIV) {
- prediv = __raw_readl(pll->base + PREDIV);
- if (prediv & PLLDIV_EN)
- prediv = (prediv & pll->div_ratio_mask) + 1;
- else
- prediv = 1;
- }
-
- /* pre-divider is fixed, but (some?) chips won't report that */
- if (cpu_is_davinci_dm355() && pll->num == 1)
- prediv = 8;
-
- if (pll->flags & PLL_HAS_POSTDIV) {
- postdiv = __raw_readl(pll->base + POSTDIV);
- if (postdiv & PLLDIV_EN)
- postdiv = (postdiv & pll->div_ratio_mask) + 1;
- else
- postdiv = 1;
- }
-
- if (!bypass) {
- rate /= prediv;
- rate *= mult;
- rate /= postdiv;
- }
-
- pr_debug("PLL%d: input = %lu MHz [ ",
- pll->num, clk->parent->rate / 1000000);
- if (bypass)
- pr_debug("bypass ");
- if (prediv > 1)
- pr_debug("/ %d ", prediv);
- if (mult > 1)
- pr_debug("* %d ", mult);
- if (postdiv > 1)
- pr_debug("/ %d ", postdiv);
- pr_debug("] --> %lu MHz output.\n", rate / 1000000);
-
- return rate;
-}
-
-/**
- * davinci_set_pllrate - 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.
- */
-int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
- unsigned int mult, unsigned int postdiv)
-{
- u32 ctrl;
- unsigned int locktime;
- unsigned long flags;
-
- if (pll->base == NULL)
- return -EINVAL;
-
- /*
- * 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) | PLLDIV_EN;
- } else {
- locktime = PLL_LOCK_TIME;
- }
- if (postdiv)
- postdiv = (postdiv - 1) | PLLDIV_EN;
- if (mult)
- mult = mult - 1;
-
- /* Protect against simultaneous calls to PLL setting seqeunce */
- spin_lock_irqsave(&clockfw_lock, flags);
-
- ctrl = __raw_readl(pll->base + PLLCTL);
-
- /* Switch the PLL to bypass mode */
- ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
- __raw_writel(ctrl, pll->base + PLLCTL);
-
- udelay(PLL_BYPASS_TIME);
-
- /* Reset and enable PLL */
- ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
- __raw_writel(ctrl, pll->base + PLLCTL);
-
- if (pll->flags & PLL_HAS_PREDIV)
- __raw_writel(prediv, pll->base + PREDIV);
-
- __raw_writel(mult, pll->base + PLLM);
-
- if (pll->flags & PLL_HAS_POSTDIV)
- __raw_writel(postdiv, pll->base + POSTDIV);
-
- udelay(PLL_RESET_TIME);
-
- /* Bring PLL out of reset */
- ctrl |= PLLCTL_PLLRST;
- __raw_writel(ctrl, pll->base + PLLCTL);
-
- udelay(locktime);
-
- /* Remove PLL from bypass mode */
- ctrl |= PLLCTL_PLLEN;
- __raw_writel(ctrl, pll->base + PLLCTL);
-
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(davinci_set_pllrate);
-
-/**
- * davinci_set_refclk_rate() - Set the reference clock rate
- * @rate: The new rate.
- *
- * Sets the reference clock rate to a given value. This will most likely
- * result in the entire clock tree getting updated.
- *
- * This is used to support boards which use a reference clock different
- * than that used by default in <soc>.c file. The reference clock rate
- * should be updated early in the boot process; ideally soon after the
- * clock tree has been initialized once with the default reference clock
- * rate (davinci_clk_init()).
- *
- * Returns 0 on success, error otherwise.
- */
-int davinci_set_refclk_rate(unsigned long rate)
-{
- struct clk *refclk;
-
- refclk = clk_get(NULL, "ref");
- if (IS_ERR(refclk)) {
- pr_err("%s: failed to get reference clock\n", __func__);
- return PTR_ERR(refclk);
- }
-
- clk_set_rate(refclk, rate);
-
- clk_put(refclk);
-
- return 0;
-}
-
-int __init davinci_clk_init(struct clk_lookup *clocks)
-{
- struct clk_lookup *c;
- struct clk *clk;
- size_t num_clocks = 0;
-
- for (c = clocks; c->clk; c++) {
- clk = c->clk;
-
- if (!clk->recalc) {
-
- /* Check if clock is a PLL */
- if (clk->pll_data)
- clk->recalc = clk_pllclk_recalc;
-
- /* Else, if it is a PLL-derived clock */
- else if (clk->flags & CLK_PLL)
- clk->recalc = clk_sysclk_recalc;
-
- /* Otherwise, it is a leaf clock (PSC clock) */
- else if (clk->parent)
- clk->recalc = clk_leafclk_recalc;
- }
-
- if (clk->pll_data) {
- struct pll_data *pll = clk->pll_data;
-
- if (!pll->div_ratio_mask)
- pll->div_ratio_mask = PLLDIV_RATIO_MASK;
-
- if (pll->phys_base && !pll->base) {
- pll->base = ioremap(pll->phys_base, SZ_4K);
- WARN_ON(!pll->base);
- }
- }
-
- if (clk->recalc)
- clk->rate = clk->recalc(clk);
-
- if (clk->lpsc)
- clk->flags |= CLK_PSC;
-
- if (clk->flags & PSC_LRST)
- clk->reset = davinci_clk_reset;
-
- clk_register(clk);
- num_clocks++;
-
- /* Turn on clocks that Linux doesn't otherwise manage */
- if (clk->flags & ALWAYS_ENABLED)
- clk_enable(clk);
- }
-
- clkdev_add_table(clocks, num_clocks);
-
- return 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-#define CLKNAME_MAX 10 /* longest clock name */
-#define NEST_DELTA 2
-#define NEST_MAX 4
-
-static void
-dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
-{
- char *state;
- char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
- struct clk *clk;
- unsigned i;
-
- if (parent->flags & CLK_PLL)
- state = "pll";
- else if (parent->flags & CLK_PSC)
- state = "psc";
- else
- state = "";
-
- /* <nest spaces> name <pad to end> */
- memset(buf, ' ', sizeof(buf) - 1);
- buf[sizeof(buf) - 1] = 0;
- i = strlen(parent->name);
- memcpy(buf + nest, parent->name,
- min(i, (unsigned)(sizeof(buf) - 1 - nest)));
-
- seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
- buf, parent->usecount, state, clk_get_rate(parent));
- /* REVISIT show device associations too */
-
- /* cost is now small, but not linear... */
- list_for_each_entry(clk, &parent->children, childnode) {
- dump_clock(s, nest + NEST_DELTA, clk);
- }
-}
-
-static int davinci_ck_show(struct seq_file *m, void *v)
-{
- struct clk *clk;
-
- /*
- * Show clock tree; We trust nonzero usecounts equate to PSC enables...
- */
- mutex_lock(&clocks_mutex);
- list_for_each_entry(clk, &clocks, node)
- if (!clk->parent)
- dump_clock(m, 0, clk);
- mutex_unlock(&clocks_mutex);
-
- return 0;
-}
-
-static int davinci_ck_open(struct inode *inode, struct file *file)
-{
- return single_open(file, davinci_ck_show, NULL);
-}
-
-static const struct file_operations davinci_ck_operations = {
- .open = davinci_ck_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int __init davinci_clk_debugfs_init(void)
-{
- debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL,
- &davinci_ck_operations);
- return 0;
-
-}
-device_initcall(davinci_clk_debugfs_init);
-#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index 2d05856..3073834 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -61,76 +61,4 @@
*/
#define PLL_LOCK_TIME 20
-#ifndef __ASSEMBLER__
-
-#include <linux/list.h>
-#include <linux/clkdev.h>
-
-#define PLLSTAT_GOSTAT BIT(0)
-#define PLLCMD_GOSET BIT(0)
-
-struct pll_data {
- u32 phys_base;
- void __iomem *base;
- u32 num;
- u32 flags;
- u32 input_rate;
- u32 div_ratio_mask;
-};
-#define PLL_HAS_PREDIV 0x01
-#define PLL_HAS_POSTDIV 0x02
-
-struct clk {
- struct list_head node;
- struct module *owner;
- const char *name;
- unsigned long rate;
- unsigned long maxrate; /* H/W supported max rate */
- u8 usecount;
- u8 lpsc;
- u8 gpsc;
- u8 domain;
- u32 flags;
- struct clk *parent;
- struct list_head children; /* list of children */
- struct list_head childnode; /* parent's child list node */
- struct pll_data *pll_data;
- u32 div_reg;
- unsigned long (*recalc) (struct clk *);
- int (*set_rate) (struct clk *clk, unsigned long rate);
- int (*round_rate) (struct clk *clk, unsigned long rate);
- int (*reset) (struct clk *clk, bool reset);
- void (*clk_enable) (struct clk *clk);
- void (*clk_disable) (struct clk *clk);
- int (*set_parent) (struct clk *clk, struct clk *parent);
-};
-
-/* Clock flags: SoC-specific flags start at BIT(16) */
-#define ALWAYS_ENABLED BIT(1)
-#define CLK_PSC BIT(2)
-#define CLK_PLL BIT(3) /* PLL-derived clock */
-#define PRE_PLL BIT(4) /* source is before PLL mult/div */
-#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */
-#define PSC_FORCE BIT(6) /* Force module state transtition */
-#define PSC_LRST BIT(8) /* Use local reset on enable/disable */
-
-#define CLK(dev, con, ck) \
- { \
- .dev_id = dev, \
- .con_id = con, \
- .clk = ck, \
- } \
-
-int davinci_clk_init(struct clk_lookup *clocks);
-int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
- unsigned int mult, unsigned int postdiv);
-int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
-int davinci_set_refclk_rate(unsigned long rate);
-int davinci_simple_set_rate(struct clk *clk, unsigned long rate);
-int davinci_clk_reset(struct clk *clk, bool reset);
-void davinci_clk_enable(struct clk *clk);
-void davinci_clk_disable(struct clk *clk);
-
-#endif
-
#endif
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index e03f95c..e1d0f0d 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -20,8 +20,6 @@
#include <mach/common.h>
#include <mach/cputype.h>
-#include "clock.h"
-
struct davinci_soc_info davinci_soc_info;
EXPORT_SYMBOL(davinci_soc_info);
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 0edda40..e8dbbb7 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -26,7 +26,6 @@
#include "davinci.h"
-#include "clock.h"
#define DAVINCI_I2C_BASE 0x01C21000
#define DAVINCI_ATA_BASE 0x01C66000
diff --git a/arch/arm/mach-davinci/include/mach/clock.h b/arch/arm/mach-davinci/include/mach/clock.h
index 3e8af6a..42ed4f2 100644
--- a/arch/arm/mach-davinci/include/mach/clock.h
+++ b/arch/arm/mach-davinci/include/mach/clock.h
@@ -15,9 +15,6 @@
struct clk;
-extern int clk_register(struct clk *clk);
-extern void clk_unregister(struct clk *clk);
-
int davinci_clk_reset_assert(struct clk *c);
int davinci_clk_reset_deassert(struct clk *c);
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index c86a058..fb1e88f 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -53,8 +53,6 @@ struct davinci_soc_info {
u32 jtag_id_reg;
struct davinci_id *ids;
unsigned long ids_num;
- u32 *psc_bases;
- unsigned long psc_bases_num;
u32 pinmux_base;
const struct mux_config *pinmux_pins;
unsigned long pinmux_pins_num;
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
deleted file mode 100644
index e5dc6bf..0000000
--- a/arch/arm/mach-davinci/psc.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * TI DaVinci Power and Sleep Controller (PSC)
- *
- * Copyright (C) 2006 Texas Instruments.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <mach/cputype.h>
-#include "psc.h"
-
-#include "clock.h"
-
-/* Return nonzero iff the domain's clock is active */
-int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
-{
- void __iomem *psc_base;
- u32 mdstat;
- struct davinci_soc_info *soc_info = &davinci_soc_info;
-
- if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
- pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
- (int)soc_info->psc_bases, ctlr);
- return 0;
- }
-
- psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
- mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
- iounmap(psc_base);
-
- /* if clocked, state can be "Enable" or "SyncReset" */
- return mdstat & BIT(12);
-}
-
-/* Control "reset" line associated with PSC domain */
-void davinci_psc_reset(unsigned int ctlr, unsigned int id, bool reset)
-{
- u32 mdctl;
- void __iomem *psc_base;
- struct davinci_soc_info *soc_info = &davinci_soc_info;
-
- if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
- pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
- (int)soc_info->psc_bases, ctlr);
- return;
- }
-
- psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
-
- mdctl = readl(psc_base + MDCTL + 4 * id);
- if (reset)
- mdctl &= ~MDCTL_LRST;
- else
- mdctl |= MDCTL_LRST;
- writel(mdctl, psc_base + MDCTL + 4 * id);
-
- iounmap(psc_base);
-}
-
-/* Enable or disable a PSC domain */
-void davinci_psc_config(unsigned int domain, unsigned int ctlr,
- unsigned int id, bool enable, u32 flags)
-{
- u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl;
- void __iomem *psc_base;
- struct davinci_soc_info *soc_info = &davinci_soc_info;
- u32 next_state = PSC_STATE_ENABLE;
-
- if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
- pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
- (int)soc_info->psc_bases, ctlr);
- return;
- }
-
- psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
-
- if (!enable) {
- if (flags & PSC_SWRSTDISABLE)
- next_state = PSC_STATE_SWRSTDISABLE;
- else
- next_state = PSC_STATE_DISABLE;
- }
-
- mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
- mdctl &= ~MDSTAT_STATE_MASK;
- mdctl |= next_state;
- if (flags & PSC_FORCE)
- mdctl |= MDCTL_FORCE;
- __raw_writel(mdctl, psc_base + MDCTL + 4 * id);
-
- pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain);
- if ((pdstat & PDSTAT_STATE_MASK) == 0) {
- pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
- pdctl |= PDCTL_NEXT;
- __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
-
- ptcmd = 1 << domain;
- __raw_writel(ptcmd, psc_base + PTCMD);
-
- do {
- epcpr = __raw_readl(psc_base + EPCPR);
- } while ((((epcpr >> domain) & 1) == 0));
-
- pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
- pdctl |= PDCTL_EPCGOOD;
- __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
- } else {
- ptcmd = 1 << domain;
- __raw_writel(ptcmd, psc_base + PTCMD);
- }
-
- do {
- ptstat = __raw_readl(psc_base + PTSTAT);
- } while (!(((ptstat >> domain) & 1) == 0));
-
- do {
- mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
- } while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
-
- iounmap(psc_base);
-}
diff --git a/arch/arm/mach-davinci/psc.h b/arch/arm/mach-davinci/psc.h
index b58707c..68cd9d3 100644
--- a/arch/arm/mach-davinci/psc.h
+++ b/arch/arm/mach-davinci/psc.h
@@ -204,14 +204,4 @@
#define PDCTL_NEXT BIT(0)
#define PDCTL_EPCGOOD BIT(8)
-#ifndef __ASSEMBLER__
-
-extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
-extern void davinci_psc_reset(unsigned int ctlr, unsigned int id,
- bool reset);
-extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
- unsigned int id, bool enable, u32 flags);
-
-#endif
-
#endif /* __ASM_ARCH_PSC_H */
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 1bb991a..bd0c80e 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -27,8 +27,6 @@
#include <mach/hardware.h>
#include <mach/time.h>
-#include "clock.h"
-
static struct clock_event_device clockevent_davinci;
static unsigned int davinci_clock_tick_rate;
--
2.7.4
This removes the unused legacy clock init code from
arch/arm/mach-davinci/dm644x.c.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- none
arch/arm/mach-davinci/dm644x.c | 300 +----------------------------------------
1 file changed, 1 insertion(+), 299 deletions(-)
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 5b5de85..cf9cd69 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -32,11 +32,6 @@
#include "davinci.h"
#include "mux.h"
-#ifndef CONFIG_COMMON_CLK
-#include "clock.h"
-#include "psc.h"
-#endif
-
/*
* Device specific clocks
*/
@@ -49,292 +44,6 @@
#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,
-};
-
-static struct pll_data pll2_data = {
- .num = 2,
- .phys_base = DAVINCI_PLL2_BASE,
-};
-
-static struct clk ref_clk = {
- .name = "ref_clk",
- .rate = DM644X_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
- .name = "pll1",
- .parent = &ref_clk,
- .pll_data = &pll1_data,
- .flags = CLK_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
- .name = "pll1_sysclk1",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-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 struct clk pll1_sysclk5 = {
- .name = "pll1_sysclk5",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_aux_clk = {
- .name = "pll1_aux_clk",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclkbp = {
- .name = "pll1_sysclkbp",
- .parent = &pll1_clk,
- .flags = CLK_PLL | PRE_PLL,
- .div_reg = BPDIV
-};
-
-static struct clk pll2_clk = {
- .name = "pll2",
- .parent = &ref_clk,
- .pll_data = &pll2_data,
- .flags = CLK_PLL,
-};
-
-static struct clk pll2_sysclk1 = {
- .name = "pll2_sysclk1",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV1,
-};
-
-static struct clk pll2_sysclk2 = {
- .name = "pll2_sysclk2",
- .parent = &pll2_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV2,
-};
-
-static struct clk pll2_sysclkbp = {
- .name = "pll2_sysclkbp",
- .parent = &pll2_clk,
- .flags = CLK_PLL | PRE_PLL,
- .div_reg = BPDIV
-};
-
-static struct clk dsp_clk = {
- .name = "dsp",
- .parent = &pll1_sysclk1,
- .lpsc = DAVINCI_LPSC_GEM,
- .domain = DAVINCI_GPSC_DSPDOMAIN,
- .usecount = 1, /* REVISIT how to disable? */
-};
-
-static struct clk arm_clk = {
- .name = "arm",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_ARM,
- .flags = ALWAYS_ENABLED,
-};
-
-static struct clk vicp_clk = {
- .name = "vicp",
- .parent = &pll1_sysclk2,
- .lpsc = DAVINCI_LPSC_IMCOP,
- .domain = DAVINCI_GPSC_DSPDOMAIN,
- .usecount = 1, /* REVISIT how to disable? */
-};
-
-static struct clk vpss_master_clk = {
- .name = "vpss_master",
- .parent = &pll1_sysclk3,
- .lpsc = DAVINCI_LPSC_VPSSMSTR,
- .flags = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
- .name = "vpss_slave",
- .parent = &pll1_sysclk3,
- .lpsc = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk uart0_clk = {
- .name = "uart0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
- .name = "uart1",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_UART1,
-};
-
-static struct clk uart2_clk = {
- .name = "uart2",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_UART2,
-};
-
-static struct clk emac_clk = {
- .name = "emac",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
-};
-
-static struct clk i2c_clk = {
- .name = "i2c",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_I2C,
-};
-
-static struct clk ide_clk = {
- .name = "ide",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_ATA,
-};
-
-static struct clk asp_clk = {
- .name = "asp0",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_McBSP,
-};
-
-static struct clk mmcsd_clk = {
- .name = "mmcsd",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk spi_clk = {
- .name = "spi",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_SPI,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk usb_clk = {
- .name = "usb",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_USB,
-};
-
-static struct clk vlynq_clk = {
- .name = "vlynq",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_VLYNQ,
-};
-
-static struct clk aemif_clk = {
- .name = "aemif",
- .parent = &pll1_sysclk5,
- .lpsc = DAVINCI_LPSC_AEMIF,
-};
-
-static struct clk pwm0_clk = {
- .name = "pwm0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM0,
-};
-
-static struct clk pwm1_clk = {
- .name = "pwm1",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM1,
-};
-
-static struct clk pwm2_clk = {
- .name = "pwm2",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_PWM2,
-};
-
-static struct clk timer0_clk = {
- .name = "timer0",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
- .name = "timer1",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
- .name = "timer2",
- .parent = &pll1_aux_clk,
- .lpsc = DAVINCI_LPSC_TIMER2,
- .usecount = 1, /* REVISIT: why can't this be disabled? */
-};
-
-static struct clk_lookup dm644x_clks[] = {
- CLK(NULL, "ref", &ref_clk),
- CLK(NULL, "pll1", &pll1_clk),
- CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
- CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
- CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
- CLK(NULL, "pll1_aux", &pll1_aux_clk),
- CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
- CLK(NULL, "pll2", &pll2_clk),
- CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
- CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
- CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
- CLK(NULL, "dsp", &dsp_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK(NULL, "vicp", &vicp_clk),
- CLK("vpss", "master", &vpss_master_clk),
- CLK("vpss", "slave", &vpss_slave_clk),
- CLK(NULL, "arm", &arm_clk),
- CLK("serial8250.0", NULL, &uart0_clk),
- CLK("serial8250.1", NULL, &uart1_clk),
- CLK("serial8250.2", NULL, &uart2_clk),
- CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
- CLK("i2c_davinci.1", NULL, &i2c_clk),
- CLK("palm_bk3710", NULL, &ide_clk),
- CLK("davinci-mcbsp", NULL, &asp_clk),
- CLK("dm6441-mmc.0", NULL, &mmcsd_clk),
- CLK(NULL, "spi", &spi_clk),
- CLK(NULL, "gpio", &gpio_clk),
- CLK(NULL, "usb", &usb_clk),
- CLK(NULL, "vlynq", &vlynq_clk),
- CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "pwm0", &pwm0_clk),
- CLK(NULL, "pwm1", &pwm1_clk),
- CLK(NULL, "pwm2", &pwm2_clk),
- CLK(NULL, "timer0", &timer0_clk),
- CLK(NULL, "timer1", &timer1_clk),
- 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,
.ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET,
@@ -827,8 +536,6 @@ static struct davinci_id dm644x_ids[] = {
},
};
-static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
/*
* T0_BOT: Timer 0, bottom: clockevent source for hrtimers
* T0_TOP: Timer 0, top : clocksource for generic timekeeping
@@ -913,8 +620,6 @@ static const struct davinci_soc_info davinci_soc_info_dm644x = {
.jtag_id_reg = 0x01c40028,
.ids = dm644x_ids,
.ids_num = ARRAY_SIZE(dm644x_ids),
- .psc_bases = dm644x_psc_bases,
- .psc_bases_num = ARRAY_SIZE(dm644x_psc_bases),
.pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
.pinmux_pins = dm644x_pins,
.pinmux_pins_num = ARRAY_SIZE(dm644x_pins),
@@ -942,7 +647,6 @@ 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);
@@ -954,9 +658,7 @@ void __init dm644x_init_time(void)
dm644x_pll_clk_init(pll1, pll2);
dm644x_psc_clk_init(psc);
-#else
- davinci_clk_init(dm644x_clks);
-#endif
+
davinci_timer_init();
}
--
2.7.4
This removes all of the clock init code from da8xx-dt.c. This includes
all of the OF_DEV_AUXDATA that was just used for looking up clocks.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- removed misleading statement from commit message
arch/arm/mach-davinci/da8xx-dt.c | 61 +---------------------------------------
1 file changed, 1 insertion(+), 60 deletions(-)
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index ab199f4..d5c6cdb 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -19,69 +19,11 @@
#include "cp_intc.h"
#include <mach/da8xx.h>
-static struct of_dev_auxdata da850_aemif_auxdata_lookup[] = {
- OF_DEV_AUXDATA("ti,davinci-nand", 0x62000000, "davinci-nand.0", NULL),
- {}
-};
-
-static struct aemif_platform_data aemif_data = {
- .dev_lookup = da850_aemif_auxdata_lookup,
-};
-
-static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
- OF_DEV_AUXDATA("ti,davinci-i2c", 0x01c22000, "i2c_davinci.1", NULL),
- OF_DEV_AUXDATA("ti,davinci-i2c", 0x01e28000, "i2c_davinci.2", NULL),
- OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "davinci-wdt", NULL),
- OF_DEV_AUXDATA("ti,da830-mmc", 0x01c40000, "da830-mmc.0", NULL),
- OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm.0", NULL),
- OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm.1", NULL),
- OF_DEV_AUXDATA("ti,da850-ecap", 0x01f06000, "ecap.0", NULL),
- OF_DEV_AUXDATA("ti,da850-ecap", 0x01f07000, "ecap.1", NULL),
- OF_DEV_AUXDATA("ti,da850-ecap", 0x01f08000, "ecap.2", NULL),
- OF_DEV_AUXDATA("ti,da830-spi", 0x01c41000, "spi_davinci.0", NULL),
- OF_DEV_AUXDATA("ti,da830-spi", 0x01f0e000, "spi_davinci.1", NULL),
- OF_DEV_AUXDATA("ns16550a", 0x01c42000, "serial8250.0", NULL),
- OF_DEV_AUXDATA("ns16550a", 0x01d0c000, "serial8250.1", NULL),
- OF_DEV_AUXDATA("ns16550a", 0x01d0d000, "serial8250.2", NULL),
- OF_DEV_AUXDATA("ti,davinci_mdio", 0x01e24000, "davinci_mdio.0", NULL),
- OF_DEV_AUXDATA("ti,davinci-dm6467-emac", 0x01e20000, "davinci_emac.1",
- NULL),
- OF_DEV_AUXDATA("ti,da830-mcasp-audio", 0x01d00000, "davinci-mcasp.0", NULL),
- OF_DEV_AUXDATA("ti,da850-aemif", 0x68000000, "ti-aemif", &aemif_data),
- OF_DEV_AUXDATA("ti,da850-tilcdc", 0x01e13000, "da8xx_lcdc.0", NULL),
- OF_DEV_AUXDATA("ti,da830-ohci", 0x01e25000, "ohci-da8xx", NULL),
- OF_DEV_AUXDATA("ti,da830-musb", 0x01e00000, "musb-da8xx", NULL),
- OF_DEV_AUXDATA("ti,da830-usb-phy", 0x01c1417c, "da8xx-usb-phy", NULL),
- OF_DEV_AUXDATA("ti,da850-ahci", 0x01e18000, "ahci_da850", NULL),
- OF_DEV_AUXDATA("ti,da850-vpif", 0x01e17000, "vpif", NULL),
- OF_DEV_AUXDATA("ti,da850-dsp", 0x11800000, "davinci-rproc.0", NULL),
- {}
-};
-
#ifdef CONFIG_ARCH_DAVINCI_DA850
static void __init da850_init_machine(void)
{
- /* All existing boards use 100MHz SATA refclkpn */
- static const unsigned long sata_refclkpn = 100 * 1000 * 1000;
-
- int ret;
-
- ret = da8xx_register_usb20_phy_clk(false);
- if (ret)
- pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
- __func__, ret);
- ret = da8xx_register_usb11_phy_clk(false);
- if (ret)
- pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
- __func__, ret);
-
- ret = da850_register_sata_refclk(sata_refclkpn);
- if (ret)
- pr_warn("%s: registering SATA REFCLK failed: %d",
- __func__, ret);
-
- of_platform_default_populate(NULL, da850_auxdata_lookup, NULL);
+ of_platform_default_populate(NULL, NULL, NULL);
davinci_pm_init();
pdata_quirks_init();
}
@@ -96,7 +38,6 @@ static const char *const da850_boards_compat[] __initconst = {
DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
.map_io = da850_init,
- .init_time = da850_init_time,
.init_machine = da850_init_machine,
.dt_compat = da850_boards_compat,
.init_late = davinci_init_late,
--
2.7.4
This adds clock provider nodes for da850 and wires them up to all of the
devices.
Signed-off-by: David Lechner <[email protected]>
---
v6 changes:
- updated for device tree bindings changes earlier in this series
- use single async2 clock instead of duplicate fixed factor clocks
- add clock-names property to mdio node
arch/arm/boot/dts/da850.dtsi | 162 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 162 insertions(+)
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index c66cf78..7f4acd7 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -21,6 +21,36 @@
#interrupt-cells = <1>;
ti,intc-size = <101>;
reg = <0xfffee000 0x2000>;
+ clocks = <&psc0 6>;
+ };
+ };
+ clocks: clocks {
+ ref_clk: ref_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "ref_clk";
+ };
+ sata_refclk: sata_refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ clock-output-names = "sata_refclk";
+ status = "disabled";
+ };
+ usb_refclkin: usb_refclkin {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <48000000>;
+ clock-output-names = "usb_refclkin";
+ status = "disabled";
+ };
+ async2_clk: async2 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&pll0_auxclk>;
};
};
dsp: dsp@11800000 {
@@ -33,6 +63,7 @@
reg-names = "l2sram", "l1pram", "l1dram", "host1cfg", "chipsig";
interrupt-parent = <&intc>;
interrupts = <28>;
+ clocks = <&psc0 15>;
status = "disabled";
};
soc@1c00000 {
@@ -43,6 +74,36 @@
ranges = <0x0 0x01c00000 0x400000>;
interrupt-parent = <&intc>;
+ psc0: clock-controller@10000 {
+ compatible = "ti,da850-psc0";
+ reg = <0x10000 0x1000>;
+ #clock-cells = <1>;
+ clocks = <&pll0_sysclk 1>, <&pll0_sysclk 2>,
+ <&pll0_sysclk 4>, <&pll0_sysclk 6>,
+ <&async1_clk>;
+ clock_names = "pll0_sysclk1", "pll0_sysclk2",
+ "pll0_sysclk4", "pll0_sysclk6",
+ "async1";
+ };
+ pll0: clock-controller@11000 {
+ compatible = "ti,da850-pll0";
+ reg = <0x11000 0x1000>;
+ clocks = <&ref_clk>, <&pll1_sysclk 3>;
+ clock-names = "clksrc", "extclksrc";
+
+ pll0_pllout: pllout {
+ #clock-cells = <0>;
+ };
+ pll0_sysclk: sysclk {
+ #clock-cells = <1>;
+ };
+ pll0_auxclk: auxclk {
+ #clock-cells = <0>;
+ };
+ pll0_obsclk: obsclk {
+ #clock-cells = <0>;
+ };
+ };
pmx_core: pinmux@14120 {
compatible = "pinctrl-single";
reg = <0x14120 0x50>;
@@ -264,8 +325,43 @@
usb_phy: usb-phy {
compatible = "ti,da830-usb-phy";
#phy-cells = <1>;
+ clocks = <&usb_phy_clk 0>, <&usb_phy_clk 1>;
+ clock-names = "usb20_phy", "usb11_phy";
status = "disabled";
};
+ usb_phy_clk: usb-phy-clocks {
+ compatible = "ti,da830-usb-phy-clocks";
+ #clock-cells = <1>;
+ clocks = <&psc1 1>, <&usb_refclkin>,
+ <&pll0_auxclk>;
+ clock-names = "fck", "usb_refclkin", "auxclk";
+ };
+ ehrpwm_tbclk: ehrpwm_tbclk {
+ compatible = "ti,da830-tbclksync";
+ #clock-cells = <0>;
+ clocks = <&psc1 17>;
+ clock-names = "fck";
+ };
+ div4p5_clk: div4.5 {
+ compatible = "ti,da830-div4p5ena";
+ #clock-cells = <0>;
+ clocks = <&pll0_pllout>;
+ clock-names = "pll0_pllout";
+ };
+ async1_clk: async1 {
+ compatible = "ti,da850-async1-clksrc";
+ #clock-cells = <0>;
+ clocks = <&pll0_sysclk 3>, <&div4p5_clk>;
+ clock-names = "pll0_sysclk3", "div4.5";
+ };
+ async3_clk: async3 {
+ compatible = "ti,da850-async3-clksrc";
+ #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>;
+ };
};
edma0: edma@0 {
compatible = "ti,edma3-tpcc";
@@ -277,18 +373,21 @@
#dma-cells = <2>;
ti,tptcs = <&edma0_tptc0 7>, <&edma0_tptc1 0>;
+ clocks = <&psc0 0>;
};
edma0_tptc0: tptc@8000 {
compatible = "ti,edma3-tptc";
reg = <0x8000 0x400>;
interrupts = <13>;
interrupt-names = "edm3_tcerrint";
+ clocks = <&psc0 1>;
};
edma0_tptc1: tptc@8400 {
compatible = "ti,edma3-tptc";
reg = <0x8400 0x400>;
interrupts = <32>;
interrupt-names = "edm3_tcerrint";
+ clocks = <&psc0 2>;
};
edma1: edma@230000 {
compatible = "ti,edma3-tpcc";
@@ -300,12 +399,14 @@
#dma-cells = <2>;
ti,tptcs = <&edma1_tptc0 7>;
+ clocks = <&psc1 0>;
};
edma1_tptc0: tptc@238000 {
compatible = "ti,edma3-tptc";
reg = <0x238000 0x400>;
interrupts = <95>;
interrupt-names = "edm3_tcerrint";
+ clocks = <&psc1 21>;
};
serial0: serial@42000 {
compatible = "ti,da830-uart", "ns16550a";
@@ -313,6 +414,7 @@
reg-io-width = <4>;
reg-shift = <2>;
interrupts = <25>;
+ clocks = <&psc0 9>;
status = "disabled";
};
serial1: serial@10c000 {
@@ -321,6 +423,7 @@
reg-io-width = <4>;
reg-shift = <2>;
interrupts = <53>;
+ clocks = <&psc1 12>;
status = "disabled";
};
serial2: serial@10d000 {
@@ -329,6 +432,7 @@
reg-io-width = <4>;
reg-shift = <2>;
interrupts = <61>;
+ clocks = <&psc1 13>;
status = "disabled";
};
rtc0: rtc@23000 {
@@ -344,6 +448,7 @@
interrupts = <15>;
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&async2_clk>;
status = "disabled";
};
i2c1: i2c@228000 {
@@ -352,11 +457,18 @@
interrupts = <51>;
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&psc1 11>;
status = "disabled";
};
+ clocksource: timer@20000 {
+ compatible = "ti,davinci-timer";
+ reg = <0x20000 0x1000>;
+ clocks = <&async2_clk>;
+ };
wdt: wdt@21000 {
compatible = "ti,davinci-wdt";
reg = <0x21000 0x1000>;
+ clocks = <&async2_clk>;
status = "disabled";
};
mmc0: mmc@40000 {
@@ -367,12 +479,14 @@
interrupts = <16>;
dmas = <&edma0 16 0>, <&edma0 17 0>;
dma-names = "rx", "tx";
+ clocks = <&psc0 5>;
status = "disabled";
};
vpif: video@217000 {
compatible = "ti,da850-vpif";
reg = <0x217000 0x1000>;
interrupts = <92>;
+ clocks = <&psc1 9>;
status = "disabled";
/* VPIF capture port */
@@ -395,6 +509,7 @@
interrupts = <72>;
dmas = <&edma1 28 0>, <&edma1 29 0>;
dma-names = "rx", "tx";
+ clocks = <&psc1 18>;
status = "disabled";
};
ehrpwm0: pwm@300000 {
@@ -402,6 +517,8 @@
"ti,am33xx-ehrpwm";
#pwm-cells = <3>;
reg = <0x300000 0x2000>;
+ clocks = <&psc1 17>, <&ehrpwm_tbclk>;
+ clock-names = "fck", "tbclk";
status = "disabled";
};
ehrpwm1: pwm@302000 {
@@ -409,6 +526,8 @@
"ti,am33xx-ehrpwm";
#pwm-cells = <3>;
reg = <0x302000 0x2000>;
+ clocks = <&psc1 17>, <&ehrpwm_tbclk>;
+ clock-names = "fck", "tbclk";
status = "disabled";
};
ecap0: ecap@306000 {
@@ -416,6 +535,8 @@
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x306000 0x80>;
+ clocks = <&psc1 20>;
+ clock-names = "fck";
status = "disabled";
};
ecap1: ecap@307000 {
@@ -423,6 +544,8 @@
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x307000 0x80>;
+ clocks = <&psc1 20>;
+ clock-names = "fck";
status = "disabled";
};
ecap2: ecap@308000 {
@@ -430,6 +553,8 @@
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x308000 0x80>;
+ clocks = <&psc1 20>;
+ clock-names = "fck";
status = "disabled";
};
spi0: spi@41000 {
@@ -442,6 +567,7 @@
interrupts = <20>;
dmas = <&edma0 14 0>, <&edma0 15 0>;
dma-names = "rx", "tx";
+ clocks = <&psc0 4>;
status = "disabled";
};
spi1: spi@30e000 {
@@ -454,6 +580,7 @@
interrupts = <56>;
dmas = <&edma0 18 0>, <&edma0 19 0>;
dma-names = "rx", "tx";
+ clocks = <&psc1 10>;
status = "disabled";
};
usb0: usb@200000 {
@@ -465,6 +592,7 @@
dr_mode = "otg";
phys = <&usb_phy 0>;
phy-names = "usb-phy";
+ clocks = <&psc1 1>;
status = "disabled";
#address-cells = <1>;
@@ -488,6 +616,7 @@
interrupts = <58>;
#dma-cells = <2>;
#dma-channels = <4>;
+ clocks = <&psc1 1>;
status = "okay";
};
};
@@ -495,13 +624,30 @@
compatible = "ti,da850-ahci";
reg = <0x218000 0x2000>, <0x22c018 0x4>;
interrupts = <67>;
+ clocks = <&psc1 8>, <&sata_refclk>;
+ clock-names = "fck", "refclk";
status = "disabled";
};
+ pll1: clock-controller@21a000 {
+ compatible = "ti,da850-pll1";
+ reg = <0x21a000 0x1000>;
+ clocks = <&ref_clk>;
+ clock-names = "clksrc";
+
+ pll1_sysclk: sysclk {
+ #clock-cells = <1>;
+ };
+ pll1_obsclk: obsclk {
+ #clock-cells = <0>;
+ };
+ };
mdio: mdio@224000 {
compatible = "ti,davinci_mdio";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x224000 0x1000>;
+ clocks = <&psc1 5>;
+ clock-names = "fck";
status = "disabled";
};
eth0: ethernet@220000 {
@@ -517,6 +663,7 @@
35
36
>;
+ clocks = <&psc1 5>;
status = "disabled";
};
usb1: usb@225000 {
@@ -525,6 +672,7 @@
interrupts = <59>;
phys = <&usb_phy 1>;
phy-names = "usb-phy";
+ clocks = <&psc1 2>;
status = "disabled";
};
gpio: gpio@226000 {
@@ -542,6 +690,16 @@
status = "disabled";
interrupt-controller;
#interrupt-cells = <2>;
+ clocks = <&psc1 3>;
+ clock-names = "gpio";
+ };
+ psc1: clock-controller@227000 {
+ compatible = "ti,da850-psc1";
+ reg = <0x227000 0x1000>;
+ #clock-cells = <1>;
+ clocks = <&pll0_sysclk 2>, <&pll0_sysclk 4>,
+ <&async3_clk>;
+ clock_names = "pll0_sysclk2", "pll0_sysclk4", "async3";
};
pinconf: pin-controller@22c00c {
compatible = "ti,da850-pupd";
@@ -560,6 +718,7 @@
dmas = <&edma0 1 1>,
<&edma0 0 1>;
dma-names = "tx", "rx";
+ clocks = <&psc1 7>;
};
lcdc: display@213000 {
@@ -567,6 +726,8 @@
reg = <0x213000 0x1000>;
interrupts = <52>;
max-pixelclock = <37500>;
+ clocks = <&psc1 16>;
+ clock-names = "fck";
status = "disabled";
};
};
@@ -578,6 +739,7 @@
reg = <0x68000000 0x00008000>;
ranges = <0 0 0x60000000 0x08000000
1 0 0x68000000 0x00008000>;
+ clocks = <&psc0 3>;
status = "disabled";
};
memctrl: memory-controller@b0000000 {
--
2.7.4
On Sat, Jan 20, 2018 at 11:13 AM, David Lechner <[email protected]> wrote:
> This series converts mach-davinci to use the common clock framework.
>
> The series works like this, the first 19 patches create new clock drivers
> using the common clock framework. There are basically 3 groups of clocks -
> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each have
> unique init data, which is the reason for so many patches.
>
> Then, starting with "ARM: da830: add new clock init using common clock",
> we get the mach code ready for the switch by adding the code needed for
> the new clock drivers and adding #ifndef CONFIG_COMMON_CLK around the
> legacy clocks so that we can switch easily between the old and the new.
>
> "ARM: davinci: switch to common clock framework" actually flips the switch
> to start using the new clock drivers. Then the next 8 patches remove all
> of the old clock code.
>
> The final three patches add device tree clock support to the one SoC that
> supports it.
>
> v6 changes (also see individual patches for details):
> - All of the device tree bindings are changed
> - All of the clock drivers are changed significantly
> - Fixed issues brought up during review of v5
> - "ARM: davinci: move davinci_clk_init() to init_time" is removed from this
> series and submitted separately
>
> v5 changes:
> - Basically, this is an entirely new series
> - Patches are broken up into bite-sized pieces
> - Converted PSC clock driver to use regmap
> - Restored "force" flag for certain DA850 clocks
> - Added device tree bindings
> - Moved more of the clock init to drivers/clk
> - Fixed frequency scaling (maybe*)
>
> * I have frequency scaling using cpufreq-dt, so I know the clocks are doing
> what they need to do to make this work, but I haven't figured out how to
> test davinci-cpufreq driver yet. (Patches to make cpufreq-dt work will be
> sent separately after this series has landed.)
>
> Dependencies:
>
> This series applies on top of linux-davinci/master plus the following patches:
> - [1] "clk: fix reentrancy of clk_enable() on UP systems" (in clk-next)
> - [2] "clk: add helper functions for managing clk_onecell_data"
> - [3] "clk: divider: read-only divider can propagate rate change"
> - [4],[5],[6],[7],[8],[9] series "ARM: davinci: common clock prep work"
>
> You can find a working branch with everything included in the "common-clk-v6"
> branch of https://github.com/dlech/ev3dev-kernel.git.
>
> [1]: https://patchwork.kernel.org/patch/10145933/
> [2]: https://patchwork.kernel.org/patch/10145873/
> [3]: https://patchwork.kernel.org/patch/10146829/
> [4]: https://patchwork.kernel.org/patch/10176241/
> [5]: https://patchwork.kernel.org/patch/10176249/
> [6]: https://patchwork.kernel.org/patch/10176245/
> [7]: https://patchwork.kernel.org/patch/10176251/
> [8]: https://patchwork.kernel.org/patch/10176243/
> [9]: https://patchwork.kernel.org/patch/10176247/
>
>
> Testing/debugging for the uninitiated:
>
> I only have one device to test with, which is based on da850, so I will
> have to rely on others to do some testing here. Since we are dealing with
> clocks, if something isn't working, you most likely won't see output on
> the serial port. To figure out what is going on, you need to enable...
>
> CONFIG_DEBUG_LL=y
> CONFIG_EARLY_PRINTK=y
>
> and add "earlyprintk clk_ignore_unused" to the kernel command line options.
> You may need to select a different UART for this depending on your board. I
> think UART1 is the default in the kernel configuration.
>
> On da850 devices comment out the lines:
>
> else
> clk_set_parent(clk, parent->clk);
>
> in da850.c or, if using device tree, comment out the lines:
>
> assigned-clocks = <&async3_clk>;
> assigned-clock-parents = <&pll1_sysclk 2>;
>
> in da850.dtsi when doing earlyprintk, otherwise the UART1 and UART2 clock
> source will change during boot and cause garbled output after a point.
>
>
> David Lechner (41):
> dt-bindings: clock: Add new bindings for TI Davinci PLL clocks
> clk: davinci: New driver for davinci PLL clocks
> clk: davinci: Add platform information for TI DA830 PLL
> clk: davinci: Add platform information for TI DA850 PLL
> clk: davinci: Add platform information for TI DM355 PLL
> clk: davinci: Add platform information for TI DM365 PLL
> clk: davinci: Add platform information for TI DM644x PLL
> clk: davinci: Add platform information for TI DM646x PLL
> dt-bindings: clock: New bindings for TI Davinci PSC
> clk: davinci: New driver for davinci PSC clocks
> clk: davinci: Add platform information for TI DA830 PSC
> clk: davinci: Add platform information for TI DA850 PSC
> clk: davinci: Add platform information for TI DM355 PSC
> clk: davinci: Add platform information for TI DM365 PSC
> clk: davinci: Add platform information for TI DM644x PSC
> clk: davinci: Add platform information for TI DM646x PSC
> dt-bindings: clock: Add bindings for DA8XX CFGCHIP clocks
> clk: davinci: New driver for TI DA8XX CFGCHIP clocks
> clk: davinci: New driver for TI DA8XX USB PHY clocks
> ARM: da830: add new clock init using common clock framework
> ARM: da850: add new clock init using common clock framework
> ARM: dm355: add new clock init using common clock framework
> ARM: dm365: add new clock init using common clock framework
> ARM: dm644x: add new clock init using common clock framework
> ARM: dm646x: add new clock init using common clock framework
> ARM: da8xx: add new USB PHY clock init using common clock framework
> ARM: da8xx: add new sata_refclk init using common clock framework
> ARM: davinci: remove CONFIG_DAVINCI_RESET_CLOCKS
> ARM: davinci_all_defconfig: remove CONFIG_DAVINCI_RESET_CLOCKS
> ARM: davinci: switch to common clock framework
> ARM: da830: Remove legacy clock init
> ARM: da850: Remove legacy clock init
> ARM: dm355: Remove legacy clock init
> ARM: dm365: Remove legacy clock init
> ARM: dm644x: Remove legacy clock init
> ARM: dm646x: Remove legacy clock init
> ARM: da8xx: Remove legacy clock init
> ARM: davinci: remove legacy clocks
> ARM: davinci: add device tree support to timer
> ARM: da8xx-dt: switch to device tree clocks
> ARM: dts: da850: Add clocks
>
> .../bindings/clock/ti/davinci/da8xx-cfgchip.txt | 93 +++
> .../devicetree/bindings/clock/ti/davinci/pll.txt | 96 +++
> .../devicetree/bindings/clock/ti/davinci/psc.txt | 66 ++
> MAINTAINERS | 7 +
> arch/arm/Kconfig | 2 +-
> arch/arm/boot/dts/da850.dtsi | 162 ++++
> arch/arm/configs/davinci_all_defconfig | 1 -
> arch/arm/mach-davinci/Kconfig | 13 +-
> arch/arm/mach-davinci/Makefile | 4 +-
> arch/arm/mach-davinci/clock.c | 745 -------------------
> arch/arm/mach-davinci/clock.h | 76 --
> arch/arm/mach-davinci/common.c | 3 -
> arch/arm/mach-davinci/da830.c | 440 +----------
> arch/arm/mach-davinci/da850.c | 685 ++---------------
> arch/arm/mach-davinci/da8xx-dt.c | 61 +-
> arch/arm/mach-davinci/davinci.h | 4 +
> arch/arm/mach-davinci/devices-da8xx.c | 43 +-
> arch/arm/mach-davinci/devices.c | 1 -
> arch/arm/mach-davinci/dm355.c | 386 +---------
> arch/arm/mach-davinci/dm365.c | 472 +-----------
> arch/arm/mach-davinci/dm644x.c | 318 +-------
> arch/arm/mach-davinci/dm646x.c | 353 +--------
> arch/arm/mach-davinci/include/mach/clock.h | 3 -
> arch/arm/mach-davinci/include/mach/common.h | 8 -
> arch/arm/mach-davinci/psc.c | 137 ----
> arch/arm/mach-davinci/psc.h | 12 -
> arch/arm/mach-davinci/time.c | 19 +-
> arch/arm/mach-davinci/usb-da8xx.c | 256 ++-----
> drivers/clk/Makefile | 1 +
> drivers/clk/davinci/Makefile | 22 +
> drivers/clk/davinci/da8xx-cfgchip.c | 305 ++++++++
> drivers/clk/davinci/da8xx-usb-phy-clk.c | 312 ++++++++
> drivers/clk/davinci/pll-da830.c | 51 ++
> drivers/clk/davinci/pll-da850.c | 163 +++++
> drivers/clk/davinci/pll-dm355.c | 66 ++
> drivers/clk/davinci/pll-dm365.c | 110 +++
> drivers/clk/davinci/pll-dm644x.c | 67 ++
> drivers/clk/davinci/pll-dm646x.c | 63 ++
> drivers/clk/davinci/pll.c | 813 +++++++++++++++++++++
> drivers/clk/davinci/pll.h | 118 +++
> drivers/clk/davinci/psc-da830.c | 85 +++
> drivers/clk/davinci/psc-da850.c | 109 +++
> drivers/clk/davinci/psc-dm355.c | 74 ++
> drivers/clk/davinci/psc-dm365.c | 79 ++
> drivers/clk/davinci/psc-dm644x.c | 68 ++
> drivers/clk/davinci/psc-dm646x.c | 62 ++
> drivers/clk/davinci/psc.c | 298 ++++++++
> drivers/clk/davinci/psc.h | 88 +++
> include/linux/clk/davinci.h | 37 +
> 49 files changed, 3683 insertions(+), 3774 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt
> create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
> create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/psc.txt
> delete mode 100644 arch/arm/mach-davinci/clock.c
> delete mode 100644 arch/arm/mach-davinci/psc.c
> create mode 100644 drivers/clk/davinci/Makefile
> create mode 100644 drivers/clk/davinci/da8xx-cfgchip.c
> create mode 100644 drivers/clk/davinci/da8xx-usb-phy-clk.c
> create mode 100644 drivers/clk/davinci/pll-da830.c
> create mode 100644 drivers/clk/davinci/pll-da850.c
> create mode 100644 drivers/clk/davinci/pll-dm355.c
> create mode 100644 drivers/clk/davinci/pll-dm365.c
> create mode 100644 drivers/clk/davinci/pll-dm644x.c
> create mode 100644 drivers/clk/davinci/pll-dm646x.c
> create mode 100644 drivers/clk/davinci/pll.c
> create mode 100644 drivers/clk/davinci/pll.h
> create mode 100644 drivers/clk/davinci/psc-da830.c
> create mode 100644 drivers/clk/davinci/psc-da850.c
> create mode 100644 drivers/clk/davinci/psc-dm355.c
> create mode 100644 drivers/clk/davinci/psc-dm365.c
> create mode 100644 drivers/clk/davinci/psc-dm644x.c
> create mode 100644 drivers/clk/davinci/psc-dm646x.c
> create mode 100644 drivers/clk/davinci/psc.c
> create mode 100644 drivers/clk/davinci/psc.h
> create mode 100644 include/linux/clk/davinci.h
>
I tested this tested on DA850-evm in both Device Tree mode and using
the board file. The reboot is broken without the watchdog module, but
the watchdog patch is in [PATCH] ARM: davinci_all_defconfig: set
CONFIG_DAVINCI_WATCHDOG=y
Go ahead and mark me down as tested if you want.
Tested-by: Adam Ford <[email protected]>
> --
> 2.7.4
>
2018-01-20 18:13 GMT+01:00 David Lechner <[email protected]>:
> This series converts mach-davinci to use the common clock framework.
>
> The series works like this, the first 19 patches create new clock drivers
> using the common clock framework. There are basically 3 groups of clocks -
> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each have
> unique init data, which is the reason for so many patches.
>
> Then, starting with "ARM: da830: add new clock init using common clock",
> we get the mach code ready for the switch by adding the code needed for
> the new clock drivers and adding #ifndef CONFIG_COMMON_CLK around the
> legacy clocks so that we can switch easily between the old and the new.
>
> "ARM: davinci: switch to common clock framework" actually flips the switch
> to start using the new clock drivers. Then the next 8 patches remove all
> of the old clock code.
>
> The final three patches add device tree clock support to the one SoC that
> supports it.
>
> v6 changes (also see individual patches for details):
> - All of the device tree bindings are changed
> - All of the clock drivers are changed significantly
> - Fixed issues brought up during review of v5
> - "ARM: davinci: move davinci_clk_init() to init_time" is removed from this
> series and submitted separately
>
> v5 changes:
> - Basically, this is an entirely new series
> - Patches are broken up into bite-sized pieces
> - Converted PSC clock driver to use regmap
> - Restored "force" flag for certain DA850 clocks
> - Added device tree bindings
> - Moved more of the clock init to drivers/clk
> - Fixed frequency scaling (maybe*)
>
> * I have frequency scaling using cpufreq-dt, so I know the clocks are doing
> what they need to do to make this work, but I haven't figured out how to
> test davinci-cpufreq driver yet. (Patches to make cpufreq-dt work will be
> sent separately after this series has landed.)
>
> Dependencies:
>
> This series applies on top of linux-davinci/master plus the following patches:
> - [1] "clk: fix reentrancy of clk_enable() on UP systems" (in clk-next)
> - [2] "clk: add helper functions for managing clk_onecell_data"
> - [3] "clk: divider: read-only divider can propagate rate change"
> - [4],[5],[6],[7],[8],[9] series "ARM: davinci: common clock prep work"
>
Hi David,
I'm getting a splat[1] when trying to mount the rootfs over nfs on a da850-lcdk.
I'll try to figure out what's happening.
Best regards,
Bartosz Golaszewski
[1] https://pastebin.com/D94z8SAe
2018-01-20 18:13 GMT+01:00 David Lechner <[email protected]>:
> This series converts mach-davinci to use the common clock framework.
>
> The series works like this, the first 19 patches create new clock drivers
> using the common clock framework. There are basically 3 groups of clocks -
> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each have
> unique init data, which is the reason for so many patches.
>
> Then, starting with "ARM: da830: add new clock init using common clock",
> we get the mach code ready for the switch by adding the code needed for
> the new clock drivers and adding #ifndef CONFIG_COMMON_CLK around the
> legacy clocks so that we can switch easily between the old and the new.
>
> "ARM: davinci: switch to common clock framework" actually flips the switch
> to start using the new clock drivers. Then the next 8 patches remove all
> of the old clock code.
>
> The final three patches add device tree clock support to the one SoC that
> supports it.
>
> v6 changes (also see individual patches for details):
> - All of the device tree bindings are changed
> - All of the clock drivers are changed significantly
> - Fixed issues brought up during review of v5
> - "ARM: davinci: move davinci_clk_init() to init_time" is removed from this
> series and submitted separately
>
> v5 changes:
> - Basically, this is an entirely new series
> - Patches are broken up into bite-sized pieces
> - Converted PSC clock driver to use regmap
> - Restored "force" flag for certain DA850 clocks
> - Added device tree bindings
> - Moved more of the clock init to drivers/clk
> - Fixed frequency scaling (maybe*)
>
> * I have frequency scaling using cpufreq-dt, so I know the clocks are doing
> what they need to do to make this work, but I haven't figured out how to
> test davinci-cpufreq driver yet. (Patches to make cpufreq-dt work will be
> sent separately after this series has landed.)
>
This driver doesn't have DT support - I suppose it would be useful to
add it and also add the corresponding DT node to da850.dtsi. If you're
ok with it, I can start working on it. I also have a patch for the i2c
cpufreq issue and it would be nice to test it with it.
Thanks,
Bartosz
On Sat, Jan 20, 2018 at 11:13:48AM -0600, David Lechner wrote:
> 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 <[email protected]>
> ---
>
> v6 changes:
> - added clocks and clock-names properties
> - expanded examples
>
> .../devicetree/bindings/clock/ti/davinci/psc.txt | 66 ++++++++++++++++++++++
> 1 file changed, 66 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..0c2d2bd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/ti/davinci/psc.txt
> @@ -0,0 +1,66 @@
> +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
> +- clocks: phandles to clocks corresponding to the clock-names property
> +- clock-names: list of parent clock names - depends on compatible value
> + - for "ti,da850-psc0", shall be "pll0_sysclk1", "pll0_sysclk2",
> + "pll0_sysclk4", "pll0_sysclk6", "async1"
> + - for "ti,da850-psc1", shall be "pll0_sysclk2", "pll0_sysclk4", "async3"
> +
> +Optional properties:
> +- #reset-cells: from reset binding; shall be set to 1 - only applicable when
> + at least one local domain provides a local reset.
> +
> +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>;
> + clocks = <&pll0_sysclk 1>, <&pll0_sysclk 2>,
> + <&pll0_sysclk 4>, <&pll0_sysclk 6>, <&async1_clk>;
> + clock_names = "pll0_sysclk1", "pll0_sysclk2",
Should be clock-names
> + "pll0_sysclk4", "pll0_sysclk6", "async1";
> + };
> + psc1: clock-controller@227000 {
> + compatible = "ti,da850-psc1";
> + reg = <0x227000 0x1000>;
> + #clock-cells = <1>;
> + clocks = <&pll0_sysclk 2>, <&pll0_sysclk 4>, <&async3_clk>;
> + clock_names = "pll0_sysclk2", "pll0_sysclk4", "async3";
ditto
With that,
Reviewed-by: Rob Herring <[email protected]>
On 01/22/2018 07:29 AM, Bartosz Golaszewski wrote:
> 2018-01-20 18:13 GMT+01:00 David Lechner <[email protected]>:
>> This series converts mach-davinci to use the common clock framework.
>>
>> The series works like this, the first 19 patches create new clock drivers
>> using the common clock framework. There are basically 3 groups of clocks -
>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each have
>> unique init data, which is the reason for so many patches.
>>
>> Then, starting with "ARM: da830: add new clock init using common clock",
>> we get the mach code ready for the switch by adding the code needed for
>> the new clock drivers and adding #ifndef CONFIG_COMMON_CLK around the
>> legacy clocks so that we can switch easily between the old and the new.
>>
>> "ARM: davinci: switch to common clock framework" actually flips the switch
>> to start using the new clock drivers. Then the next 8 patches remove all
>> of the old clock code.
>>
>> The final three patches add device tree clock support to the one SoC that
>> supports it.
>>
>> v6 changes (also see individual patches for details):
>> - All of the device tree bindings are changed
>> - All of the clock drivers are changed significantly
>> - Fixed issues brought up during review of v5
>> - "ARM: davinci: move davinci_clk_init() to init_time" is removed from this
>> series and submitted separately
>>
>> v5 changes:
>> - Basically, this is an entirely new series
>> - Patches are broken up into bite-sized pieces
>> - Converted PSC clock driver to use regmap
>> - Restored "force" flag for certain DA850 clocks
>> - Added device tree bindings
>> - Moved more of the clock init to drivers/clk
>> - Fixed frequency scaling (maybe*)
>>
>> * I have frequency scaling using cpufreq-dt, so I know the clocks are doing
>> what they need to do to make this work, but I haven't figured out how to
>> test davinci-cpufreq driver yet. (Patches to make cpufreq-dt work will be
>> sent separately after this series has landed.)
>>
>
> This driver doesn't have DT support - I suppose it would be useful to
> add it and also add the corresponding DT node to da850.dtsi. If you're
> ok with it, I can start working on it. I also have a patch for the i2c
> cpufreq issue and it would be nice to test it with it.
>
Why not just use cpufreq-dt for the DT case? It seems to be working.
I have preliminary patches on GitHub [1][2].
[1]: https://github.com/dlech/ev3dev-kernel/commit/e38897148a949b736ab135983887f9c81375f108
[2]: https://github.com/dlech/ev3dev-kernel/commit/bab85f9e45450a36a7ea6f4407f89a75edb63761
On 01/20/2018 11:14 AM, David Lechner wrote:
> This adds clock provider nodes for da850 and wires them up to all of the
> devices.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
>
> v6 changes:
> - updated for device tree bindings changes earlier in this series
> - use single async2 clock instead of duplicate fixed factor clocks
> - add clock-names property to mdio node
>
> arch/arm/boot/dts/da850.dtsi | 162 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 162 insertions(+)
>
> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
...
> pmx_core: pinmux@14120 {
> compatible = "pinctrl-single";
> reg = <0x14120 0x50>;
> @@ -264,8 +325,43 @@
> usb_phy: usb-phy {
> compatible = "ti,da830-usb-phy";
> #phy-cells = <1>;
> + clocks = <&usb_phy_clk 0>, <&usb_phy_clk 1>;
> + clock-names = "usb20_phy", "usb11_phy";
This should be:
clock-names = "usb0_clk48", "usb1_clk48";
> status = "disabled";
> };
On 01/20/2018 11:13 AM, David Lechner wrote:
> This adds the new board-specific 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 <[email protected]>
> ---
>
> v6 changes:
> - add blank lines between function calls
> - include da8xx_register_cfgchip()
>
> arch/arm/mach-davinci/da830.c | 49 +++++++++++++++++++++++++++++++++++++------
> 1 file changed, 43 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
...
> + clk = clk_register_fixed_factor(NULL, "i2c0", "pll0_aux_clk", 0, 1, 1);
Should be "pll0_auxclk" instead of "pll0_aux_clk" here and 2 more below.
> + 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
> da8xx_register_cfgchip();
> davinci_clk_init(da830_clks);
> +#endif
> davinci_timer_init();
> }
>
On 01/20/2018 11:14 AM, David Lechner wrote:
> 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 <[email protected]>
> ---
>
> v6 changes:
> - rename stuff to match changes in "clk: davinci: New driver for TI DA8XX USB
> PHY clocks"
> - take advantage of syscon lookup changes in "mfd: syscon: Add syscon_register()
> function"
>
> arch/arm/mach-davinci/usb-da8xx.c | 78 ++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 77 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
...
> +/**
> + * 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.
> + */
Should say "pll0_auxclk" instead of "pll0_aux_clk".
On 01/22/2018 05:14 AM, Bartosz Golaszewski wrote:
> 2018-01-20 18:13 GMT+01:00 David Lechner <[email protected]>:
>> This series converts mach-davinci to use the common clock framework.
>>
>> The series works like this, the first 19 patches create new clock drivers
>> using the common clock framework. There are basically 3 groups of clocks -
>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each have
>> unique init data, which is the reason for so many patches.
>>
>> Then, starting with "ARM: da830: add new clock init using common clock",
>> we get the mach code ready for the switch by adding the code needed for
>> the new clock drivers and adding #ifndef CONFIG_COMMON_CLK around the
>> legacy clocks so that we can switch easily between the old and the new.
>>
>> "ARM: davinci: switch to common clock framework" actually flips the switch
>> to start using the new clock drivers. Then the next 8 patches remove all
>> of the old clock code.
>>
>> The final three patches add device tree clock support to the one SoC that
>> supports it.
>>
>> v6 changes (also see individual patches for details):
>> - All of the device tree bindings are changed
>> - All of the clock drivers are changed significantly
>> - Fixed issues brought up during review of v5
>> - "ARM: davinci: move davinci_clk_init() to init_time" is removed from this
>> series and submitted separately
>>
>> v5 changes:
>> - Basically, this is an entirely new series
>> - Patches are broken up into bite-sized pieces
>> - Converted PSC clock driver to use regmap
>> - Restored "force" flag for certain DA850 clocks
>> - Added device tree bindings
>> - Moved more of the clock init to drivers/clk
>> - Fixed frequency scaling (maybe*)
>>
>> * I have frequency scaling using cpufreq-dt, so I know the clocks are doing
>> what they need to do to make this work, but I haven't figured out how to
>> test davinci-cpufreq driver yet. (Patches to make cpufreq-dt work will be
>> sent separately after this series has landed.)
>>
>> Dependencies:
>>
>> This series applies on top of linux-davinci/master plus the following patches:
>> - [1] "clk: fix reentrancy of clk_enable() on UP systems" (in clk-next)
>> - [2] "clk: add helper functions for managing clk_onecell_data"
>> - [3] "clk: divider: read-only divider can propagate rate change"
>> - [4],[5],[6],[7],[8],[9] series "ARM: davinci: common clock prep work"
>>
>
> Hi David,
>
> I'm getting a splat[1] when trying to mount the rootfs over nfs on a da850-lcdk.
>
> I'll try to figure out what's happening.
>
> Best regards,
> Bartosz Golaszewski
>
> [1] https://pastebin.com/D94z8SAe
>
Could it have something to do with the "rmii" clock? I don't think I added that
in the device tree.
2018-01-22 18:30 GMT+01:00 David Lechner <[email protected]>:
> On 01/22/2018 05:14 AM, Bartosz Golaszewski wrote:
>>
>> 2018-01-20 18:13 GMT+01:00 David Lechner <[email protected]>:
>>>
>>> This series converts mach-davinci to use the common clock framework.
>>>
>>> The series works like this, the first 19 patches create new clock drivers
>>> using the common clock framework. There are basically 3 groups of clocks
>>> -
>>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each
>>> have
>>> unique init data, which is the reason for so many patches.
>>>
>>> Then, starting with "ARM: da830: add new clock init using common clock",
>>> we get the mach code ready for the switch by adding the code needed for
>>> the new clock drivers and adding #ifndef CONFIG_COMMON_CLK around the
>>> legacy clocks so that we can switch easily between the old and the new.
>>>
>>> "ARM: davinci: switch to common clock framework" actually flips the
>>> switch
>>> to start using the new clock drivers. Then the next 8 patches remove all
>>> of the old clock code.
>>>
>>> The final three patches add device tree clock support to the one SoC that
>>> supports it.
>>>
>>> v6 changes (also see individual patches for details):
>>> - All of the device tree bindings are changed
>>> - All of the clock drivers are changed significantly
>>> - Fixed issues brought up during review of v5
>>> - "ARM: davinci: move davinci_clk_init() to init_time" is removed from
>>> this
>>> series and submitted separately
>>>
>>> v5 changes:
>>> - Basically, this is an entirely new series
>>> - Patches are broken up into bite-sized pieces
>>> - Converted PSC clock driver to use regmap
>>> - Restored "force" flag for certain DA850 clocks
>>> - Added device tree bindings
>>> - Moved more of the clock init to drivers/clk
>>> - Fixed frequency scaling (maybe*)
>>>
>>> * I have frequency scaling using cpufreq-dt, so I know the clocks are
>>> doing
>>> what they need to do to make this work, but I haven't figured out how
>>> to
>>> test davinci-cpufreq driver yet. (Patches to make cpufreq-dt work will
>>> be
>>> sent separately after this series has landed.)
>>>
>>> Dependencies:
>>>
>>> This series applies on top of linux-davinci/master plus the following
>>> patches:
>>> - [1] "clk: fix reentrancy of clk_enable() on UP systems" (in clk-next)
>>> - [2] "clk: add helper functions for managing clk_onecell_data"
>>> - [3] "clk: divider: read-only divider can propagate rate change"
>>> - [4],[5],[6],[7],[8],[9] series "ARM: davinci: common clock prep work"
>>>
>>
>> Hi David,
>>
>> I'm getting a splat[1] when trying to mount the rootfs over nfs on a
>> da850-lcdk.
>>
>> I'll try to figure out what's happening.
>>
>> Best regards,
>> Bartosz Golaszewski
>>
>> [1] https://pastebin.com/D94z8SAe
>>
>
> Could it have something to do with the "rmii" clock? I don't think I added
> that
> in the device tree.
>
I'm looking at it now. There are problems with emac & mdio both in
legacy and in DT mode.
The davinci_mdio driver seems to not get an actual functional clock
(phy is reported as down). I'm seeing that in old legacy code,
mdio_clk has emac_clk as parent, while after your changes they share
pll0_sysclk4 as parent, although I'm not sure if that has anything to
do with it.
I'll see about the rmii clock too.
Thanks,
Bartosz
2018-01-22 18:11 GMT+01:00 David Lechner <[email protected]>:
> On 01/22/2018 07:29 AM, Bartosz Golaszewski wrote:
>>
>> 2018-01-20 18:13 GMT+01:00 David Lechner <[email protected]>:
>>>
>>> This series converts mach-davinci to use the common clock framework.
>>>
>>> The series works like this, the first 19 patches create new clock drivers
>>> using the common clock framework. There are basically 3 groups of clocks
>>> -
>>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each
>>> have
>>> unique init data, which is the reason for so many patches.
>>>
>>> Then, starting with "ARM: da830: add new clock init using common clock",
>>> we get the mach code ready for the switch by adding the code needed for
>>> the new clock drivers and adding #ifndef CONFIG_COMMON_CLK around the
>>> legacy clocks so that we can switch easily between the old and the new.
>>>
>>> "ARM: davinci: switch to common clock framework" actually flips the
>>> switch
>>> to start using the new clock drivers. Then the next 8 patches remove all
>>> of the old clock code.
>>>
>>> The final three patches add device tree clock support to the one SoC that
>>> supports it.
>>>
>>> v6 changes (also see individual patches for details):
>>> - All of the device tree bindings are changed
>>> - All of the clock drivers are changed significantly
>>> - Fixed issues brought up during review of v5
>>> - "ARM: davinci: move davinci_clk_init() to init_time" is removed from
>>> this
>>> series and submitted separately
>>>
>>> v5 changes:
>>> - Basically, this is an entirely new series
>>> - Patches are broken up into bite-sized pieces
>>> - Converted PSC clock driver to use regmap
>>> - Restored "force" flag for certain DA850 clocks
>>> - Added device tree bindings
>>> - Moved more of the clock init to drivers/clk
>>> - Fixed frequency scaling (maybe*)
>>>
>>> * I have frequency scaling using cpufreq-dt, so I know the clocks are
>>> doing
>>> what they need to do to make this work, but I haven't figured out how
>>> to
>>> test davinci-cpufreq driver yet. (Patches to make cpufreq-dt work will
>>> be
>>> sent separately after this series has landed.)
>>>
>>
>> This driver doesn't have DT support - I suppose it would be useful to
>> add it and also add the corresponding DT node to da850.dtsi. If you're
>> ok with it, I can start working on it. I also have a patch for the i2c
>> cpufreq issue and it would be nice to test it with it.
>>
>
> Why not just use cpufreq-dt for the DT case? It seems to be working.
>
> I have preliminary patches on GitHub [1][2].
>
> [1]:
> https://github.com/dlech/ev3dev-kernel/commit/e38897148a949b736ab135983887f9c81375f108
> [2]:
> https://github.com/dlech/ev3dev-kernel/commit/bab85f9e45450a36a7ea6f4407f89a75edb63761
>
No problem with that - I'll test them as soon as I'll be able to boot my lcdk.
Thanks,
Bartosz
On 01/23/2018 08:54 AM, Bartosz Golaszewski wrote:
> 2018-01-22 18:30 GMT+01:00 David Lechner <[email protected]>:
>> On 01/22/2018 05:14 AM, Bartosz Golaszewski wrote:
>>>
>>> 2018-01-20 18:13 GMT+01:00 David Lechner <[email protected]>:
>>>>
>>>> This series converts mach-davinci to use the common clock framework.
>>>>
>>>> The series works like this, the first 19 patches create new clock drivers
>>>> using the common clock framework. There are basically 3 groups of clocks
>>>> -
>>>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each
>>>> have
>>>> unique init data, which is the reason for so many patches.
>>>>
>>>> Then, starting with "ARM: da830: add new clock init using common clock",
>>>> we get the mach code ready for the switch by adding the code needed for
>>>> the new clock drivers and adding #ifndef CONFIG_COMMON_CLK around the
>>>> legacy clocks so that we can switch easily between the old and the new.
>>>>
>>>> "ARM: davinci: switch to common clock framework" actually flips the
>>>> switch
>>>> to start using the new clock drivers. Then the next 8 patches remove all
>>>> of the old clock code.
>>>>
>>>> The final three patches add device tree clock support to the one SoC that
>>>> supports it.
>>>>
>>>> v6 changes (also see individual patches for details):
>>>> - All of the device tree bindings are changed
>>>> - All of the clock drivers are changed significantly
>>>> - Fixed issues brought up during review of v5
>>>> - "ARM: davinci: move davinci_clk_init() to init_time" is removed from
>>>> this
>>>> series and submitted separately
>>>>
>>>> v5 changes:
>>>> - Basically, this is an entirely new series
>>>> - Patches are broken up into bite-sized pieces
>>>> - Converted PSC clock driver to use regmap
>>>> - Restored "force" flag for certain DA850 clocks
>>>> - Added device tree bindings
>>>> - Moved more of the clock init to drivers/clk
>>>> - Fixed frequency scaling (maybe*)
>>>>
>>>> * I have frequency scaling using cpufreq-dt, so I know the clocks are
>>>> doing
>>>> what they need to do to make this work, but I haven't figured out how
>>>> to
>>>> test davinci-cpufreq driver yet. (Patches to make cpufreq-dt work will
>>>> be
>>>> sent separately after this series has landed.)
>>>>
>>>> Dependencies:
>>>>
>>>> This series applies on top of linux-davinci/master plus the following
>>>> patches:
>>>> - [1] "clk: fix reentrancy of clk_enable() on UP systems" (in clk-next)
>>>> - [2] "clk: add helper functions for managing clk_onecell_data"
>>>> - [3] "clk: divider: read-only divider can propagate rate change"
>>>> - [4],[5],[6],[7],[8],[9] series "ARM: davinci: common clock prep work"
>>>>
>>>
>>> Hi David,
>>>
>>> I'm getting a splat[1] when trying to mount the rootfs over nfs on a
>>> da850-lcdk.
>>>
>>> I'll try to figure out what's happening.
>>>
>>> Best regards,
>>> Bartosz Golaszewski
>>>
>>> [1] https://pastebin.com/D94z8SAe
>>>
>>
>> Could it have something to do with the "rmii" clock? I don't think I added
>> that
>> in the device tree.
>>
>
> I'm looking at it now. There are problems with emac & mdio both in
> legacy and in DT mode.
Adam, is networking working for you on the DA850 EVM?
>
> The davinci_mdio driver seems to not get an actual functional clock
> (phy is reported as down). I'm seeing that in old legacy code,
> mdio_clk has emac_clk as parent, while after your changes they share
> pll0_sysclk4 as parent, although I'm not sure if that has anything to
> do with it.
The two clocks prior to these changes was a hack to work around a
limitation of the old lock code (because of the way it used a linked list
each clock could only be used once) so, yes, that should not have anything
to do with it.
I see that there is no clk_prepare_enable() in the mdio driver or the emac
driver. I suppose it expects pm_runtime to take care of this maybe?
You can see if the clock is enabled by running:
cat /sys/kernel/debug/clk/clk_summary
>
> I'll see about the rmii clock too.
FWIW, the rmii clock is in the clock init for non-DT da850.
On 01/23/2018 10:03 AM, David Lechner wrote:
> You can see if the clock is enabled by running:
>
> cat /sys/kernel/debug/clk/clk_summary
>
I just realized if you can't boot, you can't do this. :-/
On Tue, Jan 23, 2018 at 10:06 AM, David Lechner <[email protected]> wrote:
> On 01/23/2018 10:03 AM, David Lechner wrote:
>>
>> You can see if the clock is enabled by running:
>>
>> cat /sys/kernel/debug/clk/clk_summary
>>
>
> I just realized if you can't boot, you can't do this. :-/
I can boot with the latest set in your git repo, but the Ethernet
doesn't apparently fully operate. I don't get errors, but I cannot
get a dhcp address.
I'll try to do a more exhaustive test later today to get an idea of
what works and what doesn't. When I ran my basic tests, I just did a
feel-good boot test (and reboot test)
adam
2018-01-23 17:03 GMT+01:00 David Lechner <[email protected]>:
> On 01/23/2018 08:54 AM, Bartosz Golaszewski wrote:
>>
>> 2018-01-22 18:30 GMT+01:00 David Lechner <[email protected]>:
>>>
>>> On 01/22/2018 05:14 AM, Bartosz Golaszewski wrote:
>>>>
>>>>
>>>> 2018-01-20 18:13 GMT+01:00 David Lechner <[email protected]>:
>>>>>
>>>>>
>>>>> This series converts mach-davinci to use the common clock framework.
>>>>>
>>>>> The series works like this, the first 19 patches create new clock
>>>>> drivers
>>>>> using the common clock framework. There are basically 3 groups of
>>>>> clocks
>>>>> -
>>>>> PLL, PSC and CFGCHIP (syscon). There are six different SoCs that each
>>>>> have
>>>>> unique init data, which is the reason for so many patches.
>>>>>
>>>>> Then, starting with "ARM: da830: add new clock init using common
>>>>> clock",
>>>>> we get the mach code ready for the switch by adding the code needed for
>>>>> the new clock drivers and adding #ifndef CONFIG_COMMON_CLK around the
>>>>> legacy clocks so that we can switch easily between the old and the new.
>>>>>
>>>>> "ARM: davinci: switch to common clock framework" actually flips the
>>>>> switch
>>>>> to start using the new clock drivers. Then the next 8 patches remove
>>>>> all
>>>>> of the old clock code.
>>>>>
>>>>> The final three patches add device tree clock support to the one SoC
>>>>> that
>>>>> supports it.
>>>>>
>>>>> v6 changes (also see individual patches for details):
>>>>> - All of the device tree bindings are changed
>>>>> - All of the clock drivers are changed significantly
>>>>> - Fixed issues brought up during review of v5
>>>>> - "ARM: davinci: move davinci_clk_init() to init_time" is removed from
>>>>> this
>>>>> series and submitted separately
>>>>>
>>>>> v5 changes:
>>>>> - Basically, this is an entirely new series
>>>>> - Patches are broken up into bite-sized pieces
>>>>> - Converted PSC clock driver to use regmap
>>>>> - Restored "force" flag for certain DA850 clocks
>>>>> - Added device tree bindings
>>>>> - Moved more of the clock init to drivers/clk
>>>>> - Fixed frequency scaling (maybe*)
>>>>>
>>>>> * I have frequency scaling using cpufreq-dt, so I know the clocks are
>>>>> doing
>>>>> what they need to do to make this work, but I haven't figured out
>>>>> how
>>>>> to
>>>>> test davinci-cpufreq driver yet. (Patches to make cpufreq-dt work
>>>>> will
>>>>> be
>>>>> sent separately after this series has landed.)
>>>>>
>>>>> Dependencies:
>>>>>
>>>>> This series applies on top of linux-davinci/master plus the following
>>>>> patches:
>>>>> - [1] "clk: fix reentrancy of clk_enable() on UP systems" (in clk-next)
>>>>> - [2] "clk: add helper functions for managing clk_onecell_data"
>>>>> - [3] "clk: divider: read-only divider can propagate rate change"
>>>>> - [4],[5],[6],[7],[8],[9] series "ARM: davinci: common clock prep work"
>>>>>
>>>>
>>>> Hi David,
>>>>
>>>> I'm getting a splat[1] when trying to mount the rootfs over nfs on a
>>>> da850-lcdk.
>>>>
>>>> I'll try to figure out what's happening.
>>>>
>>>> Best regards,
>>>> Bartosz Golaszewski
>>>>
>>>> [1] https://pastebin.com/D94z8SAe
>>>>
>>>
>>> Could it have something to do with the "rmii" clock? I don't think I
>>> added
>>> that
>>> in the device tree.
>>>
>>
>> I'm looking at it now. There are problems with emac & mdio both in
>> legacy and in DT mode.
>
>
> Adam, is networking working for you on the DA850 EVM?
>
>>
>> The davinci_mdio driver seems to not get an actual functional clock
>> (phy is reported as down). I'm seeing that in old legacy code,
>> mdio_clk has emac_clk as parent, while after your changes they share
>> pll0_sysclk4 as parent, although I'm not sure if that has anything to
>> do with it.
>
>
> The two clocks prior to these changes was a hack to work around a
> limitation of the old lock code (because of the way it used a linked list
> each clock could only be used once) so, yes, that should not have anything
> to do with it.
>
And it was I who did the change in commit ef37427ac567 ("ARM: davinci:
da850: don't add emac clock to lookup table twice") :) Already forgot
that.
> I see that there is no clk_prepare_enable() in the mdio driver or the emac
> driver. I suppose it expects pm_runtime to take care of this maybe?
>
> You can see if the clock is enabled by running:
>
> cat /sys/kernel/debug/clk/clk_summary
>
>>
>> I'll see about the rmii clock too.
>
> FWIW, the rmii clock is in the clock init for non-DT da850.
>
2018-01-23 17:06 GMT+01:00 David Lechner <[email protected]>:
> On 01/23/2018 10:03 AM, David Lechner wrote:
>>
>> You can see if the clock is enabled by running:
>>
>> cat /sys/kernel/debug/clk/clk_summary
>>
>
> I just realized if you can't boot, you can't do this. :-/
I can always boot from SD or just printk it.
Thanks,
Bartosz
2018-01-23 18:03 GMT+01:00 Adam Ford <[email protected]>:
> On Tue, Jan 23, 2018 at 10:06 AM, David Lechner <[email protected]> wrote:
>> On 01/23/2018 10:03 AM, David Lechner wrote:
>>>
>>> You can see if the clock is enabled by running:
>>>
>>> cat /sys/kernel/debug/clk/clk_summary
>>>
>>
>> I just realized if you can't boot, you can't do this. :-/
>
> I can boot with the latest set in your git repo, but the Ethernet
> doesn't apparently fully operate. I don't get errors, but I cannot
> get a dhcp address.
>
> I'll try to do a more exhaustive test later today to get an idea of
> what works and what doesn't. When I ran my basic tests, I just did a
> feel-good boot test (and reboot test)
>
> adam
FYI: manually calling clk_prepare_enable() in the davinci_mdio driver
seems to at least fix the ethernet. In master branch it's done by
pm_runtime_get_sync() (in davinci_mdio_reset()). However I'm still
getting several oopses and WARNs so there's some more work to do.
Thanks,
Bartosz
On 01/23/2018 12:10 PM, Bartosz Golaszewski wrote:
> 2018-01-23 18:03 GMT+01:00 Adam Ford <[email protected]>:
>> On Tue, Jan 23, 2018 at 10:06 AM, David Lechner <[email protected]> wrote:
>>> On 01/23/2018 10:03 AM, David Lechner wrote:
>>>>
>>>> You can see if the clock is enabled by running:
>>>>
>>>> cat /sys/kernel/debug/clk/clk_summary
>>>>
>>>
>>> I just realized if you can't boot, you can't do this. :-/
>>
>> I can boot with the latest set in your git repo, but the Ethernet
>> doesn't apparently fully operate. I don't get errors, but I cannot
>> get a dhcp address.
>>
>> I'll try to do a more exhaustive test later today to get an idea of
>> what works and what doesn't. When I ran my basic tests, I just did a
>> feel-good boot test (and reboot test)
>>
>> adam
>
> FYI: manually calling clk_prepare_enable() in the davinci_mdio driver
> seems to at least fix the ethernet. In master branch it's done by
> pm_runtime_get_sync() (in davinci_mdio_reset()). However I'm still
> getting several oopses and WARNs so there's some more work to do.
>
Hmm... I'm wondering if we need to also add #power-domain-cells to the
PSC clocks and power-domains properties to the consumers.
For this specific case though, it seems strange to me that the drivers
to clk_get() and clk_get_rate() but never enable the clocks.
Also, are the oopses and WARNs the same as before?
2018-01-23 19:26 GMT+01:00 David Lechner <[email protected]>:
> On 01/23/2018 12:10 PM, Bartosz Golaszewski wrote:
>>
>> 2018-01-23 18:03 GMT+01:00 Adam Ford <[email protected]>:
>>>
>>> On Tue, Jan 23, 2018 at 10:06 AM, David Lechner <[email protected]>
>>> wrote:
>>>>
>>>> On 01/23/2018 10:03 AM, David Lechner wrote:
>>>>>
>>>>>
>>>>> You can see if the clock is enabled by running:
>>>>>
>>>>> cat /sys/kernel/debug/clk/clk_summary
>>>>>
>>>>
>>>> I just realized if you can't boot, you can't do this. :-/
>>>
>>>
>>> I can boot with the latest set in your git repo, but the Ethernet
>>> doesn't apparently fully operate. I don't get errors, but I cannot
>>> get a dhcp address.
>>>
>>> I'll try to do a more exhaustive test later today to get an idea of
>>> what works and what doesn't. When I ran my basic tests, I just did a
>>> feel-good boot test (and reboot test)
>>>
>>> adam
>>
>>
>> FYI: manually calling clk_prepare_enable() in the davinci_mdio driver
>> seems to at least fix the ethernet. In master branch it's done by
>> pm_runtime_get_sync() (in davinci_mdio_reset()). However I'm still
>> getting several oopses and WARNs so there's some more work to do.
>>
>
> Hmm... I'm wondering if we need to also add #power-domain-cells to the
> PSC clocks and power-domains properties to the consumers.
>
> For this specific case though, it seems strange to me that the drivers
> to clk_get() and clk_get_rate() but never enable the clocks.
>
>
> Also, are the oopses and WARNs the same as before?
No, the ones before were all related to the ethernet failing, now I
get several stack traces from drm. Posted them on pastebin[1].
Thanks,
Bartosz
[1] https://pastebin.com/H3yZ5xHv
On 01/23/2018 12:34 PM, Bartosz Golaszewski wrote:
> 2018-01-23 19:26 GMT+01:00 David Lechner <[email protected]>:
>> On 01/23/2018 12:10 PM, Bartosz Golaszewski wrote:
>>>
>>> 2018-01-23 18:03 GMT+01:00 Adam Ford <[email protected]>:
>>>>
>>>> On Tue, Jan 23, 2018 at 10:06 AM, David Lechner <[email protected]>
>>>> wrote:
>>>>>
>>>>> On 01/23/2018 10:03 AM, David Lechner wrote:
>>>>>>
>>>>>>
>>>>>> You can see if the clock is enabled by running:
>>>>>>
>>>>>> cat /sys/kernel/debug/clk/clk_summary
>>>>>>
>>>>>
>>>>> I just realized if you can't boot, you can't do this. :-/
>>>>
>>>>
>>>> I can boot with the latest set in your git repo, but the Ethernet
>>>> doesn't apparently fully operate. I don't get errors, but I cannot
>>>> get a dhcp address.
>>>>
>>>> I'll try to do a more exhaustive test later today to get an idea of
>>>> what works and what doesn't. When I ran my basic tests, I just did a
>>>> feel-good boot test (and reboot test)
>>>>
>>>> adam
>>>
>>>
>>> FYI: manually calling clk_prepare_enable() in the davinci_mdio driver
>>> seems to at least fix the ethernet. In master branch it's done by
>>> pm_runtime_get_sync() (in davinci_mdio_reset()). However I'm still
>>> getting several oopses and WARNs so there's some more work to do.
>>>
>>
>> Hmm... I'm wondering if we need to also add #power-domain-cells to the
>> PSC clocks and power-domains properties to the consumers.
>>
>> For this specific case though, it seems strange to me that the drivers
>> to clk_get() and clk_get_rate() but never enable the clocks.
>>
>>
>> Also, are the oopses and WARNs the same as before?
>
> No, the ones before were all related to the ethernet failing, now I
> get several stack traces from drm. Posted them on pastebin[1].
>
It looks like the LCDC driver is the same way. It does clk_get() but
not clk_prepare_enable().
2018-01-23 20:24 GMT+01:00 David Lechner <[email protected]>:
> On 01/23/2018 12:34 PM, Bartosz Golaszewski wrote:
>>
>> 2018-01-23 19:26 GMT+01:00 David Lechner <[email protected]>:
>>>
>>> On 01/23/2018 12:10 PM, Bartosz Golaszewski wrote:
>>>>
>>>>
>>>> 2018-01-23 18:03 GMT+01:00 Adam Ford <[email protected]>:
>>>>>
>>>>>
>>>>> On Tue, Jan 23, 2018 at 10:06 AM, David Lechner <[email protected]>
>>>>> wrote:
>>>>>>
>>>>>>
>>>>>> On 01/23/2018 10:03 AM, David Lechner wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> You can see if the clock is enabled by running:
>>>>>>>
>>>>>>> cat /sys/kernel/debug/clk/clk_summary
>>>>>>>
>>>>>>
>>>>>> I just realized if you can't boot, you can't do this. :-/
>>>>>
>>>>>
>>>>>
>>>>> I can boot with the latest set in your git repo, but the Ethernet
>>>>> doesn't apparently fully operate. I don't get errors, but I cannot
>>>>> get a dhcp address.
>>>>>
>>>>> I'll try to do a more exhaustive test later today to get an idea of
>>>>> what works and what doesn't. When I ran my basic tests, I just did a
>>>>> feel-good boot test (and reboot test)
>>>>>
>>>>> adam
>>>>
>>>>
>>>>
>>>> FYI: manually calling clk_prepare_enable() in the davinci_mdio driver
>>>> seems to at least fix the ethernet. In master branch it's done by
>>>> pm_runtime_get_sync() (in davinci_mdio_reset()). However I'm still
>>>> getting several oopses and WARNs so there's some more work to do.
>>>>
>>>
>>> Hmm... I'm wondering if we need to also add #power-domain-cells to the
>>> PSC clocks and power-domains properties to the consumers.
>>>
>>> For this specific case though, it seems strange to me that the drivers
>>> to clk_get() and clk_get_rate() but never enable the clocks.
>>>
>>>
>>> Also, are the oopses and WARNs the same as before?
>>
>>
>> No, the ones before were all related to the ethernet failing, now I
>> get several stack traces from drm. Posted them on pastebin[1].
>>
>
> It looks like the LCDC driver is the same way. It does clk_get() but
> not clk_prepare_enable().
>
>
In the mdio case - the problem is that devm_clk_get() doesn't fail,
but somehow the clock doesn't end up in the list of the device's
clocks - which is why it's not enabled by pm_runtime_get_sync().
Bartosz
On 01/23/2018 01:53 PM, Bartosz Golaszewski wrote:
> 2018-01-23 20:24 GMT+01:00 David Lechner <[email protected]>:
>> On 01/23/2018 12:34 PM, Bartosz Golaszewski wrote:
>>>
>>> 2018-01-23 19:26 GMT+01:00 David Lechner <[email protected]>:
>>>>
>>>> On 01/23/2018 12:10 PM, Bartosz Golaszewski wrote:
>>>>>
>>>>>
>>>>> 2018-01-23 18:03 GMT+01:00 Adam Ford <[email protected]>:
>>>>>>
>>>>>>
>>>>>> On Tue, Jan 23, 2018 at 10:06 AM, David Lechner <[email protected]>
>>>>>> wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 01/23/2018 10:03 AM, David Lechner wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> You can see if the clock is enabled by running:
>>>>>>>>
>>>>>>>> cat /sys/kernel/debug/clk/clk_summary
>>>>>>>>
>>>>>>>
>>>>>>> I just realized if you can't boot, you can't do this. :-/
>>>>>>
>>>>>>
>>>>>>
>>>>>> I can boot with the latest set in your git repo, but the Ethernet
>>>>>> doesn't apparently fully operate. I don't get errors, but I cannot
>>>>>> get a dhcp address.
>>>>>>
>>>>>> I'll try to do a more exhaustive test later today to get an idea of
>>>>>> what works and what doesn't. When I ran my basic tests, I just did a
>>>>>> feel-good boot test (and reboot test)
>>>>>>
>>>>>> adam
>>>>>
>>>>>
>>>>>
>>>>> FYI: manually calling clk_prepare_enable() in the davinci_mdio driver
>>>>> seems to at least fix the ethernet. In master branch it's done by
>>>>> pm_runtime_get_sync() (in davinci_mdio_reset()). However I'm still
>>>>> getting several oopses and WARNs so there's some more work to do.
>>>>>
>>>>
>>>> Hmm... I'm wondering if we need to also add #power-domain-cells to the
>>>> PSC clocks and power-domains properties to the consumers.
>>>>
>>>> For this specific case though, it seems strange to me that the drivers
>>>> to clk_get() and clk_get_rate() but never enable the clocks.
>>>>
>>>>
>>>> Also, are the oopses and WARNs the same as before?
>>>
>>>
>>> No, the ones before were all related to the ethernet failing, now I
>>> get several stack traces from drm. Posted them on pastebin[1].
>>>
>>
>> It looks like the LCDC driver is the same way. It does clk_get() but
>> not clk_prepare_enable().
>>
>>
>
> In the mdio case - the problem is that devm_clk_get() doesn't fail,
> but somehow the clock doesn't end up in the list of the device's
> clocks - which is why it's not enabled by pm_runtime_get_sync().
>
Right. This is because devm_clk_get() now finds the clock via device
tree instead of a clkdev lookup entry. However, I think that the PM
notifier registered in arch/arm/mach-davinci/pm_domain.c only uses
the clkdev lookup to match the con_id and does not use device tree.
The same thing is happing in mdio, emac and lcdc.
On 01/23/2018 02:01 PM, David Lechner wrote:
> On 01/23/2018 01:53 PM, Bartosz Golaszewski wrote:
>>
>> In the mdio case - the problem is that devm_clk_get() doesn't fail,
>> but somehow the clock doesn't end up in the list of the device's
>> clocks - which is why it's not enabled by pm_runtime_get_sync().
>>
>
>
> Right. This is because devm_clk_get() now finds the clock via device
> tree instead of a clkdev lookup entry. However, I think that the PM
> notifier registered in arch/arm/mach-davinci/pm_domain.c only uses
> the clkdev lookup to match the con_id and does not use device tree.
> The same thing is happing in mdio, emac and lcdc.
>
Minor correction: It looks like emac doesn't do this because it doesn't
have a con_id of "fck". But, the same clock is shared by emac and mdio, so
since mdio enables the clock, emac doesn't notice or care that it did
not enable the clock itself.
On 01/23/2018 02:05 PM, David Lechner wrote:
> On 01/23/2018 02:01 PM, David Lechner wrote:
>> On 01/23/2018 01:53 PM, Bartosz Golaszewski wrote:
>>>
>>> In the mdio case - the problem is that devm_clk_get() doesn't fail,
>>> but somehow the clock doesn't end up in the list of the device's
>>> clocks - which is why it's not enabled by pm_runtime_get_sync().
>>>
>>
>>
>> Right. This is because devm_clk_get() now finds the clock via device
>> tree instead of a clkdev lookup entry. However, I think that the PM
>> notifier registered in arch/arm/mach-davinci/pm_domain.c only uses
>> the clkdev lookup to match the con_id and does not use device tree.
>> The same thing is happing in mdio, emac and lcdc.
>>
>
> Minor correction: It looks like emac doesn't do this because it doesn't
> have a con_id of "fck". But, the same clock is shared by emac and mdio, so
> since mdio enables the clock, emac doesn't notice or care that it did
> not enable the clock itself.
How about using pm_clk_add_clk() in these drivers to explicitly use the
clocks for power management instead of relying on pm_clk_add_notifier()
to do this implicitly?
On 01/20/2018 11:14 AM, David Lechner wrote:
> This removes all of the clock init code from da8xx-dt.c. This includes
> all of the OF_DEV_AUXDATA that was just used for looking up clocks.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
>
> v6 changes:
> - removed misleading statement from commit message
>
> arch/arm/mach-davinci/da8xx-dt.c | 61 +---------------------------------------
> 1 file changed, 1 insertion(+), 60 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
> static void __init da850_init_machine(void)
> {
> - /* All existing boards use 100MHz SATA refclkpn */
> - static const unsigned long sata_refclkpn = 100 * 1000 * 1000;
> -
> - int ret;
> -
> - ret = da8xx_register_usb20_phy_clk(false);
> - if (ret)
> - pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
> - __func__, ret);
> - ret = da8xx_register_usb11_phy_clk(false);
> - if (ret)
> - pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
> - __func__, ret);
> -
> - ret = da850_register_sata_refclk(sata_refclkpn);
> - if (ret)
> - pr_warn("%s: registering SATA REFCLK failed: %d",
> - __func__, ret);
> -
> - of_platform_default_populate(NULL, da850_auxdata_lookup, NULL);
> + of_platform_default_populate(NULL, NULL, NULL);
of_platform_default_populate() can actually be removed completely.
of_platform_default_populate_init() is called implicitly during
arch_initcall_sync
> davinci_pm_init();
> pdata_quirks_init();
> }
On 01/20/2018 11:14 AM, David Lechner wrote:
> This adds clock provider nodes for da850 and wires them up to all of the
> devices.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
>
> v6 changes:
> - updated for device tree bindings changes earlier in this series
> - use single async2 clock instead of duplicate fixed factor clocks
> - add clock-names property to mdio node
>
> arch/arm/boot/dts/da850.dtsi | 162 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 162 insertions(+)
>
> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
...
> + psc1: clock-controller@227000 {
> + compatible = "ti,da850-psc1";
> + reg = <0x227000 0x1000>;
> + #clock-cells = <1>;
> + clocks = <&pll0_sysclk 2>, <&pll0_sysclk 4>,
> + <&async3_clk>;
> + clock_names = "pll0_sysclk2", "pll0_sysclk4", "async3";
Should be clock-names, not clock_names
> };
2018-01-23 21:23 GMT+01:00 David Lechner <[email protected]>:
> On 01/23/2018 02:05 PM, David Lechner wrote:
>>
>> On 01/23/2018 02:01 PM, David Lechner wrote:
>>>
>>> On 01/23/2018 01:53 PM, Bartosz Golaszewski wrote:
>>>>
>>>>
>>>> In the mdio case - the problem is that devm_clk_get() doesn't fail,
>>>> but somehow the clock doesn't end up in the list of the device's
>>>> clocks - which is why it's not enabled by pm_runtime_get_sync().
>>>>
>>>
>>>
>>> Right. This is because devm_clk_get() now finds the clock via device
>>> tree instead of a clkdev lookup entry. However, I think that the PM
>>> notifier registered in arch/arm/mach-davinci/pm_domain.c only uses
>>> the clkdev lookup to match the con_id and does not use device tree.
>>> The same thing is happing in mdio, emac and lcdc.
>>>
>>
>> Minor correction: It looks like emac doesn't do this because it doesn't
>> have a con_id of "fck". But, the same clock is shared by emac and mdio, so
>> since mdio enables the clock, emac doesn't notice or care that it did
>> not enable the clock itself.
>
>
> How about using pm_clk_add_clk() in these drivers to explicitly use the
> clocks for power management instead of relying on pm_clk_add_notifier()
> to do this implicitly?
Yes, this sounds good.
Bartosz
On Wednesday 24 January 2018 01:33 PM, Bartosz Golaszewski wrote:
> 2018-01-23 21:23 GMT+01:00 David Lechner <[email protected]>:
>> On 01/23/2018 02:05 PM, David Lechner wrote:
>>>
>>> On 01/23/2018 02:01 PM, David Lechner wrote:
>>>>
>>>> On 01/23/2018 01:53 PM, Bartosz Golaszewski wrote:
>>>>>
>>>>>
>>>>> In the mdio case - the problem is that devm_clk_get() doesn't fail,
>>>>> but somehow the clock doesn't end up in the list of the device's
>>>>> clocks - which is why it's not enabled by pm_runtime_get_sync().
>>>>>
>>>>
>>>>
>>>> Right. This is because devm_clk_get() now finds the clock via device
>>>> tree instead of a clkdev lookup entry. However, I think that the PM
>>>> notifier registered in arch/arm/mach-davinci/pm_domain.c only uses
>>>> the clkdev lookup to match the con_id and does not use device tree.
>>>> The same thing is happing in mdio, emac and lcdc.
>>>>
>>>
>>> Minor correction: It looks like emac doesn't do this because it doesn't
>>> have a con_id of "fck". But, the same clock is shared by emac and mdio, so
>>> since mdio enables the clock, emac doesn't notice or care that it did
>>> not enable the clock itself.
>>
>>
>> How about using pm_clk_add_clk() in these drivers to explicitly use the
>> clocks for power management instead of relying on pm_clk_add_notifier()
>> to do this implicitly?
>
> Yes, this sounds good.
Looking at how pm_clk_notify() in clock_ops.c uses con_id[] list, right
now pm_runtime() will work only for clocks which have con_id (from the
list above) mentioned in DT. Since clk_find() mandates con_id match when
its available, NULL con_id does not match.
For simple devices like DaVinci which uses just one clock for power
management per device (multiple devices might share a clock, but not
other way around as far as I recall, anyway I will double check this
assertion), the attached patch should make EMAC work.
That still leaves why lcdc does not work. One difference is it uses
PSC1. Are there other devices in PSC1 which work (just to rule out any
thing wrong with PSC1 handling).
Thanks,
Sekhar
---8<---
diff --git a/arch/arm/mach-davinci/pm_domain.c b/arch/arm/mach-davinci/pm_domain.c
index 78eac2c0c146..0dce7397856d 100644
--- a/arch/arm/mach-davinci/pm_domain.c
+++ b/arch/arm/mach-davinci/pm_domain.c
@@ -23,7 +23,6 @@ static struct dev_pm_domain davinci_pm_domain = {
static struct pm_clk_notifier_block platform_bus_notifier = {
.pm_domain = &davinci_pm_domain,
- .con_ids = { "fck", "master", "slave", NULL },
};
static int __init davinci_pm_runtime_init(void)
2018-01-25 13:53 GMT+01:00 Sekhar Nori <[email protected]>:
> On Wednesday 24 January 2018 01:33 PM, Bartosz Golaszewski wrote:
>> 2018-01-23 21:23 GMT+01:00 David Lechner <[email protected]>:
>>> On 01/23/2018 02:05 PM, David Lechner wrote:
>>>>
>>>> On 01/23/2018 02:01 PM, David Lechner wrote:
>>>>>
>>>>> On 01/23/2018 01:53 PM, Bartosz Golaszewski wrote:
>>>>>>
>>>>>>
>>>>>> In the mdio case - the problem is that devm_clk_get() doesn't fail,
>>>>>> but somehow the clock doesn't end up in the list of the device's
>>>>>> clocks - which is why it's not enabled by pm_runtime_get_sync().
>>>>>>
>>>>>
>>>>>
>>>>> Right. This is because devm_clk_get() now finds the clock via device
>>>>> tree instead of a clkdev lookup entry. However, I think that the PM
>>>>> notifier registered in arch/arm/mach-davinci/pm_domain.c only uses
>>>>> the clkdev lookup to match the con_id and does not use device tree.
>>>>> The same thing is happing in mdio, emac and lcdc.
>>>>>
>>>>
>>>> Minor correction: It looks like emac doesn't do this because it doesn't
>>>> have a con_id of "fck". But, the same clock is shared by emac and mdio, so
>>>> since mdio enables the clock, emac doesn't notice or care that it did
>>>> not enable the clock itself.
>>>
>>>
>>> How about using pm_clk_add_clk() in these drivers to explicitly use the
>>> clocks for power management instead of relying on pm_clk_add_notifier()
>>> to do this implicitly?
>>
>> Yes, this sounds good.
>
> Looking at how pm_clk_notify() in clock_ops.c uses con_id[] list, right
> now pm_runtime() will work only for clocks which have con_id (from the
> list above) mentioned in DT. Since clk_find() mandates con_id match when
> its available, NULL con_id does not match.
>
> For simple devices like DaVinci which uses just one clock for power
> management per device (multiple devices might share a clock, but not
> other way around as far as I recall, anyway I will double check this
> assertion), the attached patch should make EMAC work.
>
Tested on da850-lcdk - patch does indeex fix emac on da850-lcdk, but
tilcdc still complains.
> That still leaves why lcdc does not work. One difference is it uses
> PSC1. Are there other devices in PSC1 which work (just to rule out any
> thing wrong with PSC1 handling).
>
Emac uses PSC1 too.
GPIO and I2C1 work fine, but OHCI rarely lives through any cpufreq
transition. I'm still trying to figure out why it's dying.
Thanks,
Bartosz
On 01/25/2018 06:53 AM, Sekhar Nori wrote:
> On Wednesday 24 January 2018 01:33 PM, Bartosz Golaszewski wrote:
>> 2018-01-23 21:23 GMT+01:00 David Lechner <[email protected]>:
>>> On 01/23/2018 02:05 PM, David Lechner wrote:
>>>>
>>>> On 01/23/2018 02:01 PM, David Lechner wrote:
>>>>>
>>>>> On 01/23/2018 01:53 PM, Bartosz Golaszewski wrote:
>>>>>>
>>>>>>
>>>>>> In the mdio case - the problem is that devm_clk_get() doesn't fail,
>>>>>> but somehow the clock doesn't end up in the list of the device's
>>>>>> clocks - which is why it's not enabled by pm_runtime_get_sync().
>>>>>>
>>>>>
>>>>>
>>>>> Right. This is because devm_clk_get() now finds the clock via device
>>>>> tree instead of a clkdev lookup entry. However, I think that the PM
>>>>> notifier registered in arch/arm/mach-davinci/pm_domain.c only uses
>>>>> the clkdev lookup to match the con_id and does not use device tree.
>>>>> The same thing is happing in mdio, emac and lcdc.
>>>>>
>>>>
>>>> Minor correction: It looks like emac doesn't do this because it doesn't
>>>> have a con_id of "fck". But, the same clock is shared by emac and mdio, so
>>>> since mdio enables the clock, emac doesn't notice or care that it did
>>>> not enable the clock itself.
>>>
>>>
>>> How about using pm_clk_add_clk() in these drivers to explicitly use the
>>> clocks for power management instead of relying on pm_clk_add_notifier()
>>> to do this implicitly?
>>
>> Yes, this sounds good.
>
> Looking at how pm_clk_notify() in clock_ops.c uses con_id[] list, right
> now pm_runtime() will work only for clocks which have con_id (from the
> list above) mentioned in DT. Since clk_find() mandates con_id match when
> its available, NULL con_id does not match.
>
> For simple devices like DaVinci which uses just one clock for power
> management per device (multiple devices might share a clock, but not
> other way around as far as I recall, anyway I will double check this
> assertion), the attached patch should make EMAC work.
>
> That still leaves why lcdc does not work. One difference is it uses
> PSC1. Are there other devices in PSC1 which work (just to rule out any
> thing wrong with PSC1 handling).
>
> Thanks,
> Sekhar
>
> ---8<---
> diff --git a/arch/arm/mach-davinci/pm_domain.c b/arch/arm/mach-davinci/pm_domain.c
> index 78eac2c0c146..0dce7397856d 100644
> --- a/arch/arm/mach-davinci/pm_domain.c
> +++ b/arch/arm/mach-davinci/pm_domain.c
> @@ -23,7 +23,6 @@ static struct dev_pm_domain davinci_pm_domain = {
>
> static struct pm_clk_notifier_block platform_bus_notifier = {
> .pm_domain = &davinci_pm_domain,
> - .con_ids = { "fck", "master", "slave", NULL },
> };
>
> static int __init davinci_pm_runtime_init(void)
>
>
Won't this cause *all* clocks, not just PSC clocks, to be used for power management?
Some examples of devices with more than just the PSC clock are SATA and the USB PHY.
On Thursday 25 January 2018 09:48 PM, David Lechner wrote:
> On 01/25/2018 06:53 AM, Sekhar Nori wrote:
>> On Wednesday 24 January 2018 01:33 PM, Bartosz Golaszewski wrote:
>>> 2018-01-23 21:23 GMT+01:00 David Lechner <[email protected]>:
>>>> On 01/23/2018 02:05 PM, David Lechner wrote:
>>>>>
>>>>> On 01/23/2018 02:01 PM, David Lechner wrote:
>>>>>>
>>>>>> On 01/23/2018 01:53 PM, Bartosz Golaszewski wrote:
>>>>>>>
>>>>>>>
>>>>>>> In the mdio case - the problem is that devm_clk_get() doesn't fail,
>>>>>>> but somehow the clock doesn't end up in the list of the device's
>>>>>>> clocks - which is why it's not enabled by pm_runtime_get_sync().
>>>>>>>
>>>>>>
>>>>>>
>>>>>> Right. This is because devm_clk_get() now finds the clock via device
>>>>>> tree instead of a clkdev lookup entry. However, I think that the PM
>>>>>> notifier registered in arch/arm/mach-davinci/pm_domain.c only uses
>>>>>> the clkdev lookup to match the con_id and does not use device tree.
>>>>>> The same thing is happing in mdio, emac and lcdc.
>>>>>>
>>>>>
>>>>> Minor correction: It looks like emac doesn't do this because it
>>>>> doesn't
>>>>> have a con_id of "fck". But, the same clock is shared by emac and
>>>>> mdio, so
>>>>> since mdio enables the clock, emac doesn't notice or care that it did
>>>>> not enable the clock itself.
>>>>
>>>>
>>>> How about using pm_clk_add_clk() in these drivers to explicitly use the
>>>> clocks for power management instead of relying on pm_clk_add_notifier()
>>>> to do this implicitly?
>>>
>>> Yes, this sounds good.
>>
>> Looking at how pm_clk_notify() in clock_ops.c uses con_id[] list, right
>> now pm_runtime() will work only for clocks which have con_id (from the
>> list above) mentioned in DT. Since clk_find() mandates con_id match when
>> its available, NULL con_id does not match.
>>
>> For simple devices like DaVinci which uses just one clock for power
>> management per device (multiple devices might share a clock, but not
>> other way around as far as I recall, anyway I will double check this
>> assertion), the attached patch should make EMAC work.
>>
>> That still leaves why lcdc does not work. One difference is it uses
>> PSC1. Are there other devices in PSC1 which work (just to rule out any
>> thing wrong with PSC1 handling).
>>
>> Thanks,
>> Sekhar
>>
>> ---8<---
>> diff --git a/arch/arm/mach-davinci/pm_domain.c
>> b/arch/arm/mach-davinci/pm_domain.c
>> index 78eac2c0c146..0dce7397856d 100644
>> --- a/arch/arm/mach-davinci/pm_domain.c
>> +++ b/arch/arm/mach-davinci/pm_domain.c
>> @@ -23,7 +23,6 @@ static struct dev_pm_domain davinci_pm_domain = {
>> static struct pm_clk_notifier_block platform_bus_notifier = {
>> .pm_domain = &davinci_pm_domain,
>> - .con_ids = { "fck", "master", "slave", NULL },
>> };
>> static int __init davinci_pm_runtime_init(void)
>>
>>
>
> Won't this cause *all* clocks, not just PSC clocks, to be used for power
> management?
In case of DT, the first clock mentioned in 'clocks' property will get
picked up since it will match with wildcard con_id. This unfortunately
depends on how the clocks list is prepared so quite implementation
dependent.
>
> Some examples of devices with more than just the PSC clock are SATA and
> the USB PHY.
Its not a problem to have more than one clock passed in device node as
long as only one clock (the first clock) needs to participate in power
management.
This may work for the moment, but longer term I do think genpd
implementation for DaVinci will be needed. Or may be there is breakage
even today that I am not able to think on top of my head.
Thanks,
Sekhar
On Sat, Jan 20, 2018 at 11:13:40AM -0600, David Lechner wrote:
> This adds a new binding for the PLL IP blocks in the mach-davinci
> family of processors. Currently, only da850 has device tree support
> but these bindings can also work for other SoCs in this family just
> by adding new compatible strings.
>
> 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 <[email protected]>
> ---
>
> v6 changes:
> - Added clock-names property
> - Added ti,clkmode-square-wave property
> - Added pllout child node
> - Added obsclk child node
> - Expanded examples
>
> .../devicetree/bindings/clock/ti/davinci/pll.txt | 96 ++++++++++++++++++++++
> 1 file changed, 96 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..36998e1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
> @@ -0,0 +1,96 @@
> +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: phandles corresponding to the clock names
> +- clock-names: names of the clock sources - depends on compatible string
> + - for "ti,da850-pll0", shall be "clksrc", "extclksrc"
> + - for "ti,da850-pll1", shall be "clksrc"
> +
> +Optional properties:
> +- ti,clkmode-square-wave: Indicates that the the board is supplying a square
> + wave input on the OSCIN pin instead of using a crystal oscillator.
> + This property is only valid when compatible = "ti,da850-pll0".
> +
> +
> +Optional child nodes:
> +
> +pllout
> + Describes the main PLL clock output (before POSTDIV). The node name must
> + be "pllout".
> +
> + Required properties:
> + - #clock-cells: shall be 0
> +
> +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 index parameter for the clock cell.
> +
> + Required properties:
> + - #clock-cells: shall be 1
> +
> +auxclk
> + Describes the AUXCLK output of the PLL. The node name must be "auxclk".
> + This child node is only valid when compatible = "ti,da850-pll0".
> +
> + Required properties:
> + - #clock-cells: shall be 0
> +
> +obsclk
> + Describes the OBSCLK output of the PLL. The node name must be "obsclk".
> +
> + Required properties:
> + - #clock-cells: shall be 0
So why have all these child nodes vs. just defining a single number
space of clock ids?
Rob
On Sat, Jan 20, 2018 at 11:13:56AM -0600, David Lechner wrote:
> This adds a new binding for the clocks present in the CFGCHIP syscon
> registers in TI DA8XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
>
> v6 changes:
> - combine "dt-bindings: clock: Add bindings for DA8XX CFGCHIP gate clocks",
> "dt-bindings: clock: Add binding for TI DA8XX CFGCHIP mux clocks" and
> "dt-bindings: clock: Add bindings for TI DA8XX USB PHY clocks" into a single
> file containing all CFGCHIP clocks bindings
> - added compatible = "ti,da830-div4p5ena"
> - added compatible = "ti,da850-async1-clksrc"
> - renamed other compatible strings
> - changed and added some clk-names strings
> - USB PHY clocks are combined into a single node with #clock-cells = <1>
>
> .../bindings/clock/ti/davinci/da8xx-cfgchip.txt | 93 ++++++++++++++++++++++
> 1 file changed, 93 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/ti/davinci/da8xx-cfgchip.txt
Reviewed-by: Rob Herring <[email protected]>
On 01/29/2018 01:53 PM, Rob Herring wrote:
> On Sat, Jan 20, 2018 at 11:13:40AM -0600, David Lechner wrote:
>> This adds a new binding for the PLL IP blocks in the mach-davinci
>> family of processors. Currently, only da850 has device tree support
>> but these bindings can also work for other SoCs in this family just
>> by adding new compatible strings.
>>
>> 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 <[email protected]>
>> ---
>>
>> v6 changes:
>> - Added clock-names property
>> - Added ti,clkmode-square-wave property
>> - Added pllout child node
>> - Added obsclk child node
>> - Expanded examples
>>
>> .../devicetree/bindings/clock/ti/davinci/pll.txt | 96 ++++++++++++++++++++++
>> 1 file changed, 96 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..36998e1
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
>> @@ -0,0 +1,96 @@
>> +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: phandles corresponding to the clock names
>> +- clock-names: names of the clock sources - depends on compatible string
>> + - for "ti,da850-pll0", shall be "clksrc", "extclksrc"
>> + - for "ti,da850-pll1", shall be "clksrc"
>> +
>> +Optional properties:
>> +- ti,clkmode-square-wave: Indicates that the the board is supplying a square
>> + wave input on the OSCIN pin instead of using a crystal oscillator.
>> + This property is only valid when compatible = "ti,da850-pll0".
>> +
>> +
>> +Optional child nodes:
>> +
>> +pllout
>> + Describes the main PLL clock output (before POSTDIV). The node name must
>> + be "pllout".
>> +
>> + Required properties:
>> + - #clock-cells: shall be 0
>> +
>> +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 index parameter for the clock cell.
>> +
>> + Required properties:
>> + - #clock-cells: shall be 1
>> +
>> +auxclk
>> + Describes the AUXCLK output of the PLL. The node name must be "auxclk".
>> + This child node is only valid when compatible = "ti,da850-pll0".
>> +
>> + Required properties:
>> + - #clock-cells: shall be 0
>> +
>> +obsclk
>> + Describes the OBSCLK output of the PLL. The node name must be "obsclk".
>> +
>> + Required properties:
>> + - #clock-cells: shall be 0
>
> So why have all these child nodes vs. just defining a single number
> space of clock ids?
>
> Rob
>
I think that it makes the bindings more self-documenting. Not all PLLs have
all of possible types of output clocks, so the presence or absence of a
child node indicates if a PLL actually has that output or not.
It is also complicated by the fact that one of the child nodes (sysclk)
is already an array of clocks.
To do what you are suggesting might look something like this...
---
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: phandles corresponding to the clock names
- clock-names: names of the clock sources - depends on compatible string
- for "ti,da850-pll0", shall be "clksrc", "extclksrc"
- for "ti,da850-pll1", shall be "clksrc"
- #clock-cells: shall be set to <2>.
Consumers:
The clock cell values for consumers work as follows...
The first index is one of the constants defined in ti-davinci-pll.h
The second index is 0 unless the first index is TI_DAVINCI_SYSCLK. In the case
of TI_DAVINCI_SYSCLK the second index the SYSCLK domain ID (n in SYSCLKn).
For compatible = "ti,da850-pll0":
- <&pll0 TI_DAVINCI_PLLOUT 0> is the PLLOUT clock
- <&pll0 TI_DAVINCI_SYSCLK n> is one of the SYSCLKn clock domains where n is 1 to 7
- <&pll0 TI_DAVINCI_AUXCLK 0> is the AUXCLK clock domain
- <&pll0 TI_DAVINCI_OBSCLK 0> is the OBSCLK clock domain
- all other index combinations are invalid
For compatible = "ti,da850-pll1":
- <&pll0 TI_DAVINCI_SYSCLK n> is one of the SYSCLKn clock domains where n is 1 to 3
- <&pll0 TI_DAVINCI_OBSCLK 0> is the OBSCLK clock domain
- all other index combinations are invalid
---
I guess it is not too bad (writing a clock lookup function that knows
all of these rules could get interesting though).
On Mon, Jan 29, 2018 at 3:14 PM, David Lechner <[email protected]> wrote:
> On 01/29/2018 01:53 PM, Rob Herring wrote:
>>
>> On Sat, Jan 20, 2018 at 11:13:40AM -0600, David Lechner wrote:
>>>
>>> This adds a new binding for the PLL IP blocks in the mach-davinci
>>> family of processors. Currently, only da850 has device tree support
>>> but these bindings can also work for other SoCs in this family just
>>> by adding new compatible strings.
>>>
>>> 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 <[email protected]>
>>> ---
>>>
>>> v6 changes:
>>> - Added clock-names property
>>> - Added ti,clkmode-square-wave property
>>> - Added pllout child node
>>> - Added obsclk child node
>>> - Expanded examples
>>>
>>> .../devicetree/bindings/clock/ti/davinci/pll.txt | 96
>>> ++++++++++++++++++++++
>>> 1 file changed, 96 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..36998e1
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
>>> @@ -0,0 +1,96 @@
>>> +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: phandles corresponding to the clock names
>>> +- clock-names: names of the clock sources - depends on compatible string
>>> + - for "ti,da850-pll0", shall be "clksrc", "extclksrc"
>>> + - for "ti,da850-pll1", shall be "clksrc"
>>> +
>>> +Optional properties:
>>> +- ti,clkmode-square-wave: Indicates that the the board is supplying a
>>> square
>>> + wave input on the OSCIN pin instead of using a crystal
>>> oscillator.
>>> + This property is only valid when compatible = "ti,da850-pll0".
>>> +
>>> +
>>> +Optional child nodes:
>>> +
>>> +pllout
>>> + Describes the main PLL clock output (before POSTDIV). The node
>>> name must
>>> + be "pllout".
>>> +
>>> + Required properties:
>>> + - #clock-cells: shall be 0
>>> +
>>> +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 index parameter for the clock cell.
>>> +
>>> + Required properties:
>>> + - #clock-cells: shall be 1
>>> +
>>> +auxclk
>>> + Describes the AUXCLK output of the PLL. The node name must be
>>> "auxclk".
>>> + This child node is only valid when compatible = "ti,da850-pll0".
>>> +
>>> + Required properties:
>>> + - #clock-cells: shall be 0
>>> +
>>> +obsclk
>>> + Describes the OBSCLK output of the PLL. The node name must be
>>> "obsclk".
>>> +
>>> + Required properties:
>>> + - #clock-cells: shall be 0
>>
>>
>> So why have all these child nodes vs. just defining a single number
>> space of clock ids?
>>
>> Rob
>>
>
> I think that it makes the bindings more self-documenting. Not all PLLs have
> all of possible types of output clocks, so the presence or absence of a
> child node indicates if a PLL actually has that output or not.
Doesn't the compatible string do that?
> It is also complicated by the fact that one of the child nodes (sysclk)
> is already an array of clocks.
>
> To do what you are suggesting might look something like this...
>
> ---
>
> 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: phandles corresponding to the clock names
> - clock-names: names of the clock sources - depends on compatible string
> - for "ti,da850-pll0", shall be "clksrc", "extclksrc"
> - for "ti,da850-pll1", shall be "clksrc"
> - #clock-cells: shall be set to <2>.
>
> Consumers:
>
> The clock cell values for consumers work as follows...
>
> The first index is one of the constants defined in ti-davinci-pll.h
>
> The second index is 0 unless the first index is TI_DAVINCI_SYSCLK. In the
> case
> of TI_DAVINCI_SYSCLK the second index the SYSCLK domain ID (n in SYSCLKn).
>
> For compatible = "ti,da850-pll0":
> - <&pll0 TI_DAVINCI_PLLOUT 0> is the PLLOUT clock
> - <&pll0 TI_DAVINCI_SYSCLK n> is one of the SYSCLKn clock domains
> where n is 1 to 7
> - <&pll0 TI_DAVINCI_AUXCLK 0> is the AUXCLK clock domain
> - <&pll0 TI_DAVINCI_OBSCLK 0> is the OBSCLK clock domain
> - all other index combinations are invalid
>
> For compatible = "ti,da850-pll1":
> - <&pll0 TI_DAVINCI_SYSCLK n> is one of the SYSCLKn clock domains
> where n is 1 to 3
> - <&pll0 TI_DAVINCI_OBSCLK 0> is the OBSCLK clock domain
> - all other index combinations are invalid
You don't really need 2 cells here. I guess if you want to keep the
child nodes, that is fine.
Rob
On 01/30/2018 08:50 AM, Rob Herring wrote:
> On Mon, Jan 29, 2018 at 3:14 PM, David Lechner <[email protected]> wrote:
>> On 01/29/2018 01:53 PM, Rob Herring wrote:
>>>
>>> On Sat, Jan 20, 2018 at 11:13:40AM -0600, David Lechner wrote:
>>>>
>>>> This adds a new binding for the PLL IP blocks in the mach-davinci
>>>> family of processors. Currently, only da850 has device tree support
>>>> but these bindings can also work for other SoCs in this family just
>>>> by adding new compatible strings.
>>>>
>>>> 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 <[email protected]>
>>>> ---
>>>>
>>>> v6 changes:
>>>> - Added clock-names property
>>>> - Added ti,clkmode-square-wave property
>>>> - Added pllout child node
>>>> - Added obsclk child node
>>>> - Expanded examples
>>>>
>>>> .../devicetree/bindings/clock/ti/davinci/pll.txt | 96
>>>> ++++++++++++++++++++++
>>>> 1 file changed, 96 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..36998e1
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
>>>> @@ -0,0 +1,96 @@
>>>> +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: phandles corresponding to the clock names
>>>> +- clock-names: names of the clock sources - depends on compatible string
>>>> + - for "ti,da850-pll0", shall be "clksrc", "extclksrc"
>>>> + - for "ti,da850-pll1", shall be "clksrc"
>>>> +
>>>> +Optional properties:
>>>> +- ti,clkmode-square-wave: Indicates that the the board is supplying a
>>>> square
>>>> + wave input on the OSCIN pin instead of using a crystal
>>>> oscillator.
>>>> + This property is only valid when compatible = "ti,da850-pll0".
>>>> +
>>>> +
>>>> +Optional child nodes:
>>>> +
>>>> +pllout
>>>> + Describes the main PLL clock output (before POSTDIV). The node
>>>> name must
>>>> + be "pllout".
>>>> +
>>>> + Required properties:
>>>> + - #clock-cells: shall be 0
>>>> +
>>>> +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 index parameter for the clock cell.
>>>> +
>>>> + Required properties:
>>>> + - #clock-cells: shall be 1
>>>> +
>>>> +auxclk
>>>> + Describes the AUXCLK output of the PLL. The node name must be
>>>> "auxclk".
>>>> + This child node is only valid when compatible = "ti,da850-pll0".
>>>> +
>>>> + Required properties:
>>>> + - #clock-cells: shall be 0
>>>> +
>>>> +obsclk
>>>> + Describes the OBSCLK output of the PLL. The node name must be
>>>> "obsclk".
>>>> +
>>>> + Required properties:
>>>> + - #clock-cells: shall be 0
>>>
>>>
>>> So why have all these child nodes vs. just defining a single number
>>> space of clock ids?
>>>
>>> Rob
>>>
>>
>> I think that it makes the bindings more self-documenting. Not all PLLs have
>> all of possible types of output clocks, so the presence or absence of a
>> child node indicates if a PLL actually has that output or not.
>
> Doesn't the compatible string do that?
Sure.
>
>> It is also complicated by the fact that one of the child nodes (sysclk)
>> is already an array of clocks.
>>
>> To do what you are suggesting might look something like this...
>>
>> ---
>>
>> 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: phandles corresponding to the clock names
>> - clock-names: names of the clock sources - depends on compatible string
>> - for "ti,da850-pll0", shall be "clksrc", "extclksrc"
>> - for "ti,da850-pll1", shall be "clksrc"
>> - #clock-cells: shall be set to <2>.
>>
>> Consumers:
>>
>> The clock cell values for consumers work as follows...
>>
>> The first index is one of the constants defined in ti-davinci-pll.h
>>
>> The second index is 0 unless the first index is TI_DAVINCI_SYSCLK. In the
>> case
>> of TI_DAVINCI_SYSCLK the second index the SYSCLK domain ID (n in SYSCLKn).
>>
>> For compatible = "ti,da850-pll0":
>> - <&pll0 TI_DAVINCI_PLLOUT 0> is the PLLOUT clock
>> - <&pll0 TI_DAVINCI_SYSCLK n> is one of the SYSCLKn clock domains
>> where n is 1 to 7
>> - <&pll0 TI_DAVINCI_AUXCLK 0> is the AUXCLK clock domain
>> - <&pll0 TI_DAVINCI_OBSCLK 0> is the OBSCLK clock domain
>> - all other index combinations are invalid
>>
>> For compatible = "ti,da850-pll1":
>> - <&pll0 TI_DAVINCI_SYSCLK n> is one of the SYSCLKn clock domains
>> where n is 1 to 3
>> - <&pll0 TI_DAVINCI_OBSCLK 0> is the OBSCLK clock domain
>> - all other index combinations are invalid
>
> You don't really need 2 cells here. I guess if you want to keep the
> child nodes, that is fine.
OK, I can see how it could work with one cell.
Since this is already implemented and working, I'm inclined to leave it
as-is if it is "good enough". But, I am fine going either way if there
are other opinions on the matter.
On Wednesday 31 January 2018 12:16 AM, David Lechner wrote:
> On 01/30/2018 08:50 AM, Rob Herring wrote:
>> On Mon, Jan 29, 2018 at 3:14 PM, David Lechner <[email protected]>
>> wrote:
>>> On 01/29/2018 01:53 PM, Rob Herring wrote:
>>>>
>>>> On Sat, Jan 20, 2018 at 11:13:40AM -0600, David Lechner wrote:
>>>>>
>>>>> This adds a new binding for the PLL IP blocks in the mach-davinci
>>>>> family of processors. Currently, only da850 has device tree support
>>>>> but these bindings can also work for other SoCs in this family just
>>>>> by adding new compatible strings.
>>>>>
>>>>> 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 <[email protected]>
>>>>> ---
>>>>>
>>>>> v6 changes:
>>>>> - Added clock-names property
>>>>> - Added ti,clkmode-square-wave property
>>>>> - Added pllout child node
>>>>> - Added obsclk child node
>>>>> - Expanded examples
>>>>>
>>>>> .../devicetree/bindings/clock/ti/davinci/pll.txt | 96
>>>>> ++++++++++++++++++++++
>>>>> 1 file changed, 96 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..36998e1
>>>>> --- /dev/null
>>>>> +++ b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
>>>>> @@ -0,0 +1,96 @@
>>>>> +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: phandles corresponding to the clock names
>>>>> +- clock-names: names of the clock sources - depends on compatible
>>>>> string
>>>>> + - for "ti,da850-pll0", shall be "clksrc", "extclksrc"
>>>>> + - for "ti,da850-pll1", shall be "clksrc"
>>>>> +
>>>>> +Optional properties:
>>>>> +- ti,clkmode-square-wave: Indicates that the the board is supplying a
>>>>> square
>>>>> + wave input on the OSCIN pin instead of using a crystal
>>>>> oscillator.
>>>>> + This property is only valid when compatible = "ti,da850-pll0".
>>>>> +
>>>>> +
>>>>> +Optional child nodes:
>>>>> +
>>>>> +pllout
>>>>> + Describes the main PLL clock output (before POSTDIV). The node
>>>>> name must
>>>>> + be "pllout".
>>>>> +
>>>>> + Required properties:
>>>>> + - #clock-cells: shall be 0
>>>>> +
>>>>> +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 index parameter for the clock
>>>>> cell.
>>>>> +
>>>>> + Required properties:
>>>>> + - #clock-cells: shall be 1
>>>>> +
>>>>> +auxclk
>>>>> + Describes the AUXCLK output of the PLL. The node name must be
>>>>> "auxclk".
>>>>> + This child node is only valid when compatible =
>>>>> "ti,da850-pll0".
>>>>> +
>>>>> + Required properties:
>>>>> + - #clock-cells: shall be 0
>>>>> +
>>>>> +obsclk
>>>>> + Describes the OBSCLK output of the PLL. The node name must be
>>>>> "obsclk".
>>>>> +
>>>>> + Required properties:
>>>>> + - #clock-cells: shall be 0
>>>>
>>>>
>>>> So why have all these child nodes vs. just defining a single number
>>>> space of clock ids?
>>>>
>>>> Rob
>>>>
>>>
>>> I think that it makes the bindings more self-documenting. Not all
>>> PLLs have
>>> all of possible types of output clocks, so the presence or absence of a
>>> child node indicates if a PLL actually has that output or not.
>>
>> Doesn't the compatible string do that?
>
> Sure.
>
>>
>>> It is also complicated by the fact that one of the child nodes (sysclk)
>>> is already an array of clocks.
>>>
>>> To do what you are suggesting might look something like this...
>>>
>>> ---
>>>
>>> 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: phandles corresponding to the clock names
>>> - clock-names: names of the clock sources - depends on compatible string
>>> - for "ti,da850-pll0", shall be "clksrc", "extclksrc"
>>> - for "ti,da850-pll1", shall be "clksrc"
>>> - #clock-cells: shall be set to <2>.
>>>
>>> Consumers:
>>>
>>> The clock cell values for consumers work as follows...
>>>
>>> The first index is one of the constants defined in ti-davinci-pll.h
>>>
>>> The second index is 0 unless the first index is TI_DAVINCI_SYSCLK. In
>>> the
>>> case
>>> of TI_DAVINCI_SYSCLK the second index the SYSCLK domain ID (n in
>>> SYSCLKn).
>>>
>>> For compatible = "ti,da850-pll0":
>>> - <&pll0 TI_DAVINCI_PLLOUT 0> is the PLLOUT clock
>>> - <&pll0 TI_DAVINCI_SYSCLK n> is one of the SYSCLKn clock
>>> domains
>>> where n is 1 to 7
>>> - <&pll0 TI_DAVINCI_AUXCLK 0> is the AUXCLK clock domain
>>> - <&pll0 TI_DAVINCI_OBSCLK 0> is the OBSCLK clock domain
>>> - all other index combinations are invalid
>>>
>>> For compatible = "ti,da850-pll1":
>>> - <&pll0 TI_DAVINCI_SYSCLK n> is one of the SYSCLKn clock
>>> domains
>>> where n is 1 to 3
>>> - <&pll0 TI_DAVINCI_OBSCLK 0> is the OBSCLK clock domain
>>> - all other index combinations are invalid
>>
>> You don't really need 2 cells here. I guess if you want to keep the
>> child nodes, that is fine.
>
> OK, I can see how it could work with one cell.
>
> Since this is already implemented and working, I'm inclined to leave it
> as-is if it is "good enough". But, I am fine going either way if there
> are other opinions on the matter.
FWIW, I think the current binding is fine too. The clocks are of
different kind (fixed clock, fixed divider, flexible divider etc). So,
its slightly better to have child nodes, I guess.
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, 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 <[email protected]>
Looks nice and clean to me. There is still some feedback though.
One thing missing is DIV4.5 clock. It will be nice to add that too,
mostly just because it will make the binding complete.
> +void of_davinci_pll_init(struct device_node *node,
> + const struct davinci_pll_clk_info *info,
> + const struct davinci_pll_obsclk_info *obsclk_info,
> + const struct davinci_pll_sysclk_info *div_info,
> + u8 max_sysclk_id)
> +{
> + struct device_node *child;
> + const char *parent_name;
> + void __iomem *base;
> + struct clk *clk;
> +
> + base = of_iomap(node, 0);
> + if (!base) {
> + pr_err("ioremap failed");
> + return;
> + }
> +
> + if (info->flags & PLL_HAS_OSCIN)
> + parent_name = of_clk_get_parent_name(node, 0);
> + else
> + parent_name = OSCIN_CLK_NAME;
I don't think the reference clock input handling is fully correct/flexible.
There are two ways to provide input clock (ref_clk) to PLL. Either use
the internal oscillator with a crystal connected between OSCIN and
OSCOUT (CLKMODE = 0) or a clean clock input (CLKMODE = 1) connected to
OSCIN (OSCOUT disconnected).
This is a board specific decision. On the LogicPD EVM, the former option
is used, on the LCDK board, the later.
So, I think what we need is a DT property like
"ti,davinci-use-internal-osc" for the PLL. Boards can set or ignore it
and you can switch CLKMODE on or off based on that.
Setting CLKMODE = 1 will switch off the internal oscillator (and
presumably save power), but it does not act as a mux. This explains why
not worrying about setting this correctly in current mainline still works.
I am also not sure if we really need PLL_HAS_OSCIN since all DaVinci
SoCs set it anyway.
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> This adds platform-specific declarations for the PLL clocks on TI DA830/
> OMAP-L137/AM17XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> This adds platform-specific declarations for the PLL clocks on TI DA850/
> OMAP-L138/AM18XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
> +static const struct davinci_pll_clk_info da850_pll1_info __initconst = {
> + .name = "pll1",
> + .unlock_reg = CFGCHIP(3),
> + .unlock_mask = CFGCHIP3_PLL1_MASTER_LOCK,
I guess this will change with the cfgchip handling discussion last week.
> + .pllm_mask = GENMASK(4, 0),
> + .pllm_min = 4,
> + .pllm_max = 32,
> + .pllout_min_rate = 300000000,
> + .pllout_max_rate = 600000000,
> + .flags = PLL_HAS_POSTDIV,
> +};
> +
[...]
> +void __init da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1)
> +{
> + const struct davinci_pll_sysclk_info *info;
> +
> + davinci_pll_clk_register(&da850_pll0_info, "ref_clk", pll0);
> +
> + davinci_pll_auxclk_register("pll0_auxclk", pll0);
> +
> + for (info = da850_pll0_sysclk_info; info->name; info++)
> + davinci_pll_sysclk_register(info, pll0);
> +
> + davinci_pll_obsclk_register(&da850_pll0_obsclk_info, pll0);
> +
> + davinci_pll_clk_register(&da850_pll1_info, "oscin", pll1);
Both PLL0 and PLL1 use the same reference clock. So this should be
"ref_clk". I dont think we ever need to register a clock called oscin
along with "ref_clk". There is only one reference clock. It can either
be obtained using internal oscillator or external oscillator.
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> +void __init dm355_pll_clk_init(void __iomem *pll1, void __iomem *pll2)
> +{
> + const struct davinci_pll_sysclk_info *info;
> +
> + davinci_pll_clk_register(&dm355_pll1_info, "ref_clk", pll1);
> +
> + for (info = dm355_pll1_sysclk_info; info->name; info++)
> + davinci_pll_sysclk_register(info, pll1);
> +
> + davinci_pll_auxclk_register("pll1_auxclk", pll1);
> +
> + davinci_pll_sysclkbp_clk_register("pll1_sysclkbp", pll1);
> +
> + davinci_pll_clk_register(&dm355_pll2_info, "oscin", pll2);
Even on DM355, both PLLs accept reference clock from the same input. So
this can be "ref_clk" as well.
Rest of it looks good to me (and thanks for looking up the data manual
for accurate PLLM max and min settings).
Regards,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> +
> +void __init dm365_pll_clk_init(void __iomem *pll1, void __iomem *pll2)
> +{
> + const struct davinci_pll_sysclk_info *info;
> +
> + davinci_pll_clk_register(&dm365_pll1_info, "ref_clk", pll1);
> +
> + davinci_pll_auxclk_register("pll1_auxclk", pll1);
> +
> + davinci_pll_sysclkbp_clk_register("pll1_sysclkbp", pll1);
> +
> + davinci_pll_obsclk_register(&dm365_pll1_obsclk_info, pll1);
> +
> + for (info = dm365_pll1_sysclk_info; info->name; info++)
> + davinci_pll_sysclk_register(info, pll1);
> +
> + davinci_pll_clk_register(&dm365_pll2_info, "oscin", pll2);
As pointed out in other patches, I think we can remove "oscin" here and
also get rid of clk_register_fixed_factor() for oscin in
davinci_pll_clk_register().
Rest of the patch looks good to me.
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, 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 <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> This adds platform-specific declarations for the PSC clocks on TI DA830/
> OMAP-L137/AM17XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> This adds platform-specific declarations for the PSC clocks on TI DA850/
> OMAP-L138/AM18XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> + LPSC(26, 0, gpio, pll1_sysclk2, gpio_clkdev, 0),
> + LPSC(27, 0, timer0, pll1_auxclk, timer0_clkdev, 0),
> + LPSC(28, 0, timer1, pll1_auxclk, NULL, 0),
> + /* REVISIT: why can't this be disabled? */
> + LPSC(29, 0, timer2, pll1_auxclk, timer2_clkdev,
> + LPSC_ALWAYS_ENABLED),
> + LPSC(31, 0, arm, pll1_sysclk1, NULL,
> + LPSC_ALWAYS_ENABLED),
IMO, in this case the line break makes it more difficult to read so that
checkpatch warning should be ignored.
Thanks
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> This adds platform-specific declarations for the PSC clocks on TI
> DM365 based systems.
>
> Signed-off-by: David Lechner <[email protected]>
Apart from comment given on 13/41 that applies here:
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> This adds platform-specific declarations for the PSC clocks on TI
> DM644x based systems.
>
> Signed-off-by: David Lechner <[email protected]>
Apart from a comment given on similar file:
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> This adds platform-specific declarations for the PSC clocks on TI
> DM646x based systems.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Thursday 01 February 2018 01:31 PM, Sekhar Nori wrote:
> One thing missing is DIV4.5 clock. It will be nice to add that too,
> mostly just because it will make the binding complete.
Ah, ignore this comment please. I noticed that its part of cfgchip
clocks (which makes sense).
Thanks,
Sekhar
On 02/01/2018 02:58 AM, Sekhar Nori wrote:
> On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
>> This adds platform-specific declarations for the PLL clocks on TI DA850/
>> OMAP-L138/AM18XX SoCs.
>>
>> Signed-off-by: David Lechner <[email protected]>
>
>> +static const struct davinci_pll_clk_info da850_pll1_info __initconst = {
>> + .name = "pll1",
>> + .unlock_reg = CFGCHIP(3),
>> + .unlock_mask = CFGCHIP3_PLL1_MASTER_LOCK,
>
> I guess this will change with the cfgchip handling discussion last week.
Actually no, there really weren't any changes to the clock drivers because
of this change. Only a small change in mach-davinci.
>
>> + .pllm_mask = GENMASK(4, 0),
>> + .pllm_min = 4,
>> + .pllm_max = 32,
>> + .pllout_min_rate = 300000000,
>> + .pllout_max_rate = 600000000,
>> + .flags = PLL_HAS_POSTDIV,
>> +};
>> +
>
> [...]
>
>> +void __init da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1)
>> +{
>> + const struct davinci_pll_sysclk_info *info;
>> +
>> + davinci_pll_clk_register(&da850_pll0_info, "ref_clk", pll0);
>> +
>> + davinci_pll_auxclk_register("pll0_auxclk", pll0);
>> +
>> + for (info = da850_pll0_sysclk_info; info->name; info++)
>> + davinci_pll_sysclk_register(info, pll0);
>> +
>> + davinci_pll_obsclk_register(&da850_pll0_obsclk_info, pll0);
>> +
>> + davinci_pll_clk_register(&da850_pll1_info, "oscin", pll1);
>
> Both PLL0 and PLL1 use the same reference clock. So this should be
> "ref_clk". I dont think we ever need to register a clock called oscin
> along with "ref_clk". There is only one reference clock. It can either
> be obtained using internal oscillator or external oscillator.
>
As per my response to the previous path, this depends on which both
which SoC and which diagram in the TRM for that SoC you are looking at.
It works either way.
On 01/20/2018 11:13 AM, David Lechner wrote:
> This adds platform-specific declarations for the PLL clocks on TI DA850/
> OMAP-L138/AM18XX SoCs.
>
> Signed-off-by: David Lechner <[email protected]>
> ---
>
> v6 changes:
> - Added da850_pll{0,1}_info with controller-specific information
> - Added OBSCLK data
> - Add empty lines between function calls
>
> drivers/clk/davinci/Makefile | 1 +
> drivers/clk/davinci/pll-da850.c | 163 ++++++++++++++++++++++++++++++++++++++++
> include/linux/clk/davinci.h | 1 +
> 3 files changed, 165 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..a94e1a6
> --- /dev/null
> +++ b/drivers/clk/davinci/pll-da850.c
> @@ -0,0 +1,163 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PLL clock descriptions for TI DA850/OMAP-L138/AM18XX
> + *
> + * Copyright (C) 2018 David Lechner <[email protected]>
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/da8xx-cfgchip.h>
> +#include <linux/of.h>
> +#include <linux/types.h>
> +
> +#include "pll.h"
> +
> +#define OCSEL_OCSRC_OSCIN 0x14
> +#define OCSEL_OCSRC_PLL0_SYSCLK(n) (0x16 + (n))
> +#define OCSEL_OCSRC_PLL1_OBSCLK 0x1e
> +#define OCSEL_OCSRC_PLL1_SYSCLK(n) (0x16 + (n))
> +
> +static const struct davinci_pll_clk_info da850_pll0_info __initconst = {
> + .name = "pll0",
> + .unlock_reg = CFGCHIP(0),
> + .unlock_mask = CFGCHIP0_PLL_MASTER_LOCK,
> + .pllm_mask = GENMASK(4, 0),
> + .pllm_min = 4,
> + .pllm_max = 32,
> + .pllout_min_rate = 300000000,
> + .pllout_max_rate = 600000000,
> + .flags = PLL_HAS_OSCIN | PLL_HAS_PREDIV | PLL_HAS_POSTDIV |
> + PLL_HAS_EXTCLKSRC,
> +};
> +
> +/*
> + * NB: Technically, the clocks flagged as SYSCLK_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_sysclk_info da850_pll0_sysclk_info[] __initconst = {
> + SYSCLK(1, pll0_sysclk1, pll0_pllen, 5, SYSCLK_FIXED_DIV),
> + SYSCLK(2, pll0_sysclk2, pll0_pllen, 5, SYSCLK_FIXED_DIV),
> + SYSCLK(3, pll0_sysclk3, pll0_pllen, 5, 0),
> + SYSCLK(4, pll0_sysclk4, pll0_pllen, 5, SYSCLK_FIXED_DIV),
> + SYSCLK(5, pll0_sysclk5, pll0_pllen, 5, 0),
> + SYSCLK(6, pll0_sysclk6, pll0_pllen, 5, SYSCLK_ARM_RATE | SYSCLK_FIXED_DIV),
> + SYSCLK(7, pll0_sysclk7, pll0_pllen, 5, 0),
> + { }
> +};
> +
> +static const char * const da850_pll0_obsclk_parent_names[] __initconst = {
> + "oscin",
> + "pll0_sysclk1",
> + "pll0_sysclk2",
> + "pll0_sysclk3",
> + "pll0_sysclk4",
> + "pll0_sysclk5",
> + "pll0_sysclk6",
> + "pll0_sysclk7",
> + "pll1_obsclk",
> +};
> +
> +static u32 da850_pll0_obsclk_table[] = {
> + OCSEL_OCSRC_OSCIN,
> + OCSEL_OCSRC_PLL0_SYSCLK(1),
> + OCSEL_OCSRC_PLL0_SYSCLK(2),
> + OCSEL_OCSRC_PLL0_SYSCLK(3),
> + OCSEL_OCSRC_PLL0_SYSCLK(4),
> + OCSEL_OCSRC_PLL0_SYSCLK(5),
> + OCSEL_OCSRC_PLL0_SYSCLK(6),
> + OCSEL_OCSRC_PLL0_SYSCLK(7),
> + OCSEL_OCSRC_PLL1_OBSCLK,
> +};
> +
> +static const struct davinci_pll_obsclk_info da850_pll0_obsclk_info __initconst = {
> + .name = "pll0_obsclk",
> + .parent_names = da850_pll0_obsclk_parent_names,
> + .num_parents = ARRAY_SIZE(da850_pll0_obsclk_parent_names),
> + .table = da850_pll0_obsclk_table,
> + .ocsrc_mask = GENMASK(4, 0),
> +};
> +
> +static const struct davinci_pll_clk_info da850_pll1_info __initconst = {
> + .name = "pll1",
> + .unlock_reg = CFGCHIP(3),
> + .unlock_mask = CFGCHIP3_PLL1_MASTER_LOCK,
> + .pllm_mask = GENMASK(4, 0),
> + .pllm_min = 4,
> + .pllm_max = 32,
> + .pllout_min_rate = 300000000,
> + .pllout_max_rate = 600000000,
> + .flags = PLL_HAS_POSTDIV,
> +};
> +
> +static const struct davinci_pll_sysclk_info da850_pll1_sysclk_info[] __initconst = {
> + SYSCLK(1, pll1_sysclk1, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED),
> + SYSCLK(2, pll1_sysclk2, pll1_pllen, 5, 0),
> + SYSCLK(3, pll1_sysclk3, pll1_pllen, 5, 0),
> + { }
> +};
> +
> +static const char * const da850_pll1_obsclk_parent_names[] __initconst = {
> + "oscin",
Re: the issue of "ref_clk" vs. "oscin"...
This is one of the places where having the otherwise unnecessary "oscin" clock
really helps out. The PLL driver doesn't control "ref_clk" - it comes from somewhere
else. And in the case of DT, it may not even be named "ref_clk", so we really
don't want to hard-code the name "ref_clk" here.
If we have to allow a variable name here, it just makes more work in the driver
shuffling names around.
And the name "oscin" totally makes sense here because the TRM lists this input to the
mux as "OSCIN".
> + "pll1_sysclk1",
> + "pll1_sysclk2",
> + "pll1_sysclk3",
> +};
> +
> +static u32 da850_pll1_obsclk_table[] = {
> + OCSEL_OCSRC_OSCIN,
> + OCSEL_OCSRC_PLL1_SYSCLK(1),
> + OCSEL_OCSRC_PLL1_SYSCLK(2),
> + OCSEL_OCSRC_PLL1_SYSCLK(3),
> +};
> +
> +static const struct davinci_pll_obsclk_info da850_pll1_obsclk_info __initconst = {
> + .name = "pll1_obsclk",
> + .parent_names = da850_pll1_obsclk_parent_names,
> + .num_parents = ARRAY_SIZE(da850_pll1_obsclk_parent_names),
> + .table = da850_pll1_obsclk_table,
> + .ocsrc_mask = GENMASK(4, 0),
> +};
> +
> +void __init da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1)
> +{
> + const struct davinci_pll_sysclk_info *info;
> +
> + davinci_pll_clk_register(&da850_pll0_info, "ref_clk", pll0);
And really, we probably shouldn't be hard-coding "ref_clk" here either.
Basically, we are making the assumption that the board file has registered
a clock named "ref_clk". It would probably be better to pass the name
as a parameter.
> +
> + davinci_pll_auxclk_register("pll0_auxclk", pll0);
> +
> + for (info = da850_pll0_sysclk_info; info->name; info++)
> + davinci_pll_sysclk_register(info, pll0);
> +
> + davinci_pll_obsclk_register(&da850_pll0_obsclk_info, pll0);
> +
> + davinci_pll_clk_register(&da850_pll1_info, "oscin", pll1);
> +
> + for (info = da850_pll1_sysclk_info; info->name; info++)
> + davinci_pll_sysclk_register(info, pll1);
> +
> + davinci_pll_obsclk_register(&da850_pll1_obsclk_info, pll1);
> +}
> +
> +#ifdef CONFIG_OF
> +static void __init of_da850_pll0_auxclk_init(struct device_node *node)
> +{
> + of_davinci_pll_init(node, &da850_pll0_info, &da850_pll0_obsclk_info,
> + da850_pll0_sysclk_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, &da850_pll1_info, &da850_pll1_obsclk_info,
> + da850_pll1_sysclk_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__ */
>
On 02/01/2018 02:01 AM, Sekhar Nori wrote:
> On Saturday 20 January 2018 10:43 PM, 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 <[email protected]>
>
> Looks nice and clean to me. There is still some feedback though.
>
> One thing missing is DIV4.5 clock. It will be nice to add that too,
> mostly just because it will make the binding complete.
>
>> +void of_davinci_pll_init(struct device_node *node,
>> + const struct davinci_pll_clk_info *info,
>> + const struct davinci_pll_obsclk_info *obsclk_info,
>> + const struct davinci_pll_sysclk_info *div_info,
>> + u8 max_sysclk_id)
>> +{
>> + struct device_node *child;
>> + const char *parent_name;
>> + void __iomem *base;
>> + struct clk *clk;
>> +
>> + base = of_iomap(node, 0);
>> + if (!base) {
>> + pr_err("ioremap failed");
>> + return;
>> + }
>> +
>> + if (info->flags & PLL_HAS_OSCIN)
>> + parent_name = of_clk_get_parent_name(node, 0);
>> + else
>> + parent_name = OSCIN_CLK_NAME;
>
> I don't think the reference clock input handling is fully correct/flexible.
>
> There are two ways to provide input clock (ref_clk) to PLL. Either use
> the internal oscillator with a crystal connected between OSCIN and
> OSCOUT (CLKMODE = 0) or a clean clock input (CLKMODE = 1) connected to
> OSCIN (OSCOUT disconnected).
>
> This is a board specific decision. On the LogicPD EVM, the former option
> is used, on the LCDK board, the later.
>
> So, I think what we need is a DT property like
> "ti,davinci-use-internal-osc" for the PLL. Boards can set or ignore it
> and you can switch CLKMODE on or off based on that.
>
> Setting CLKMODE = 1 will switch off the internal oscillator (and
> presumably save power), but it does not act as a mux. This explains why
> not worrying about setting this correctly in current mainline still works.
>
> I am also not sure if we really need PLL_HAS_OSCIN since all DaVinci
> SoCs set it anyway.
I realize this is a bit confusing. I think that part of this comes from
the fact that OSCIN is not used consistently in the TRMs. It is used as
the name of the actual pin on the SoC for connecting an external clock
signal or crystal. It is also used as an input to CLKMODE where it means
the output of the internal oscillator rather than the external pin (some
SoCs show CLKMODE as a mux with OSCIN and CLKIN, but I agree that it is
not really a mux since OSCIN and CLKIN are the same external pin on the
SoC - then other SoCs show OSCIN meaning only the external pin here).
Furthermore, OSCIN is listed as one of the inputs of EXTCLKSRC also as
one of the inputs of OBSCLK on da850-type SoCs.
So, the option I went with here is that "ref_clk" is the external clock
connected to the OSCIN pin and that the "oscin" clock is the clock domain
_after_ CLKMODE. This matches the use of OSCIN in the TRMs where "OSCIN"
is used as an input for EXTCLKSRC and OBSCLK. Also the fact that the
external reference clock is sometimes called CLKSRC instead of OSCIN
influenced the decision go with "oscin" being the internal (to the PLL)
clock domain.
I think what I should have done, though, is named PLL_HAS_OSCIN as
PLL_HAS_CLKMODE instead. I think what you are missing here is that
PLL_HAS_OSCIN (or PLL_HAS_CLKMODE) only means that the PLL _has_
PLLCTL[CLKMODE]. It does _not_ mean that we set (or clear) PLLCTL[CLKMODE].
On SoCs with two PLLs, only one of them has the PLLCTL[CLKMODE] bit (and
therefore the PLL_HAS_OSCIN flag) and the output of this is shared by both
PLLs, e.g. Figure 7-1. PLLC Structure in the AM1808 TRM (spruh82c). So,
the clock tree in Linux ends up looking like this:
ref_clk - the external clock - aka CLKSRC
+-oscin - internal clock domain after CLKMODE - shared by both PLLs
+-pll0_extclksrc
+-pll0_prediv
+-pll0_auxclk
+-pll0_obsclk - via the OSCSRC mux
+-pll1_pllen
+-pll1_pllout
+-pll1_obsclk - via the OSCSRC mux
Clocks beyond two levels deep are omitted for brevity.
It should be easy to see the correlation here Figure 7-1 with the
exception that in Figure 7-1 "OSCIN" has the meaning of "the physical
pin on the chip" (which Linux calls "ref_clk") and there is no clear
label in Figure 7-1 of what the clock domain after PLLCTL[CLKMODE] is
called (which Linux calls "oscin").
Sure, it would work just fine if we left "oscin" out of the picture,
but it simplifies the driver implementation by having a known "oscin"
clock that is fully controlled by the clock driver code instead of
having to pass the user-supplied "ref_clk" around a bunch of places.
And, we could try to call it something other than "oscin" to try
to avoid confusion, but then you will just cause confusion in other
places (which could be less total confusion, so I am open to change
here).
---
Switching topics to CLKMODE and DT...
There is a "ti,clkmode-square-wave" property in the proposed DT bindings
that does exactly what you have suggested, except the logic is
reversed. When omitted, it assumes the use of a crystal oscillator.
I believe this is the most common configuration, which is why I made
it the default instead of the other way around.
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> +EMIFA clock source (ASYNC1)
> +---------------------------
> +Required properties:
> +- compatible: shall be "ti,da850-async1-clksrc".
> +- #clock-cells: from common clock binding; shall be set to 0.
> +- clocks: phandles to the parent clocks corresponding to clock-names
> +- clock-names: shall be "pll0_sysclk3", "div4.5"
Is this clock really referred to as aysnc1 in documentation? I don't get
hits for async1 in OMAP-L138 TRM.
Thanks,
Sekhar
On Friday 02 February 2018 12:27 AM, David Lechner wrote:
> On 02/01/2018 02:01 AM, Sekhar Nori wrote:
>> On Saturday 20 January 2018 10:43 PM, 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 <[email protected]>
>>
>> Looks nice and clean to me. There is still some feedback though.
>>
>> One thing missing is DIV4.5 clock. It will be nice to add that too,
>> mostly just because it will make the binding complete.
>>
>>> +void of_davinci_pll_init(struct device_node *node,
>>> + const struct davinci_pll_clk_info *info,
>>> + const struct davinci_pll_obsclk_info *obsclk_info,
>>> + const struct davinci_pll_sysclk_info *div_info,
>>> + u8 max_sysclk_id)
>>> +{
>>> + struct device_node *child;
>>> + const char *parent_name;
>>> + void __iomem *base;
>>> + struct clk *clk;
>>> +
>>> + base = of_iomap(node, 0);
>>> + if (!base) {
>>> + pr_err("ioremap failed");
>>> + return;
>>> + }
>>> +
>>> + if (info->flags & PLL_HAS_OSCIN)
>>> + parent_name = of_clk_get_parent_name(node, 0);
>>> + else
>>> + parent_name = OSCIN_CLK_NAME;
>>
>> I don't think the reference clock input handling is fully
>> correct/flexible.
>>
>> There are two ways to provide input clock (ref_clk) to PLL. Either use
>> the internal oscillator with a crystal connected between OSCIN and
>> OSCOUT (CLKMODE = 0) or a clean clock input (CLKMODE = 1) connected to
>> OSCIN (OSCOUT disconnected).
>>
>> This is a board specific decision. On the LogicPD EVM, the former option
>> is used, on the LCDK board, the later.
>>
>> So, I think what we need is a DT property like
>> "ti,davinci-use-internal-osc" for the PLL. Boards can set or ignore it
>> and you can switch CLKMODE on or off based on that.
>>
>> Setting CLKMODE = 1 will switch off the internal oscillator (and
>> presumably save power), but it does not act as a mux. This explains why
>> not worrying about setting this correctly in current mainline still
>> works.
>>
>> I am also not sure if we really need PLL_HAS_OSCIN since all DaVinci
>> SoCs set it anyway.
>
>
> I realize this is a bit confusing. I think that part of this comes from
> the fact that OSCIN is not used consistently in the TRMs. It is used as
Thats right, I noticed that too. But all SoC datasheets I looked at
supported both internal oscillator and external clock input. Also, no
SoC had different reference clocks for its PLLs (DM355 has two crystal
inputs, but one of them goes only to the video peripheral).
So I still think there is benefit in standardizing on a single name in
kernel/DT (I was hoping it can be "ref_clk").
> the name of the actual pin on the SoC for connecting an external clock
> signal or crystal. It is also used as an input to CLKMODE where it means
> the output of the internal oscillator rather than the external pin (some
> SoCs show CLKMODE as a mux with OSCIN and CLKIN, but I agree that it is
> not really a mux since OSCIN and CLKIN are the same external pin on the
> SoC - then other SoCs show OSCIN meaning only the external pin here).
> Furthermore, OSCIN is listed as one of the inputs of EXTCLKSRC also as
> one of the inputs of OBSCLK on da850-type SoCs.
Right.
> So, the option I went with here is that "ref_clk" is the external clock
> connected to the OSCIN pin and that the "oscin" clock is the clock domain
> _after_ CLKMODE. This matches the use of OSCIN in the TRMs where "OSCIN"
> is used as an input for EXTCLKSRC and OBSCLK. Also the fact that the
> external reference clock is sometimes called CLKSRC instead of OSCIN
> influenced the decision go with "oscin" being the internal (to the PLL)
> clock domain.
Okay, I think we need some comments in code to make this distinction clear.
I do not yet understand why we need to differentiate between the
external-to-chip clock domain from internal "after CLKMODE" domain.
OTOH, I don't see a big harm in doing it either (as long as the
distinction is clear).
>
> I think what I should have done, though, is named PLL_HAS_OSCIN as
> PLL_HAS_CLKMODE instead. I think what you are missing here is that
> PLL_HAS_OSCIN (or PLL_HAS_CLKMODE) only means that the PLL _has_
> PLLCTL[CLKMODE]. It does _not_ mean that we set (or clear) PLLCTL[CLKMODE].
> On SoCs with two PLLs, only one of them has the PLLCTL[CLKMODE] bit (and
> therefore the PLL_HAS_OSCIN flag) and the output of this is shared by both
> PLLs, e.g. Figure 7-1. PLLC Structure in the AM1808 TRM (spruh82c). So,
> the clock tree in Linux ends up looking like this:
I agree with renaming PLL_HAS_OSCIN with PLL_HAS_CLKMODE will be much
clearer.
>
> ref_clk - the external clock - aka CLKSRC
> +-oscin - internal clock domain after CLKMODE - shared by both PLLs
> +-pll0_extclksrc
> +-pll0_prediv
> +-pll0_auxclk
> +-pll0_obsclk - via the OSCSRC mux
> +-pll1_pllen
> +-pll1_pllout
> +-pll1_obsclk - via the OSCSRC mux
>
> Clocks beyond two levels deep are omitted for brevity.
>
> It should be easy to see the correlation here Figure 7-1 with the
> exception that in Figure 7-1 "OSCIN" has the meaning of "the physical
> pin on the chip" (which Linux calls "ref_clk") and there is no clear
> label in Figure 7-1 of what the clock domain after PLLCTL[CLKMODE] is
> called (which Linux calls "oscin").
Yeah, thats why I was not sure why need to make the distinction between
these domains.
> Sure, it would work just fine if we left "oscin" out of the picture,
> but it simplifies the driver implementation by having a known "oscin"
> clock that is fully controlled by the clock driver code instead of
> having to pass the user-supplied "ref_clk" around a bunch of places.
Okay.
> And, we could try to call it something other than "oscin" to try
> to avoid confusion, but then you will just cause confusion in other
> places (which could be less total confusion, so I am open to change
> here).
Calling external clock as "ref_clk" and internal clock domain as "oscin"
is fine. Its the best choice of names given the terminology
inconsistency between TRMs of different devices.
> ---
>
> Switching topics to CLKMODE and DT...
>
> There is a "ti,clkmode-square-wave" property in the proposed DT bindings
> that does exactly what you have suggested, except the logic is
> reversed. When omitted, it assumes the use of a crystal oscillator.
> I believe this is the most common configuration, which is why I made
> it the default instead of the other way around.
This is fine and looks like I missed its existence while making my
suggestion.
Thanks,
Sekhar
On Friday 02 February 2018 12:34 AM, David Lechner wrote:
> On 02/01/2018 02:58 AM, Sekhar Nori wrote:
>> On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
>>> This adds platform-specific declarations for the PLL clocks on TI DA850/
>>> OMAP-L138/AM18XX SoCs.
>>>
>>> Signed-off-by: David Lechner <[email protected]>
>>
>>> +static const struct davinci_pll_clk_info da850_pll1_info __initconst
>>> = {
>>> + .name = "pll1",
>>> + .unlock_reg = CFGCHIP(3),
>>> + .unlock_mask = CFGCHIP3_PLL1_MASTER_LOCK,
>>
>> I guess this will change with the cfgchip handling discussion last week.
>
> Actually no, there really weren't any changes to the clock drivers because
> of this change. Only a small change in mach-davinci.
>
>>
>>> + .pllm_mask = GENMASK(4, 0),
>>> + .pllm_min = 4,
>>> + .pllm_max = 32,
>>> + .pllout_min_rate = 300000000,
>>> + .pllout_max_rate = 600000000,
>>> + .flags = PLL_HAS_POSTDIV,
>>> +};
>>> +
>>
>> [...]
>>
>>> +void __init da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1)
>>> +{
>>> + const struct davinci_pll_sysclk_info *info;
>>> +
>>> + davinci_pll_clk_register(&da850_pll0_info, "ref_clk", pll0);
>>> +
>>> + davinci_pll_auxclk_register("pll0_auxclk", pll0);
>>> +
>>> + for (info = da850_pll0_sysclk_info; info->name; info++)
>>> + davinci_pll_sysclk_register(info, pll0);
>>> +
>>> + davinci_pll_obsclk_register(&da850_pll0_obsclk_info, pll0);
>>> +
>>> + davinci_pll_clk_register(&da850_pll1_info, "oscin", pll1);
>>
>> Both PLL0 and PLL1 use the same reference clock. So this should be
>> "ref_clk". I dont think we ever need to register a clock called oscin
>> along with "ref_clk". There is only one reference clock. It can either
>> be obtained using internal oscillator or external oscillator.
>>
>
> As per my response to the previous path, this depends on which both
> which SoC and which diagram in the TRM for that SoC you are looking at.
> It works either way.
I see the distinction you are making between clock inputs to the two
PLLs now. A comment somewhere (probably in pll.c) should do it.
Thanks,
Sekhar
On Friday 02 February 2018 12:52 AM, David Lechner wrote:
>> +static const char * const da850_pll1_obsclk_parent_names[]
>> __initconst = {
>> + "oscin",
>
> Re: the issue of "ref_clk" vs. "oscin"...
>
> This is one of the places where having the otherwise unnecessary "oscin"
> clock
> really helps out. The PLL driver doesn't control "ref_clk" - it comes
> from somewhere
> else. And in the case of DT, it may not even be named "ref_clk", so we
> really
> don't want to hard-code the name "ref_clk" here.
TBH, I don't really see what is wrong with mandating the name "ref_clk"
as the reference clock name to be provided. And for all board-files and
DTs to supply the same name.
> If we have to allow a variable name here, it just makes more work in the
> driver
> shuffling names around.
>
> And the name "oscin" totally makes sense here because the TRM lists this
> input to the
> mux as "OSCIN".
Fine with me if you feel it simplifies implementation for you (and also
because of the distinction you want to make between the external "before
CLKMODE" clock and internal "after CLKMODE" clock). What I do care about
though is:
a) In the DT case, ability for different boards to provide different
ref_clk frequencies. We never really had this in the legacy board
file way (except some rudimentary support on DM6467T). And its fine
to continue with status quo for board files.
b) In the DT case, ability for board to specify whether it uses the
on-chip oscillator or has an external clean clock provider.
>> +void __init da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1)
>> +{
>> + const struct davinci_pll_sysclk_info *info;
>> +
>> + davinci_pll_clk_register(&da850_pll0_info, "ref_clk", pll0);
>
> And really, we probably shouldn't be hard-coding "ref_clk" here either.
> Basically, we are making the assumption that the board file has registered
> a clock named "ref_clk". It would probably be better to pass the name
> as a parameter.
As I noted before, I am not sure if this level of naming flexibility is
needed. Every board needs to have one anyway. They might as well call it
by the same name.
That said, I wont oppose it either if you decide to have that flexibility.
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> +static const struct clk_ops da8xx_cfgchip_div4p5_clk_ops = {
> + .enable = da8xx_cfgchip_gate_clk_enable,
> + .disable = da8xx_cfgchip_gate_clk_disable,
> + .is_enabled = da8xx_cfgchip_gate_clk_is_enabled,
I assume the reason for not using clk-gate.c is lack of regmap support
there?
> + .recalc_rate = da8xx_cfgchip_div4p5_recalc_rate,
> +};
> +
> +static struct clk * __init
> +da8xx_cfgchip_gate_clk_register(const struct da8xx_cfgchip_gate_clk_info *info,
> + const char *parent_name,
> + struct regmap *regmap)
> +{
> + struct da8xx_cfgchip_gate_clk *gate;
> + struct clk_init_data init;
> +
> + gate = kzalloc(sizeof(*gate), GFP_KERNEL);
> + if (!gate)
> + return ERR_PTR(-ENOMEM);
> +
> + init.name = info->name;
> + if (info->flags & DA8XX_GATE_CLOCK_IS_DIV4P5)
> + init.ops = &da8xx_cfgchip_div4p5_clk_ops;
> + else
> + init.ops = &da8xx_cfgchip_gate_clk_ops;
This will be easier to read using ternary operator, I think. But you
will probably have line breaks.
Thanks,
Sekhar
On Friday 02 February 2018 06:49 PM, Sekhar Nori wrote:
> On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
>> +static const struct clk_ops da8xx_cfgchip_div4p5_clk_ops = {
>> + .enable = da8xx_cfgchip_gate_clk_enable,
>> + .disable = da8xx_cfgchip_gate_clk_disable,
>> + .is_enabled = da8xx_cfgchip_gate_clk_is_enabled,
>
> I assume the reason for not using clk-gate.c is lack of regmap support
> there?
This is rather question for da8xx_cfgchip_gate_clk_ops. Sorry about the
bad context.
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> diff --git a/include/linux/clk/davinci.h b/include/linux/clk/davinci.h
> index 54ea3ff..04b48b3 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;
Its probably better to include clk-provider.h and regmap.h?
Thanks,
Sekhar
On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
> 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);
> +
> + da8xx_register_cfgchip();
> +
> + 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");
Isn't this better done in da830_pll_clk_init() ? I think we can get rid
of the dummy fixed factor clock too and directly use the pll0_auxclk.
That reminds me, is "pll0_aux_clk" above correct, or should it be
"pll0_auxclk" like in da830_pll_clk_init()?
> +
> + clk = clk_register_fixed_factor(NULL, "rmii", "pll0_sysclk7", 0, 1, 1);
> + clk_register_clkdev(clk, "rmii", NULL);
I don't see any driver looking for this clock using con_id "rmii". I
know this came from existing code. But its most likely a vestige and can
be dropped.
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> void __init da850_init_time(void)
> {
> +#ifdef CONFIG_COMMON_CLK
> + void __iomem *pll0, *pll1, *psc0, *psc1;
> + struct regmap *cfgchip;
> + 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);
> +
> + cfgchip = da8xx_register_cfgchip();
> + if (WARN(IS_ERR(cfgchip), "failed to register CFGCHIP syscon"))
> + return;
> +
> + clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA850_REF_FREQ);
> +
> + da850_pll_clk_init(pll0, pll1);
> +
> + da8xx_cfgchip_register_div4p5(cfgchip);
> +
> + da8xx_cfgchip_register_async1(cfgchip);
> +
> + clk = clk_register_fixed_factor(NULL, "async2", "pll0_auxclk", 0, 1, 1);
> + clk_register_clkdev(clk, NULL, "i2c_davinci.1");
> + clk_register_clkdev(clk, "timer0", NULL);
> + clk_register_clkdev(clk, NULL, "davinci-wdt");
I think its better to get these clkdevs registered in
da850_pll_clk_init() itself.
> +
> + clk = da8xx_cfgchip_register_async3(cfgchip);
> +
> + /* 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, "rmii", "pll0_sysclk7", 0, 1, 1);
> + clk_register_clkdev(clk, "rmii", NULL);
Like in da830, can drop this rmii clock, I think.
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This adds the new board-specific 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 <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This adds the new board-specific 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 <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This adds the new board-specific 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 <[email protected]>
I did not notice this before, but the subject line for this and other
patches needs to be "ARM: davinci: "
Apart from that:
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> 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");
Lets move this to dm646x_pll_clk_init() and directly register to clkdev
to pll1_sysclk3?
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This adds the new SATA REFCLK clock init in mach-davinci/devices-da8xx.c
> using the new common clock framework drivers.
>
> The #ifdefs are needed to prevent compile errors until the entire
> ARCH_DAVINCI is converted.
>
> Also, the #includes are sorted since we are adding some here.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> The common clock framework will take care of disabling unused clocks when
> we switch from the legacy davinci clocks and having this enabled will
> cause compile errors after we switch, so remove it now.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This removes CONFIG_DAVINCI_RESET_CLOCKS. The option has been removed from
> the kernel.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On 02/02/2018 02:37 AM, Sekhar Nori wrote:
> On Friday 02 February 2018 12:52 AM, David Lechner wrote:
>
>>> +static const char * const da850_pll1_obsclk_parent_names[]
>>> __initconst = {
>>> + "oscin",
>>
>> Re: the issue of "ref_clk" vs. "oscin"...
>>
>> This is one of the places where having the otherwise unnecessary "oscin"
>> clock
>> really helps out. The PLL driver doesn't control "ref_clk" - it comes
>> from somewhere
>> else. And in the case of DT, it may not even be named "ref_clk", so we
>> really
>> don't want to hard-code the name "ref_clk" here.
>
> TBH, I don't really see what is wrong with mandating the name "ref_clk"
> as the reference clock name to be provided. And for all board-files and
> DTs to supply the same name.
>
>> If we have to allow a variable name here, it just makes more work in the
>> driver
>> shuffling names around.
>>
>> And the name "oscin" totally makes sense here because the TRM lists this
>> input to the
>> mux as "OSCIN".
>
> Fine with me if you feel it simplifies implementation for you (and also
> because of the distinction you want to make between the external "before
> CLKMODE" clock and internal "after CLKMODE" clock). What I do care about
> though is:
>
> a) In the DT case, ability for different boards to provide different
> ref_clk frequencies. We never really had this in the legacy board
> file way (except some rudimentary support on DM6467T). And its fine
> to continue with status quo for board files.
You can do this now. You would just add something like this to the board's
.dts file:
& ref_clk {
clock-frequency = <30000000>; /* 30 MHz */
};
>
> b) In the DT case, ability for board to specify whether it uses the
> on-chip oscillator or has an external clean clock provider.
Boards with an oscillator don't need to do anything since that is the
default. Boards with clock will need to do this:
&pll0 {
ti,clkmode-square-wave;
};
>
>>> +void __init da850_pll_clk_init(void __iomem *pll0, void __iomem *pll1)
>>> +{
>>> + const struct davinci_pll_sysclk_info *info;
>>> +
>>> + davinci_pll_clk_register(&da850_pll0_info, "ref_clk", pll0);
>>
>> And really, we probably shouldn't be hard-coding "ref_clk" here either.
>> Basically, we are making the assumption that the board file has registered
>> a clock named "ref_clk". It would probably be better to pass the name
>> as a parameter.
>
> As I noted before, I am not sure if this level of naming flexibility is
> needed. Every board needs to have one anyway. They might as well call it
> by the same name.
>
> That said, I wont oppose it either if you decide to have that flexibility.
>
I'll sleep on it. Like you, I could go either way. I'm temped to just leave
it as-is though (with some added comments for clarification, of course).
On 02/02/2018 12:20 AM, Sekhar Nori wrote:
> On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
>> +EMIFA clock source (ASYNC1)
>> +---------------------------
>> +Required properties:
>> +- compatible: shall be "ti,da850-async1-clksrc".
>> +- #clock-cells: from common clock binding; shall be set to 0.
>> +- clocks: phandles to the parent clocks corresponding to clock-names
>> +- clock-names: shall be "pll0_sysclk3", "div4.5"
>
> Is this clock really referred to as aysnc1 in documentation? I don't get
> hits for async1 in OMAP-L138 TRM.
>
It looks like it is only called ASYNC1 in the datasheet, not the TRM.
Table 6-5. Maximum Internal Clock Frequencies at Each Voltage Operating
Point
On 02/02/2018 07:19 AM, Sekhar Nori wrote:
> On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
>> +static const struct clk_ops da8xx_cfgchip_div4p5_clk_ops = {
>> + .enable = da8xx_cfgchip_gate_clk_enable,
>> + .disable = da8xx_cfgchip_gate_clk_disable,
>> + .is_enabled = da8xx_cfgchip_gate_clk_is_enabled,
>
> I assume the reason for not using clk-gate.c is lack of regmap support
> there?
Correct.
I couldn't find a way to get a lock from the regmap that could
be passed to clk_register_gate() to prevent non-clock drivers from
trying to use the regmap at the same the the clocks are.
>
>> + .recalc_rate = da8xx_cfgchip_div4p5_recalc_rate,
>> +};
>> +
>> +static struct clk * __init
>> +da8xx_cfgchip_gate_clk_register(const struct da8xx_cfgchip_gate_clk_info *info,
>> + const char *parent_name,
>> + struct regmap *regmap)
>> +{
>> + struct da8xx_cfgchip_gate_clk *gate;
>> + struct clk_init_data init;
>> +
>> + gate = kzalloc(sizeof(*gate), GFP_KERNEL);
>> + if (!gate)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + init.name = info->name;
>> + if (info->flags & DA8XX_GATE_CLOCK_IS_DIV4P5)
>> + init.ops = &da8xx_cfgchip_div4p5_clk_ops;
>> + else
>> + init.ops = &da8xx_cfgchip_gate_clk_ops;
>
> This will be easier to read using ternary operator, I think. But you
> will probably have line breaks.
The names are so long that the ternary operator doesn't make it better IMHO.
init.ops = (info->flags & DA8XX_GATE_CLOCK_IS_DIV4P5) ?
&da8xx_cfgchip_div4p5_clk_ops :
&da8xx_cfgchip_gate_clk_ops;
On 02/02/2018 08:12 AM, Sekhar Nori wrote:
> On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
>> 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);
>> +
>> + da8xx_register_cfgchip();
>> +
>> + 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");
>
> Isn't this better done in da830_pll_clk_init() ? I think we can get rid
> of the dummy fixed factor clock too and directly use the pll0_auxclk.
I considered it, but I kind of like keeping the fixed factor clocks for
debugging purposes. If you just have "pll0_auxclk" the enable count is
not helpful because you don't know which driver did the enabling.
On the other hand, once things are working, you don't really need to
do any debugging.
> That reminds me, is "pll0_aux_clk" above correct, or should it be
> "pll0_auxclk" like in da830_pll_clk_init()?
Yes, it should be "pll0_auxclk".
>
>> +
>> + clk = clk_register_fixed_factor(NULL, "rmii", "pll0_sysclk7", 0, 1, 1);
>> + clk_register_clkdev(clk, "rmii", NULL);
>
> I don't see any driver looking for this clock using con_id "rmii". I
> know this came from existing code. But its most likely a vestige and can
> be dropped.
>
> Thanks,
> Sekhar
>
On 02/02/2018 08:20 AM, Sekhar Nori wrote:
> On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
>> void __init da850_init_time(void)
>> {
>> +#ifdef CONFIG_COMMON_CLK
>> + void __iomem *pll0, *pll1, *psc0, *psc1;
>> + struct regmap *cfgchip;
>> + 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);
>> +
>> + cfgchip = da8xx_register_cfgchip();
>> + if (WARN(IS_ERR(cfgchip), "failed to register CFGCHIP syscon"))
>> + return;
>> +
>> + clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA850_REF_FREQ);
>> +
>> + da850_pll_clk_init(pll0, pll1);
>> +
>> + da8xx_cfgchip_register_div4p5(cfgchip);
>> +
>> + da8xx_cfgchip_register_async1(cfgchip);
>> +
>> + clk = clk_register_fixed_factor(NULL, "async2", "pll0_auxclk", 0, 1, 1);
>> + clk_register_clkdev(clk, NULL, "i2c_davinci.1");
>> + clk_register_clkdev(clk, "timer0", NULL);
>> + clk_register_clkdev(clk, NULL, "davinci-wdt");
>
> I think its better to get these clkdevs registered in
> da850_pll_clk_init() itself.
Sounds good to me.
>
>> +
>> + clk = da8xx_cfgchip_register_async3(cfgchip);
>> +
>> + /* 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, "rmii", "pll0_sysclk7", 0, 1, 1);
>> + clk_register_clkdev(clk, "rmii", NULL);
>
> Like in da830, can drop this rmii clock, I think.
>
> Thanks,
> Sekhar
>
On 02/02/2018 08:39 AM, Sekhar Nori wrote:
> On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
>> This adds the new board-specific 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 <[email protected]>
>
> I did not notice this before, but the subject line for this and other
> patches needs to be "ARM: davinci: "
so "davinci" == "dm644x" and not any other SoC?
>
> Apart from that:
>
> Reviewed-by: Sekhar Nori <[email protected]>
>
> Thanks,
> Sekhar
>
On Friday 02 February 2018 11:36 PM, David Lechner wrote:
> On 02/02/2018 08:39 AM, Sekhar Nori wrote:
>> On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
>>> This adds the new board-specific 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 <[email protected]>
>>
>> I did not notice this before, but the subject line for this and other
>> patches needs to be "ARM: davinci: "
>
> so "davinci" == "dm644x" and not any other SoC?
No, I meant "ARM: davinci: dm644x: " instead of just "ARM: dm644x".
Thanks,
Sekhar
On Friday 02 February 2018 11:20 PM, David Lechner wrote:
> On 02/02/2018 12:20 AM, Sekhar Nori wrote:
>> On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
>>> +EMIFA clock source (ASYNC1)
>>> +---------------------------
>>> +Required properties:
>>> +- compatible: shall be "ti,da850-async1-clksrc".
>>> +- #clock-cells: from common clock binding; shall be set to 0.
>>> +- clocks: phandles to the parent clocks corresponding to clock-names
>>> +- clock-names: shall be "pll0_sysclk3", "div4.5"
>>
>> Is this clock really referred to as aysnc1 in documentation? I don't get
>> hits for async1 in OMAP-L138 TRM.
>>
>
> It looks like it is only called ASYNC1 in the datasheet, not the TRM.
>
> Table 6-5. Maximum Internal Clock Frequencies at Each Voltage Operating
> Point
I see it now. Its fine to use async1 then.
Thanks,
Sekhar
On Friday 02 February 2018 11:33 PM, David Lechner wrote:
> On 02/02/2018 08:12 AM, Sekhar Nori wrote:
>> On Saturday 20 January 2018 10:43 PM, David Lechner wrote:
>>> 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);
>>> +
>>> + da8xx_register_cfgchip();
>>> +
>>> + 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");
>>
>> Isn't this better done in da830_pll_clk_init() ? I think we can get rid
>> of the dummy fixed factor clock too and directly use the pll0_auxclk.
>
>
> I considered it, but I kind of like keeping the fixed factor clocks for
> debugging purposes. If you just have "pll0_auxclk" the enable count is
> not helpful because you don't know which driver did the enabling.
I think it is better to more or less reflect the hardware here. We would
not be doing this in the DT case, for example.
I see your point on debugging. Such code can perhaps be temporarily
introduced if really debugging such an issue. This will be the case with
any shared clock.
Thanks,
Sekhar
2018-01-24 4:26 GMT+01:00 David Lechner <[email protected]>:
> On 01/20/2018 11:14 AM, David Lechner wrote:
>>
>> This removes all of the clock init code from da8xx-dt.c. This includes
>> all of the OF_DEV_AUXDATA that was just used for looking up clocks.
>>
>> Signed-off-by: David Lechner <[email protected]>
>> ---
>>
>> v6 changes:
>> - removed misleading statement from commit message
>>
>> arch/arm/mach-davinci/da8xx-dt.c | 61
>> +---------------------------------------
>> 1 file changed, 1 insertion(+), 60 deletions(-)
>>
>> diff --git a/arch/arm/mach-davinci/da8xx-dt.c
>> b/arch/arm/mach-davinci/da8xx-dt.c
>
>
>> static void __init da850_init_machine(void)
>> {
>> - /* All existing boards use 100MHz SATA refclkpn */
>> - static const unsigned long sata_refclkpn = 100 * 1000 * 1000;
>> -
>> - int ret;
>> -
>> - ret = da8xx_register_usb20_phy_clk(false);
>> - if (ret)
>> - pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
>> - __func__, ret);
>> - ret = da8xx_register_usb11_phy_clk(false);
>> - if (ret)
>> - pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
>> - __func__, ret);
>> -
>> - ret = da850_register_sata_refclk(sata_refclkpn);
>> - if (ret)
>> - pr_warn("%s: registering SATA REFCLK failed: %d",
>> - __func__, ret);
>> -
>> - of_platform_default_populate(NULL, da850_auxdata_lookup, NULL);
>> + of_platform_default_populate(NULL, NULL, NULL);
>
>
> of_platform_default_populate() can actually be removed completely.
> of_platform_default_populate_init() is called implicitly during
> arch_initcall_sync
>
>> davinci_pm_init();
>> pdata_quirks_init();
>> }
Hi David,
this patch breaks nand on da850-lcdk (and probably on da850-evm) since
the nand driver can no longer clk_get() the nand clock. We would need
to keep the dev_auxdata at least for aemif.
Thanks,
Bartosz
2018-02-05 15:04 GMT+01:00 Bartosz Golaszewski <[email protected]>:
> 2018-01-24 4:26 GMT+01:00 David Lechner <[email protected]>:
>> On 01/20/2018 11:14 AM, David Lechner wrote:
>>>
>>> This removes all of the clock init code from da8xx-dt.c. This includes
>>> all of the OF_DEV_AUXDATA that was just used for looking up clocks.
>>>
>>> Signed-off-by: David Lechner <[email protected]>
>>> ---
>>>
>>> v6 changes:
>>> - removed misleading statement from commit message
>>>
>>> arch/arm/mach-davinci/da8xx-dt.c | 61
>>> +---------------------------------------
>>> 1 file changed, 1 insertion(+), 60 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-davinci/da8xx-dt.c
>>> b/arch/arm/mach-davinci/da8xx-dt.c
>>
>>
>>> static void __init da850_init_machine(void)
>>> {
>>> - /* All existing boards use 100MHz SATA refclkpn */
>>> - static const unsigned long sata_refclkpn = 100 * 1000 * 1000;
>>> -
>>> - int ret;
>>> -
>>> - ret = da8xx_register_usb20_phy_clk(false);
>>> - if (ret)
>>> - pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
>>> - __func__, ret);
>>> - ret = da8xx_register_usb11_phy_clk(false);
>>> - if (ret)
>>> - pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
>>> - __func__, ret);
>>> -
>>> - ret = da850_register_sata_refclk(sata_refclkpn);
>>> - if (ret)
>>> - pr_warn("%s: registering SATA REFCLK failed: %d",
>>> - __func__, ret);
>>> -
>>> - of_platform_default_populate(NULL, da850_auxdata_lookup, NULL);
>>> + of_platform_default_populate(NULL, NULL, NULL);
>>
>>
>> of_platform_default_populate() can actually be removed completely.
>> of_platform_default_populate_init() is called implicitly during
>> arch_initcall_sync
>>
>>> davinci_pm_init();
>>> pdata_quirks_init();
>>> }
>
> Hi David,
>
> this patch breaks nand on da850-lcdk (and probably on da850-evm) since
> the nand driver can no longer clk_get() the nand clock. We would need
> to keep the dev_auxdata at least for aemif.
>
> Thanks,
> Bartosz
Actually scratch that last e-mail, I missed the fact that the nand
node is only there in the board dts files. I've just sent you a patch
that enables nand on da850-lcdk. Please include it in your series.
I'll do the same for evm shortly.
Thanks,
Bartosz
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This switches ARCH_DAVINCI to use the common clock framework. The legacy
> clock code in arch/arm/mach-davinci/ is no longer used. New drivers in
> drivers/clk/davinci/ are used instead.
>
> A few macros had to be moved to prevent compile errors.
s/compile/compilation
> Signed-off-by: David Lechner <[email protected]>
> --- a/arch/arm/mach-davinci/davinci.h
> +++ b/arch/arm/mach-davinci/davinci.h
> @@ -35,6 +35,10 @@
> #include <media/davinci/vpbe.h>
> #include <media/davinci/vpbe_osd.h>
>
> +#define DAVINCI_PLL1_BASE 0x01c40800
> +#define DAVINCI_PLL2_BASE 0x01c40c00
> +#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01c41000
Please drop the tab after #define
With that.
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This removes the unused legacy clock init code from
> arch/arm/mach-davinci/da830.c.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This removes the unused legacy clock init code from
> arch/arm/mach-davinci/da850.c.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This removes the unused legacy clock init code from
> arch/arm/mach-davinci/dm355.c.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This removes the unused legacy clock init code from
> arch/arm/mach-davinci/dm365.c.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This removes the unused legacy clock init code from
> arch/arm/mach-davinci/dm644x.c.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This removes the unused legacy clock init code from
> arch/arm/mach-davinci/dm646x.c.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This removes the unused legacy clock init code from
> arch/arm/mach-davinci/{devices,usb}-da8xx}.c.
>
> Signed-off-by: David Lechner <[email protected]>
Can you please mention SATA and USB in subject line and in patch
description?
Apart from that:
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> This removes the unused legacy clock code from arch/arm/mach-davinci/.
>
> Signed-off-by: David Lechner <[email protected]>
Reviewed-by: Sekhar Nori <[email protected]>
Thanks,
Sekhar
On Saturday 20 January 2018 10:44 PM, David Lechner wrote:
> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
> index c66cf78..7f4acd7 100644
> --- a/arch/arm/boot/dts/da850.dtsi
> +++ b/arch/arm/boot/dts/da850.dtsi
> @@ -21,6 +21,36 @@
> #interrupt-cells = <1>;
> ti,intc-size = <101>;
> reg = <0xfffee000 0x2000>;
> + clocks = <&psc0 6>;
> + };
> + };
> + clocks: clocks {
> + ref_clk: ref_clk {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <24000000>;
> + clock-output-names = "ref_clk";
> + };
The ref_clk clock-frequency should rather be added in each board file
since its not fixed by the SoC. In general we dont want any SoC defined
properties to be overwritten by board files (except the status = property).
Thanks,
Sekhar