* [PATCH 0/7] core, cpu and gated clocks for mvebu
@ 2012-11-15 21:28 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: mturquette-QSEj5FYQhm4dnm+yROfE0A
Cc: Thomas Petazzoni, Andrew Lunn, Jason Cooper,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux ARM
This patchset combines code from Gregory Clement, Sebastian
Hesselbarth and myself to implement core clks, cpu clock and gated
clocks on Marvel MVEBU SoCs.
The Armada 370/XP core clock code is a refactored version of the
already submitted and ACKed code from Gregory. It has been made to fit
inside a framework developed by Sebastian which can handle all MVEBU
SoCs. The Armarda 370/XP SoCs have more core clocks than the older SoCs, and
the framework needs to handle this. Rather than specify the clock
frequencies in DT, a Sample At Reset register is used, which describes
each core clock frequency.
Armarda XP is an SMP processor, with each CPU having its own
clock. Gregories code for this has been taken as is.
The Armarda 370/XP clock source has been converted to the common clock
framework.
Dove, Kirkword, and probably Armarda 370/XP have the ability to gate
clocks to various blocks. A clk-gate clock is created for each of the
gateable clocks on Dove and Kirkwood. Armarda 370/XP clock gates are
currently unimplemented. Dove and Kirkwood board-dt.c and DT
descriptions are then modified to make use of these clk gates.
This code has been tested on:
Kirkwood based QNAP TS219
Armarda 370 based mirabox
Armara XP based OpenBlocks
and by Sebastian on:
Dove based Cubox.
Andrew Lunn (1):
ARM: Kirkwood: switch to DT clock providers
Gregory CLEMENT (3):
clk: mvebu: add armada-370-xp CPU specific clocks
clk: armada-370-xp: add support for clock framework
clocksource: time-armada-370-xp converted to clk framework
Sebastian Hesselbarth (3):
clk: mvebu: add mvebu core clocks.
clk: mvebu: add clock gating control provider for DT
ARM: dove: switch to DT clock providers
.../devicetree/bindings/clock/mvebu-core-clock.txt | 47 ++
.../devicetree/bindings/clock/mvebu-cpu-clock.txt | 21 +
.../bindings/clock/mvebu-gated-clock.txt | 76 +++
arch/arm/Kconfig | 1 +
arch/arm/boot/dts/armada-370-db.dts | 4 -
arch/arm/boot/dts/armada-370-xp.dtsi | 1 +
arch/arm/boot/dts/armada-370.dtsi | 7 +
arch/arm/boot/dts/armada-xp.dtsi | 42 ++
arch/arm/boot/dts/dove.dtsi | 20 +
arch/arm/boot/dts/kirkwood.dtsi | 22 +
arch/arm/mach-dove/Kconfig | 2 +
arch/arm/mach-dove/common.c | 64 +-
arch/arm/mach-kirkwood/Kconfig | 2 +
arch/arm/mach-kirkwood/board-dt.c | 72 ++-
arch/arm/mach-mvebu/Kconfig | 6 +
arch/arm/mach-mvebu/armada-370-xp.c | 9 +-
arch/arm/plat-orion/include/plat/common.h | 1 +
drivers/clk/Kconfig | 2 +
drivers/clk/Makefile | 1 +
drivers/clk/mvebu/Kconfig | 8 +
drivers/clk/mvebu/Makefile | 3 +
drivers/clk/mvebu/clk-core.c | 675 ++++++++++++++++++++
drivers/clk/mvebu/clk-core.h | 18 +
drivers/clk/mvebu/clk-cpu.c | 155 +++++
drivers/clk/mvebu/clk-cpu.h | 18 +
drivers/clk/mvebu/clk-gating-ctrl.c | 177 +++++
drivers/clk/mvebu/clk.c | 37 ++
drivers/clocksource/time-armada-370-xp.c | 11 +-
include/linux/clk/mvebu.h | 23 +
29 files changed, 1487 insertions(+), 38 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
create mode 100644 drivers/clk/mvebu/Kconfig
create mode 100644 drivers/clk/mvebu/Makefile
create mode 100644 drivers/clk/mvebu/clk-core.c
create mode 100644 drivers/clk/mvebu/clk-core.h
create mode 100644 drivers/clk/mvebu/clk-cpu.c
create mode 100644 drivers/clk/mvebu/clk-cpu.h
create mode 100644 drivers/clk/mvebu/clk-gating-ctrl.c
create mode 100644 drivers/clk/mvebu/clk.c
create mode 100644 include/linux/clk/mvebu.h
--
1.7.10.4
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 0/7] core, cpu and gated clocks for mvebu
@ 2012-11-15 21:28 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: linux-arm-kernel
This patchset combines code from Gregory Clement, Sebastian
Hesselbarth and myself to implement core clks, cpu clock and gated
clocks on Marvel MVEBU SoCs.
The Armada 370/XP core clock code is a refactored version of the
already submitted and ACKed code from Gregory. It has been made to fit
inside a framework developed by Sebastian which can handle all MVEBU
SoCs. The Armarda 370/XP SoCs have more core clocks than the older SoCs, and
the framework needs to handle this. Rather than specify the clock
frequencies in DT, a Sample At Reset register is used, which describes
each core clock frequency.
Armarda XP is an SMP processor, with each CPU having its own
clock. Gregories code for this has been taken as is.
The Armarda 370/XP clock source has been converted to the common clock
framework.
Dove, Kirkword, and probably Armarda 370/XP have the ability to gate
clocks to various blocks. A clk-gate clock is created for each of the
gateable clocks on Dove and Kirkwood. Armarda 370/XP clock gates are
currently unimplemented. Dove and Kirkwood board-dt.c and DT
descriptions are then modified to make use of these clk gates.
This code has been tested on:
Kirkwood based QNAP TS219
Armarda 370 based mirabox
Armara XP based OpenBlocks
and by Sebastian on:
Dove based Cubox.
Andrew Lunn (1):
ARM: Kirkwood: switch to DT clock providers
Gregory CLEMENT (3):
clk: mvebu: add armada-370-xp CPU specific clocks
clk: armada-370-xp: add support for clock framework
clocksource: time-armada-370-xp converted to clk framework
Sebastian Hesselbarth (3):
clk: mvebu: add mvebu core clocks.
clk: mvebu: add clock gating control provider for DT
ARM: dove: switch to DT clock providers
.../devicetree/bindings/clock/mvebu-core-clock.txt | 47 ++
.../devicetree/bindings/clock/mvebu-cpu-clock.txt | 21 +
.../bindings/clock/mvebu-gated-clock.txt | 76 +++
arch/arm/Kconfig | 1 +
arch/arm/boot/dts/armada-370-db.dts | 4 -
arch/arm/boot/dts/armada-370-xp.dtsi | 1 +
arch/arm/boot/dts/armada-370.dtsi | 7 +
arch/arm/boot/dts/armada-xp.dtsi | 42 ++
arch/arm/boot/dts/dove.dtsi | 20 +
arch/arm/boot/dts/kirkwood.dtsi | 22 +
arch/arm/mach-dove/Kconfig | 2 +
arch/arm/mach-dove/common.c | 64 +-
arch/arm/mach-kirkwood/Kconfig | 2 +
arch/arm/mach-kirkwood/board-dt.c | 72 ++-
arch/arm/mach-mvebu/Kconfig | 6 +
arch/arm/mach-mvebu/armada-370-xp.c | 9 +-
arch/arm/plat-orion/include/plat/common.h | 1 +
drivers/clk/Kconfig | 2 +
drivers/clk/Makefile | 1 +
drivers/clk/mvebu/Kconfig | 8 +
drivers/clk/mvebu/Makefile | 3 +
drivers/clk/mvebu/clk-core.c | 675 ++++++++++++++++++++
drivers/clk/mvebu/clk-core.h | 18 +
drivers/clk/mvebu/clk-cpu.c | 155 +++++
drivers/clk/mvebu/clk-cpu.h | 18 +
drivers/clk/mvebu/clk-gating-ctrl.c | 177 +++++
drivers/clk/mvebu/clk.c | 37 ++
drivers/clocksource/time-armada-370-xp.c | 11 +-
include/linux/clk/mvebu.h | 23 +
29 files changed, 1487 insertions(+), 38 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
create mode 100644 drivers/clk/mvebu/Kconfig
create mode 100644 drivers/clk/mvebu/Makefile
create mode 100644 drivers/clk/mvebu/clk-core.c
create mode 100644 drivers/clk/mvebu/clk-core.h
create mode 100644 drivers/clk/mvebu/clk-cpu.c
create mode 100644 drivers/clk/mvebu/clk-cpu.h
create mode 100644 drivers/clk/mvebu/clk-gating-ctrl.c
create mode 100644 drivers/clk/mvebu/clk.c
create mode 100644 include/linux/clk/mvebu.h
--
1.7.10.4
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/7] clk: mvebu: add mvebu core clocks.
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:28 ` Andrew Lunn
-1 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: mturquette
Cc: Thomas Petazzoni, Andrew Lunn, Jason Cooper, devicetree-discuss,
Gregory Clement, linux ARM, Sebastian Hesselbarth
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
This driver allows to provide DT clocks for core clocks found on
Marvell Kirkwood, Dove & 370/XP SoCs. The core clock frequencies and
ratios are determined by decoding the Sample-At-Reset registers.
Although technically correct, using a divider of 0 will lead to
div_by_zero panic. Let's use a ratio of 0/1 instead to fail later
with a zero clock.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
.../devicetree/bindings/clock/mvebu-core-clock.txt | 47 ++
drivers/clk/Kconfig | 2 +
drivers/clk/Makefile | 1 +
drivers/clk/mvebu/Kconfig | 3 +
drivers/clk/mvebu/Makefile | 1 +
drivers/clk/mvebu/clk-core.c | 675 ++++++++++++++++++++
drivers/clk/mvebu/clk-core.h | 18 +
drivers/clk/mvebu/clk.c | 23 +
include/linux/clk/mvebu.h | 22 +
9 files changed, 792 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
create mode 100644 drivers/clk/mvebu/Kconfig
create mode 100644 drivers/clk/mvebu/Makefile
create mode 100644 drivers/clk/mvebu/clk-core.c
create mode 100644 drivers/clk/mvebu/clk-core.h
create mode 100644 drivers/clk/mvebu/clk.c
create mode 100644 include/linux/clk/mvebu.h
diff --git a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
new file mode 100644
index 0000000..84cfae7
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
@@ -0,0 +1,47 @@
+* Core Clock bindings for Marvell MVEBU SoCs
+
+Marvell MVEBU SoCs usually allow to determine core clock frequencies by
+reading the Sample-At-Reset (SAR) register. The core clock consumer should
+specify the desired clock by having the clock ID in its "clocks" phandle cell.
+
+The following is a list of provided IDs and clock names on Kirkwood and Dove:
+ 0 = tclk (Internal Bus clock)
+ 1 = cpuclk (CPU0 clock)
+ 2 = l2clk (L2 Cache clock derived from CPU0 clock)
+ 3 = ddrclk (DDR controller clock derived from CPU0 clock)
+
+The following is a list of provided IDs and clock names on 370/XP:
+ 0 = tclk (Internal Bus clock)
+ 1 = cpuclk (CPU clock)
+ 2 = nbclk (L2 Cache clock)
+ 3 = hclk (DRAM control clock)
+ 4 = dramclk (DDR clock)
+
+Required properties:
+- compatible : shall be one of the following:
+ "marvell,dove-core-clocks" - for Dove SoC core clocks
+ "marvell,kirkwood-core-clocks" - for Kirkwood SoC (except mv88f6180)
+ "marvell,mv88f6180-core-clocks" - for Kirkwood MV88f6180 SoC
+ "marvell,370-core-clocks" - For 370 SoC core clocks
+ "marvell,xp-core-clocks" - For XP SoC core clocks
+- reg : shall be the register address of the Sample-At-Reset (SAR) register
+- #clock-cells : from common clock binding; shall be set to 1
+
+Optional properties:
+- clock-output-names : from common clock binding; allows overwrite default clock
+ output names ("tclk", "cpuclk", "l2clk", "ddrclk")
+
+Example:
+
+core_clk: core-clocks@d0214 {
+ compatible = "marvell,dove-core-clocks";
+ reg = <0xd0214 0x4>;
+ #clock-cells = <1>;
+};
+
+spi0: spi@10600 {
+ compatible = "marvell,orion-spi";
+ /* ... */
+ /* get tclk from core clock provider */
+ clocks = <&core_clk 0>;
+};
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index bace9e9..60427c0 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -54,3 +54,5 @@ config COMMON_CLK_MAX77686
This driver supports Maxim 77686 crystal oscillator clock.
endmenu
+
+source "drivers/clk/mvebu/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 71a25b9..d0a14ae 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-$(CONFIG_ARCH_U300) += clk-u300.o
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o
+obj-$(CONFIG_PLAT_ORION) += mvebu/
ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_MMP) += mmp/
endif
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
new file mode 100644
index 0000000..fd7bf97
--- /dev/null
+++ b/drivers/clk/mvebu/Kconfig
@@ -0,0 +1,3 @@
+config MVEBU_CLK_CORE
+ bool
+
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
new file mode 100644
index 0000000..de1d961
--- /dev/null
+++ b/drivers/clk/mvebu/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MVEBU_CLK_CORE) += clk.o clk-core.o
diff --git a/drivers/clk/mvebu/clk-core.c b/drivers/clk/mvebu/clk-core.c
new file mode 100644
index 0000000..26ba835
--- /dev/null
+++ b/drivers/clk/mvebu/clk-core.c
@@ -0,0 +1,675 @@
+/*
+ * Marvell EBU clock core handling defined at reset
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include "clk-core.h"
+
+struct core_ratio {
+ int id;
+ const char *name;
+};
+
+struct core_clocks {
+ u32 (*get_tclk_freq)(void __iomem *sar);
+ u32 (*get_cpu_freq)(void __iomem *sar);
+ void (*get_clk_ratio)(void __iomem *sar, int id, int *mult, int *div);
+ const struct core_ratio *ratios;
+ int num_ratios;
+};
+
+static struct clk_onecell_data clk_data;
+
+static void __init mvebu_clk_core_setup(struct device_node *np,
+ struct core_clocks *coreclk)
+{
+ const char *tclk_name = "tclk";
+ const char *cpuclk_name = "cpuclk";
+ void __iomem *base;
+ unsigned long rate;
+ int n;
+
+ base = of_iomap(np, 0);
+ if (WARN_ON(!base))
+ return;
+
+ /*
+ * Allocate struct for TCLK, cpu clk, and core ratio clocks
+ */
+ clk_data.clk_num = 2 + coreclk->num_ratios;
+ clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *),
+ GFP_KERNEL);
+ if (WARN_ON(!clk_data.clks))
+ return;
+
+ /*
+ * Register TCLK
+ */
+ of_property_read_string_index(np, "clock-output-names", 0,
+ &tclk_name);
+ rate = coreclk->get_tclk_freq(base);
+ clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL,
+ CLK_IS_ROOT, rate);
+ WARN_ON(IS_ERR(clk_data.clks[0]));
+
+ /*
+ * Register CPU clock
+ */
+ of_property_read_string_index(np, "clock-output-names", 1,
+ &cpuclk_name);
+ rate = coreclk->get_cpu_freq(base);
+ clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL,
+ CLK_IS_ROOT, rate);
+ WARN_ON(IS_ERR(clk_data.clks[1]));
+
+ /*
+ * Register fixed-factor clocks derived from CPU clock
+ */
+ for (n = 0; n < coreclk->num_ratios; n++) {
+ const char *rclk_name = coreclk->ratios[n].name;
+ int mult, div;
+
+ of_property_read_string_index(np, "clock-output-names",
+ 2+n, &rclk_name);
+ coreclk->get_clk_ratio(base, coreclk->ratios[n].id,
+ &mult, &div);
+ clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name,
+ cpuclk_name, 0, mult, div);
+ WARN_ON(IS_ERR(clk_data.clks[2+n]));
+ };
+
+ /*
+ * SAR register isn't needed anymore
+ */
+ iounmap(base);
+
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+#ifdef CONFIG_MACH_ARMADA_370_XP
+/*
+ * 370/XP Sample At Reset is a 64 bit bitfiled split in two register
+ * of 32 bits
+ */
+
+#define SARL 0 /* Low part [0:31] */
+#define SARL_AXP_PCLK_FREQ_OPT 21
+#define SARL_AXP_PCLK_FREQ_OPT_MASK 0x7
+#define SARL_A370_PCLK_FREQ_OPT 11
+#define SARL_A370_PCLK_FREQ_OPT_MASK 0xF
+#define SARL_AXP_FAB_FREQ_OPT 24
+#define SARL_AXP_FAB_FREQ_OPT_MASK 0xF
+#define SARL_A370_FAB_FREQ_OPT 15
+#define SARL_A370_FAB_FREQ_OPT_MASK 0x1F
+#define SARL_A370_TCLK_FREQ_OPT 20
+#define SARL_A370_TCLK_FREQ_OPT_MASK 0x1
+#define SARH 4 /* High part [32:63] */
+#define SARH_AXP_PCLK_FREQ_OPT (52-32)
+#define SARH_AXP_PCLK_FREQ_OPT_MASK 0x1
+#define SARH_AXP_PCLK_FREQ_OPT_SHIFT 3
+#define SARH_AXP_FAB_FREQ_OPT (51-32)
+#define SARH_AXP_FAB_FREQ_OPT_MASK 0x1
+#define SARH_AXP_FAB_FREQ_OPT_SHIFT 4
+
+static const u32 __initconst a370_tclk_frequencies[] = {
+ 16600000,
+ 20000000,
+};
+
+static u32 __init a370_get_tclk_freq(void __iomem *sar)
+{
+ u8 tclk_freq_select = 0;
+
+ tclk_freq_select = ((readl(sar) >> SARL_A370_TCLK_FREQ_OPT) &
+ SARL_A370_TCLK_FREQ_OPT_MASK);
+ return a370_tclk_frequencies[tclk_freq_select];
+}
+
+static const u32 __initconst a370_cpu_frequencies[] = {
+ 400000000,
+ 533000000,
+ 667000000,
+ 800000000,
+ 1000000000,
+ 1067000000,
+ 1200000000,
+};
+
+static u32 __init a370_get_cpu_freq(void __iomem *sar)
+{
+ u32 cpu_freq;
+ u8 cpu_freq_select = 0;
+
+ cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) &
+ SARL_A370_PCLK_FREQ_OPT_MASK);
+ if (cpu_freq_select > ARRAY_SIZE(a370_cpu_frequencies)) {
+ pr_err("CPU freq select unsuported %d\n", cpu_freq_select);
+ cpu_freq = 0;
+ } else
+ cpu_freq = a370_cpu_frequencies[cpu_freq_select];
+
+ return cpu_freq;
+}
+
+enum { A370_XP_NBCLK, A370_XP_HCLK, A370_XP_DRAMCLK };
+
+static const struct core_ratio __initconst a370_xp_core_ratios[] = {
+ { .id = A370_XP_NBCLK, .name = "nbclk" },
+ { .id = A370_XP_HCLK, .name = "hclk" },
+ { .id = A370_XP_DRAMCLK, .name = "dramclk" },
+};
+
+static const int __initconst a370_xp_nbclk_ratios[32][2] = {
+ {0, 1}, {1, 2}, {2, 2}, {2, 2},
+ {1, 2}, {1, 2}, {1, 1}, {2, 3},
+ {0, 1}, {1, 2}, {2, 4}, {0, 1},
+ {1, 2}, {0, 1}, {0, 1}, {2, 2},
+ {0, 1}, {0, 1}, {0, 1}, {1, 1},
+ {2, 3}, {0, 1}, {0, 1}, {0, 1},
+ {0, 1}, {0, 1}, {0, 1}, {1, 1},
+ {0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static const int __initconst a370_xp_hclk_ratios[32][2] = {
+ {0, 1}, {1, 2}, {2, 6}, {2, 3},
+ {1, 3}, {1, 4}, {1, 2}, {2, 6},
+ {0, 1}, {1, 6}, {2, 10}, {0, 1},
+ {1, 4}, {0, 1}, {0, 1}, {2, 5},
+ {0, 1}, {0, 1}, {0, 1}, {1, 2},
+ {2, 6}, {0, 1}, {0, 1}, {0, 1},
+ {0, 1}, {0, 1}, {0, 1}, {1, 1},
+ {0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static const int __initconst a370_xp_dramclk_ratios[32][2] = {
+ {0, 1}, {1, 2}, {2, 3}, {2, 3},
+ {1, 3}, {1, 2}, {1, 2}, {2, 6},
+ {0, 1}, {1, 3}, {2, 5}, {0, 1},
+ {1, 4}, {0, 1}, {0, 1}, {2, 5},
+ {0, 1}, {0, 1}, {0, 1}, {1, 1},
+ {2, 3}, {0, 1}, {0, 1}, {0, 1},
+ {0, 1}, {0, 1}, {0, 1}, {1, 1},
+ {0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static void __init a370_xp_get_clk_ratio(u32 opt,
+ void __iomem *sar, int id, int *mult, int *div)
+{
+ switch (id) {
+ case A370_XP_NBCLK:
+ *mult = a370_xp_nbclk_ratios[opt][0];
+ *div = a370_xp_nbclk_ratios[opt][1];
+ break;
+ case A370_XP_HCLK:
+ *mult = a370_xp_hclk_ratios[opt][0];
+ *div = a370_xp_hclk_ratios[opt][1];
+ break;
+ case A370_XP_DRAMCLK:
+ *mult = a370_xp_dramclk_ratios[opt][0];
+ *div = a370_xp_dramclk_ratios[opt][1];
+ break;
+ }
+}
+
+static void __init a370_get_clk_ratio(
+ void __iomem *sar, int id, int *mult, int *div)
+{
+ u32 opt = ((readl(sar) >> SARL_A370_FAB_FREQ_OPT) &
+ SARL_A370_FAB_FREQ_OPT_MASK);
+
+ a370_xp_get_clk_ratio(opt, sar, id, mult, div);
+}
+
+
+static const struct core_clocks a370_core_clocks = {
+ .get_tclk_freq = a370_get_tclk_freq,
+ .get_cpu_freq = a370_get_cpu_freq,
+ .get_clk_ratio = a370_get_clk_ratio,
+ .ratios = a370_xp_core_ratios,
+ .num_ratios = ARRAY_SIZE(a370_xp_core_ratios),
+};
+
+static const u32 __initconst xp_cpu_frequencies[] = {
+ 1000000000,
+ 1066000000,
+ 1200000000,
+ 1333000000,
+ 1500000000,
+ 1666000000,
+ 1800000000,
+ 2000000000,
+ 667000000,
+ 0,
+ 800000000,
+ 1600000000,
+};
+
+/* For Armada XP TCLK frequency is fix: 250MHz */
+static u32 __init xp_get_tclk_freq(void __iomem *sar)
+{
+ return 250 * 1000 * 1000;
+}
+
+static u32 __init xp_get_cpu_freq(void __iomem *sar)
+{
+ u32 cpu_freq;
+ u8 cpu_freq_select = 0;
+
+ cpu_freq_select = ((readl(sar) >> SARL_AXP_PCLK_FREQ_OPT) &
+ SARL_AXP_PCLK_FREQ_OPT_MASK);
+ /*
+ * The upper bit is not contiguous to the other ones and
+ * located in the high part of the SAR registers
+ */
+ cpu_freq_select |= (((readl(sar+4) >> SARH_AXP_PCLK_FREQ_OPT) &
+ SARH_AXP_PCLK_FREQ_OPT_MASK)
+ << SARH_AXP_PCLK_FREQ_OPT_SHIFT);
+ if (cpu_freq_select > ARRAY_SIZE(xp_cpu_frequencies)) {
+ pr_err("CPU freq select unsuported: %d\n", cpu_freq_select);
+ cpu_freq = 0;
+ } else
+ cpu_freq = xp_cpu_frequencies[cpu_freq_select];
+
+ return cpu_freq;
+}
+
+static void __init xp_get_clk_ratio(
+ void __iomem *sar, int id, int *mult, int *div)
+{
+
+ u32 opt = ((readl(sar) >> SARL_AXP_FAB_FREQ_OPT) &
+ SARL_AXP_FAB_FREQ_OPT_MASK);
+ /*
+ * The upper bit is not contiguous to the other ones and
+ * located in the high part of the SAR registers
+ */
+ opt |= (((readl(sar+4) >> SARH_AXP_FAB_FREQ_OPT) &
+ SARH_AXP_FAB_FREQ_OPT_MASK)
+ << SARH_AXP_FAB_FREQ_OPT_SHIFT);
+
+ a370_xp_get_clk_ratio(opt, sar, id, mult, div);
+}
+
+static const struct core_clocks xp_core_clocks = {
+ .get_tclk_freq = xp_get_tclk_freq,
+ .get_cpu_freq = xp_get_cpu_freq,
+ .get_clk_ratio = xp_get_clk_ratio,
+ .ratios = a370_xp_core_ratios,
+ .num_ratios = ARRAY_SIZE(a370_xp_core_ratios),
+};
+
+#endif /* CONFIG_MACH_ARMADA_370_XP */
+
+/*
+ * Dove PLL sample-at-reset configuration
+ *
+ * SAR0[8:5] : CPU frequency
+ * 5 = 1000 MHz
+ * 6 = 933 MHz
+ * 7 = 933 MHz
+ * 8 = 800 MHz
+ * 9 = 800 MHz
+ * 10 = 800 MHz
+ * 11 = 1067 MHz
+ * 12 = 667 MHz
+ * 13 = 533 MHz
+ * 14 = 400 MHz
+ * 15 = 333 MHz
+ * others reserved.
+ *
+ * SAR0[11:9] : CPU to L2 Clock divider ratio
+ * 0 = (1/1) * CPU
+ * 2 = (1/2) * CPU
+ * 4 = (1/3) * CPU
+ * 6 = (1/4) * CPU
+ * others reserved.
+ *
+ * SAR0[15:12] : CPU to DDR DRAM Clock divider ratio
+ * 0 = (1/1) * CPU
+ * 2 = (1/2) * CPU
+ * 3 = (2/5) * CPU
+ * 4 = (1/3) * CPU
+ * 6 = (1/4) * CPU
+ * 8 = (1/5) * CPU
+ * 10 = (1/6) * CPU
+ * 12 = (1/7) * CPU
+ * 14 = (1/8) * CPU
+ * 15 = (1/10) * CPU
+ * others reserved.
+ *
+ * SAR0[24:23] : TCLK frequency
+ * 0 = 166 MHz
+ * 1 = 125 MHz
+ * others reserved.
+ */
+#ifdef CONFIG_ARCH_DOVE
+#define SAR_DOVE_CPU_FREQ 5
+#define SAR_DOVE_CPU_FREQ_MASK 0xf
+#define SAR_DOVE_L2_RATIO 9
+#define SAR_DOVE_L2_RATIO_MASK 0x7
+#define SAR_DOVE_DDR_RATIO 12
+#define SAR_DOVE_DDR_RATIO_MASK 0xf
+#define SAR_DOVE_TCLK_FREQ 23
+#define SAR_DOVE_TCLK_FREQ_MASK 0x3
+
+static const u32 __initconst dove_tclk_frequencies[] = {
+ 166666667,
+ 125000000,
+ 0, 0
+};
+
+static u32 __init dove_get_tclk_freq(void __iomem *sar)
+{
+ u32 opt = (readl(sar) >> SAR_DOVE_TCLK_FREQ) &
+ SAR_DOVE_TCLK_FREQ_MASK;
+ return dove_tclk_frequencies[opt];
+}
+
+static const u32 __initconst dove_cpu_frequencies[] = {
+ 0, 0, 0, 0, 0,
+ 1000000000,
+ 933333333, 933333333,
+ 800000000, 800000000, 800000000,
+ 1066666667,
+ 666666667,
+ 533333333,
+ 400000000,
+ 333333333
+};
+
+static u32 __init dove_get_cpu_freq(void __iomem *sar)
+{
+ u32 opt = (readl(sar) >> SAR_DOVE_CPU_FREQ) &
+ SAR_DOVE_CPU_FREQ_MASK;
+ return dove_cpu_frequencies[opt];
+}
+
+enum { DOVE_CPU_TO_L2, DOVE_CPU_TO_DDR };
+
+static const struct core_ratio __initconst dove_core_ratios[] = {
+ { .id = DOVE_CPU_TO_L2, .name = "l2clk", },
+ { .id = DOVE_CPU_TO_DDR, .name = "ddrclk", }
+};
+
+static const int __initconst dove_cpu_l2_ratios[8][2] = {
+ { 1, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
+ { 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 }
+};
+
+static const int __initconst dove_cpu_ddr_ratios[16][2] = {
+ { 1, 1 }, { 0, 1 }, { 1, 2 }, { 2, 5 },
+ { 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 },
+ { 1, 5 }, { 0, 1 }, { 1, 6 }, { 0, 1 },
+ { 1, 7 }, { 0, 1 }, { 1, 8 }, { 1, 10 }
+};
+
+static void __init dove_get_clk_ratio(
+ void __iomem *sar, int id, int *mult, int *div)
+{
+ switch (id) {
+ case DOVE_CPU_TO_L2:
+ {
+ u32 opt = (readl(sar) >> SAR_DOVE_L2_RATIO) &
+ SAR_DOVE_L2_RATIO_MASK;
+ *mult = dove_cpu_l2_ratios[opt][0];
+ *div = dove_cpu_l2_ratios[opt][1];
+ break;
+ }
+ case DOVE_CPU_TO_DDR:
+ {
+ u32 opt = (readl(sar) >> SAR_DOVE_DDR_RATIO) &
+ SAR_DOVE_DDR_RATIO_MASK;
+ *mult = dove_cpu_ddr_ratios[opt][0];
+ *div = dove_cpu_ddr_ratios[opt][1];
+ break;
+ }
+ }
+}
+
+static const struct core_clocks dove_core_clocks = {
+ .get_tclk_freq = dove_get_tclk_freq,
+ .get_cpu_freq = dove_get_cpu_freq,
+ .get_clk_ratio = dove_get_clk_ratio,
+ .ratios = dove_core_ratios,
+ .num_ratios = ARRAY_SIZE(dove_core_ratios),
+};
+#endif /* CONFIG_ARCH_DOVE */
+
+/*
+ * Kirkwood PLL sample-at-reset configuration
+ * (6180 has different SAR layout than other Kirkwood SoCs)
+ *
+ * SAR0[4:3,22,1] : CPU frequency (6281,6292,6282)
+ * 4 = 600 MHz
+ * 6 = 800 MHz
+ * 7 = 1000 MHz
+ * 9 = 1200 MHz
+ * 12 = 1500 MHz
+ * 13 = 1600 MHz
+ * 14 = 1800 MHz
+ * 15 = 2000 MHz
+ * others reserved.
+ *
+ * SAR0[19,10:9] : CPU to L2 Clock divider ratio (6281,6292,6282)
+ * 1 = (1/2) * CPU
+ * 3 = (1/3) * CPU
+ * 5 = (1/4) * CPU
+ * others reserved.
+ *
+ * SAR0[8:5] : CPU to DDR DRAM Clock divider ratio (6281,6292,6282)
+ * 2 = (1/2) * CPU
+ * 4 = (1/3) * CPU
+ * 6 = (1/4) * CPU
+ * 7 = (2/9) * CPU
+ * 8 = (1/5) * CPU
+ * 9 = (1/6) * CPU
+ * others reserved.
+ *
+ * SAR0[4:2] : Kirkwood 6180 cpu/l2/ddr clock configuration (6180 only)
+ * 5 = [CPU = 600 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/3) * CPU]
+ * 6 = [CPU = 800 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/4) * CPU]
+ * 7 = [CPU = 1000 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/5) * CPU]
+ * others reserved.
+ *
+ * SAR0[21] : TCLK frequency
+ * 0 = 200 MHz
+ * 1 = 166 MHz
+ * others reserved.
+ */
+#ifdef CONFIG_ARCH_KIRKWOOD
+#define SAR_KIRKWOOD_CPU_FREQ(x) \
+ (((x & (1 << 1)) >> 1) | \
+ ((x & (1 << 22)) >> 21) | \
+ ((x & (3 << 3)) >> 1))
+#define SAR_KIRKWOOD_L2_RATIO(x) \
+ (((x & (3 << 9)) >> 9) | \
+ (((x & (1 << 19)) >> 17)))
+#define SAR_KIRKWOOD_DDR_RATIO 5
+#define SAR_KIRKWOOD_DDR_RATIO_MASK 0xf
+#define SAR_MV88F6180_CLK 2
+#define SAR_MV88F6180_CLK_MASK 0x7
+#define SAR_KIRKWOOD_TCLK_FREQ 21
+#define SAR_KIRKWOOD_TCLK_FREQ_MASK 0x1
+
+enum { KIRKWOOD_CPU_TO_L2, KIRKWOOD_CPU_TO_DDR };
+
+static const struct core_ratio __initconst kirkwood_core_ratios[] = {
+ { .id = KIRKWOOD_CPU_TO_L2, .name = "l2clk", },
+ { .id = KIRKWOOD_CPU_TO_DDR, .name = "ddrclk", }
+};
+
+static u32 __init kirkwood_get_tclk_freq(void __iomem *sar)
+{
+ u32 opt = (readl(sar) >> SAR_KIRKWOOD_TCLK_FREQ) &
+ SAR_KIRKWOOD_TCLK_FREQ_MASK;
+ return (opt) ? 166666667 : 200000000;
+}
+
+static const u32 __initconst kirkwood_cpu_frequencies[] = {
+ 0, 0, 0, 0,
+ 600000000,
+ 0,
+ 800000000,
+ 1000000000,
+ 0,
+ 1200000000,
+ 0, 0,
+ 1500000000,
+ 1600000000,
+ 1800000000,
+ 2000000000
+};
+
+static u32 __init kirkwood_get_cpu_freq(void __iomem *sar)
+{
+ u32 opt = SAR_KIRKWOOD_CPU_FREQ(readl(sar));
+ return kirkwood_cpu_frequencies[opt];
+}
+
+static const int __initconst kirkwood_cpu_l2_ratios[8][2] = {
+ { 0, 1 }, { 1, 2 }, { 0, 1 }, { 1, 3 },
+ { 0, 1 }, { 1, 4 }, { 0, 1 }, { 0, 1 }
+};
+
+static const int __initconst kirkwood_cpu_ddr_ratios[16][2] = {
+ { 0, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
+ { 1, 3 }, { 0, 1 }, { 1, 4 }, { 2, 9 },
+ { 1, 5 }, { 1, 6 }, { 0, 1 }, { 0, 1 },
+ { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }
+};
+
+static void __init kirkwood_get_clk_ratio(
+ void __iomem *sar, int id, int *mult, int *div)
+{
+ switch (id) {
+ case KIRKWOOD_CPU_TO_L2:
+ {
+ u32 opt = SAR_KIRKWOOD_L2_RATIO(readl(sar));
+ *mult = kirkwood_cpu_l2_ratios[opt][0];
+ *div = kirkwood_cpu_l2_ratios[opt][1];
+ break;
+ }
+ case KIRKWOOD_CPU_TO_DDR:
+ {
+ u32 opt = (readl(sar) >> SAR_KIRKWOOD_DDR_RATIO) &
+ SAR_KIRKWOOD_DDR_RATIO_MASK;
+ *mult = kirkwood_cpu_ddr_ratios[opt][0];
+ *div = kirkwood_cpu_ddr_ratios[opt][1];
+ break;
+ }
+ }
+}
+
+static const struct core_clocks kirkwood_core_clocks = {
+ .get_tclk_freq = kirkwood_get_tclk_freq,
+ .get_cpu_freq = kirkwood_get_cpu_freq,
+ .get_clk_ratio = kirkwood_get_clk_ratio,
+ .ratios = kirkwood_core_ratios,
+ .num_ratios = ARRAY_SIZE(kirkwood_core_ratios),
+};
+
+static const u32 __initconst mv88f6180_cpu_frequencies[] = {
+ 0, 0, 0, 0, 0,
+ 600000000,
+ 800000000,
+ 1000000000
+};
+
+static u32 __init mv88f6180_get_cpu_freq(void __iomem *sar)
+{
+ u32 opt = (readl(sar) >> SAR_MV88F6180_CLK) & SAR_MV88F6180_CLK_MASK;
+ return mv88f6180_cpu_frequencies[opt];
+}
+
+static const int __initconst mv88f6180_cpu_ddr_ratios[8][2] = {
+ { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 },
+ { 0, 1 }, { 1, 3 }, { 1, 4 }, { 1, 5 }
+};
+
+static void __init mv88f6180_get_clk_ratio(
+ void __iomem *sar, int id, int *mult, int *div)
+{
+ switch (id) {
+ case KIRKWOOD_CPU_TO_L2:
+ {
+ /* mv88f6180 has a fixed 1:2 CPU-to-L2 ratio */
+ *mult = 1;
+ *div = 2;
+ break;
+ }
+ case KIRKWOOD_CPU_TO_DDR:
+ {
+ u32 opt = (readl(sar) >> SAR_MV88F6180_CLK) &
+ SAR_MV88F6180_CLK_MASK;
+ *mult = mv88f6180_cpu_ddr_ratios[opt][0];
+ *div = mv88f6180_cpu_ddr_ratios[opt][1];
+ break;
+ }
+ }
+}
+
+static const struct core_clocks mv88f6180_core_clocks = {
+ .get_tclk_freq = kirkwood_get_tclk_freq,
+ .get_cpu_freq = mv88f6180_get_cpu_freq,
+ .get_clk_ratio = mv88f6180_get_clk_ratio,
+ .ratios = kirkwood_core_ratios,
+ .num_ratios = ARRAY_SIZE(kirkwood_core_ratios),
+};
+#endif /* CONFIG_ARCH_KIRKWOOD */
+
+static const __initdata struct of_device_id clk_core_match[] = {
+#ifdef CONFIG_MACH_ARMADA_370_XP
+ {
+ .compatible = "marvell,370-core-clocks",
+ .data = &a370_core_clocks,
+ },
+ {
+ .compatible = "marvell,xp-core-clocks",
+ .data = &xp_core_clocks,
+ },
+#endif
+#ifdef CONFIG_ARCH_DOVE
+ {
+ .compatible = "marvell,dove-core-clocks",
+ .data = &dove_core_clocks,
+ },
+#endif
+
+#ifdef CONFIG_ARCH_KIRKWOOD
+ {
+ .compatible = "marvell,kirkwood-core-clocks",
+ .data = &kirkwood_core_clocks,
+ },
+ {
+ .compatible = "marvell,mv88f6180-core-clocks",
+ .data = &mv88f6180_core_clocks,
+ },
+#endif
+
+ { }
+};
+
+void __init mvebu_core_clk_init(void)
+{
+ struct device_node *np;
+
+ for_each_matching_node(np, clk_core_match) {
+ const struct of_device_id *match =
+ of_match_node(clk_core_match, np);
+ mvebu_clk_core_setup(np, (struct core_clocks *)match->data);
+ }
+}
diff --git a/drivers/clk/mvebu/clk-core.h b/drivers/clk/mvebu/clk-core.h
new file mode 100644
index 0000000..28b5e02
--- /dev/null
+++ b/drivers/clk/mvebu/clk-core.h
@@ -0,0 +1,18 @@
+/*
+ * * Marvell EBU clock core handling defined at reset
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MVEBU_CLK_CORE_H
+#define __MVEBU_CLK_CORE_H
+
+void __init mvebu_core_clk_init(void);
+
+#endif
diff --git a/drivers/clk/mvebu/clk.c b/drivers/clk/mvebu/clk.c
new file mode 100644
index 0000000..e6742ac
--- /dev/null
+++ b/drivers/clk/mvebu/clk.c
@@ -0,0 +1,23 @@
+/*
+ * Marvell EBU SoC clock handling.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/clk/mvebu.h>
+#include <linux/of.h>
+#include "clk-core.h"
+
+void __init mvebu_clocks_init(void)
+{
+ mvebu_core_clk_init();
+}
diff --git a/include/linux/clk/mvebu.h b/include/linux/clk/mvebu.h
new file mode 100644
index 0000000..8c4ae71
--- /dev/null
+++ b/include/linux/clk/mvebu.h
@@ -0,0 +1,22 @@
+/*
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __CLK_MVEBU_H_
+#define __CLK_MVEBU_H_
+
+void __init mvebu_clocks_init(void);
+
+#endif
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 1/7] clk: mvebu: add mvebu core clocks.
@ 2012-11-15 21:28 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
This driver allows to provide DT clocks for core clocks found on
Marvell Kirkwood, Dove & 370/XP SoCs. The core clock frequencies and
ratios are determined by decoding the Sample-At-Reset registers.
Although technically correct, using a divider of 0 will lead to
div_by_zero panic. Let's use a ratio of 0/1 instead to fail later
with a zero clock.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
.../devicetree/bindings/clock/mvebu-core-clock.txt | 47 ++
drivers/clk/Kconfig | 2 +
drivers/clk/Makefile | 1 +
drivers/clk/mvebu/Kconfig | 3 +
drivers/clk/mvebu/Makefile | 1 +
drivers/clk/mvebu/clk-core.c | 675 ++++++++++++++++++++
drivers/clk/mvebu/clk-core.h | 18 +
drivers/clk/mvebu/clk.c | 23 +
include/linux/clk/mvebu.h | 22 +
9 files changed, 792 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
create mode 100644 drivers/clk/mvebu/Kconfig
create mode 100644 drivers/clk/mvebu/Makefile
create mode 100644 drivers/clk/mvebu/clk-core.c
create mode 100644 drivers/clk/mvebu/clk-core.h
create mode 100644 drivers/clk/mvebu/clk.c
create mode 100644 include/linux/clk/mvebu.h
diff --git a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
new file mode 100644
index 0000000..84cfae7
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
@@ -0,0 +1,47 @@
+* Core Clock bindings for Marvell MVEBU SoCs
+
+Marvell MVEBU SoCs usually allow to determine core clock frequencies by
+reading the Sample-At-Reset (SAR) register. The core clock consumer should
+specify the desired clock by having the clock ID in its "clocks" phandle cell.
+
+The following is a list of provided IDs and clock names on Kirkwood and Dove:
+ 0 = tclk (Internal Bus clock)
+ 1 = cpuclk (CPU0 clock)
+ 2 = l2clk (L2 Cache clock derived from CPU0 clock)
+ 3 = ddrclk (DDR controller clock derived from CPU0 clock)
+
+The following is a list of provided IDs and clock names on 370/XP:
+ 0 = tclk (Internal Bus clock)
+ 1 = cpuclk (CPU clock)
+ 2 = nbclk (L2 Cache clock)
+ 3 = hclk (DRAM control clock)
+ 4 = dramclk (DDR clock)
+
+Required properties:
+- compatible : shall be one of the following:
+ "marvell,dove-core-clocks" - for Dove SoC core clocks
+ "marvell,kirkwood-core-clocks" - for Kirkwood SoC (except mv88f6180)
+ "marvell,mv88f6180-core-clocks" - for Kirkwood MV88f6180 SoC
+ "marvell,370-core-clocks" - For 370 SoC core clocks
+ "marvell,xp-core-clocks" - For XP SoC core clocks
+- reg : shall be the register address of the Sample-At-Reset (SAR) register
+- #clock-cells : from common clock binding; shall be set to 1
+
+Optional properties:
+- clock-output-names : from common clock binding; allows overwrite default clock
+ output names ("tclk", "cpuclk", "l2clk", "ddrclk")
+
+Example:
+
+core_clk: core-clocks at d0214 {
+ compatible = "marvell,dove-core-clocks";
+ reg = <0xd0214 0x4>;
+ #clock-cells = <1>;
+};
+
+spi0: spi at 10600 {
+ compatible = "marvell,orion-spi";
+ /* ... */
+ /* get tclk from core clock provider */
+ clocks = <&core_clk 0>;
+};
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index bace9e9..60427c0 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -54,3 +54,5 @@ config COMMON_CLK_MAX77686
This driver supports Maxim 77686 crystal oscillator clock.
endmenu
+
+source "drivers/clk/mvebu/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 71a25b9..d0a14ae 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-$(CONFIG_ARCH_U300) += clk-u300.o
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o
+obj-$(CONFIG_PLAT_ORION) += mvebu/
ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_MMP) += mmp/
endif
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
new file mode 100644
index 0000000..fd7bf97
--- /dev/null
+++ b/drivers/clk/mvebu/Kconfig
@@ -0,0 +1,3 @@
+config MVEBU_CLK_CORE
+ bool
+
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
new file mode 100644
index 0000000..de1d961
--- /dev/null
+++ b/drivers/clk/mvebu/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MVEBU_CLK_CORE) += clk.o clk-core.o
diff --git a/drivers/clk/mvebu/clk-core.c b/drivers/clk/mvebu/clk-core.c
new file mode 100644
index 0000000..26ba835
--- /dev/null
+++ b/drivers/clk/mvebu/clk-core.c
@@ -0,0 +1,675 @@
+/*
+ * Marvell EBU clock core handling defined at reset
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include "clk-core.h"
+
+struct core_ratio {
+ int id;
+ const char *name;
+};
+
+struct core_clocks {
+ u32 (*get_tclk_freq)(void __iomem *sar);
+ u32 (*get_cpu_freq)(void __iomem *sar);
+ void (*get_clk_ratio)(void __iomem *sar, int id, int *mult, int *div);
+ const struct core_ratio *ratios;
+ int num_ratios;
+};
+
+static struct clk_onecell_data clk_data;
+
+static void __init mvebu_clk_core_setup(struct device_node *np,
+ struct core_clocks *coreclk)
+{
+ const char *tclk_name = "tclk";
+ const char *cpuclk_name = "cpuclk";
+ void __iomem *base;
+ unsigned long rate;
+ int n;
+
+ base = of_iomap(np, 0);
+ if (WARN_ON(!base))
+ return;
+
+ /*
+ * Allocate struct for TCLK, cpu clk, and core ratio clocks
+ */
+ clk_data.clk_num = 2 + coreclk->num_ratios;
+ clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *),
+ GFP_KERNEL);
+ if (WARN_ON(!clk_data.clks))
+ return;
+
+ /*
+ * Register TCLK
+ */
+ of_property_read_string_index(np, "clock-output-names", 0,
+ &tclk_name);
+ rate = coreclk->get_tclk_freq(base);
+ clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL,
+ CLK_IS_ROOT, rate);
+ WARN_ON(IS_ERR(clk_data.clks[0]));
+
+ /*
+ * Register CPU clock
+ */
+ of_property_read_string_index(np, "clock-output-names", 1,
+ &cpuclk_name);
+ rate = coreclk->get_cpu_freq(base);
+ clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL,
+ CLK_IS_ROOT, rate);
+ WARN_ON(IS_ERR(clk_data.clks[1]));
+
+ /*
+ * Register fixed-factor clocks derived from CPU clock
+ */
+ for (n = 0; n < coreclk->num_ratios; n++) {
+ const char *rclk_name = coreclk->ratios[n].name;
+ int mult, div;
+
+ of_property_read_string_index(np, "clock-output-names",
+ 2+n, &rclk_name);
+ coreclk->get_clk_ratio(base, coreclk->ratios[n].id,
+ &mult, &div);
+ clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name,
+ cpuclk_name, 0, mult, div);
+ WARN_ON(IS_ERR(clk_data.clks[2+n]));
+ };
+
+ /*
+ * SAR register isn't needed anymore
+ */
+ iounmap(base);
+
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+#ifdef CONFIG_MACH_ARMADA_370_XP
+/*
+ * 370/XP Sample At Reset is a 64 bit bitfiled split in two register
+ * of 32 bits
+ */
+
+#define SARL 0 /* Low part [0:31] */
+#define SARL_AXP_PCLK_FREQ_OPT 21
+#define SARL_AXP_PCLK_FREQ_OPT_MASK 0x7
+#define SARL_A370_PCLK_FREQ_OPT 11
+#define SARL_A370_PCLK_FREQ_OPT_MASK 0xF
+#define SARL_AXP_FAB_FREQ_OPT 24
+#define SARL_AXP_FAB_FREQ_OPT_MASK 0xF
+#define SARL_A370_FAB_FREQ_OPT 15
+#define SARL_A370_FAB_FREQ_OPT_MASK 0x1F
+#define SARL_A370_TCLK_FREQ_OPT 20
+#define SARL_A370_TCLK_FREQ_OPT_MASK 0x1
+#define SARH 4 /* High part [32:63] */
+#define SARH_AXP_PCLK_FREQ_OPT (52-32)
+#define SARH_AXP_PCLK_FREQ_OPT_MASK 0x1
+#define SARH_AXP_PCLK_FREQ_OPT_SHIFT 3
+#define SARH_AXP_FAB_FREQ_OPT (51-32)
+#define SARH_AXP_FAB_FREQ_OPT_MASK 0x1
+#define SARH_AXP_FAB_FREQ_OPT_SHIFT 4
+
+static const u32 __initconst a370_tclk_frequencies[] = {
+ 16600000,
+ 20000000,
+};
+
+static u32 __init a370_get_tclk_freq(void __iomem *sar)
+{
+ u8 tclk_freq_select = 0;
+
+ tclk_freq_select = ((readl(sar) >> SARL_A370_TCLK_FREQ_OPT) &
+ SARL_A370_TCLK_FREQ_OPT_MASK);
+ return a370_tclk_frequencies[tclk_freq_select];
+}
+
+static const u32 __initconst a370_cpu_frequencies[] = {
+ 400000000,
+ 533000000,
+ 667000000,
+ 800000000,
+ 1000000000,
+ 1067000000,
+ 1200000000,
+};
+
+static u32 __init a370_get_cpu_freq(void __iomem *sar)
+{
+ u32 cpu_freq;
+ u8 cpu_freq_select = 0;
+
+ cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) &
+ SARL_A370_PCLK_FREQ_OPT_MASK);
+ if (cpu_freq_select > ARRAY_SIZE(a370_cpu_frequencies)) {
+ pr_err("CPU freq select unsuported %d\n", cpu_freq_select);
+ cpu_freq = 0;
+ } else
+ cpu_freq = a370_cpu_frequencies[cpu_freq_select];
+
+ return cpu_freq;
+}
+
+enum { A370_XP_NBCLK, A370_XP_HCLK, A370_XP_DRAMCLK };
+
+static const struct core_ratio __initconst a370_xp_core_ratios[] = {
+ { .id = A370_XP_NBCLK, .name = "nbclk" },
+ { .id = A370_XP_HCLK, .name = "hclk" },
+ { .id = A370_XP_DRAMCLK, .name = "dramclk" },
+};
+
+static const int __initconst a370_xp_nbclk_ratios[32][2] = {
+ {0, 1}, {1, 2}, {2, 2}, {2, 2},
+ {1, 2}, {1, 2}, {1, 1}, {2, 3},
+ {0, 1}, {1, 2}, {2, 4}, {0, 1},
+ {1, 2}, {0, 1}, {0, 1}, {2, 2},
+ {0, 1}, {0, 1}, {0, 1}, {1, 1},
+ {2, 3}, {0, 1}, {0, 1}, {0, 1},
+ {0, 1}, {0, 1}, {0, 1}, {1, 1},
+ {0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static const int __initconst a370_xp_hclk_ratios[32][2] = {
+ {0, 1}, {1, 2}, {2, 6}, {2, 3},
+ {1, 3}, {1, 4}, {1, 2}, {2, 6},
+ {0, 1}, {1, 6}, {2, 10}, {0, 1},
+ {1, 4}, {0, 1}, {0, 1}, {2, 5},
+ {0, 1}, {0, 1}, {0, 1}, {1, 2},
+ {2, 6}, {0, 1}, {0, 1}, {0, 1},
+ {0, 1}, {0, 1}, {0, 1}, {1, 1},
+ {0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static const int __initconst a370_xp_dramclk_ratios[32][2] = {
+ {0, 1}, {1, 2}, {2, 3}, {2, 3},
+ {1, 3}, {1, 2}, {1, 2}, {2, 6},
+ {0, 1}, {1, 3}, {2, 5}, {0, 1},
+ {1, 4}, {0, 1}, {0, 1}, {2, 5},
+ {0, 1}, {0, 1}, {0, 1}, {1, 1},
+ {2, 3}, {0, 1}, {0, 1}, {0, 1},
+ {0, 1}, {0, 1}, {0, 1}, {1, 1},
+ {0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static void __init a370_xp_get_clk_ratio(u32 opt,
+ void __iomem *sar, int id, int *mult, int *div)
+{
+ switch (id) {
+ case A370_XP_NBCLK:
+ *mult = a370_xp_nbclk_ratios[opt][0];
+ *div = a370_xp_nbclk_ratios[opt][1];
+ break;
+ case A370_XP_HCLK:
+ *mult = a370_xp_hclk_ratios[opt][0];
+ *div = a370_xp_hclk_ratios[opt][1];
+ break;
+ case A370_XP_DRAMCLK:
+ *mult = a370_xp_dramclk_ratios[opt][0];
+ *div = a370_xp_dramclk_ratios[opt][1];
+ break;
+ }
+}
+
+static void __init a370_get_clk_ratio(
+ void __iomem *sar, int id, int *mult, int *div)
+{
+ u32 opt = ((readl(sar) >> SARL_A370_FAB_FREQ_OPT) &
+ SARL_A370_FAB_FREQ_OPT_MASK);
+
+ a370_xp_get_clk_ratio(opt, sar, id, mult, div);
+}
+
+
+static const struct core_clocks a370_core_clocks = {
+ .get_tclk_freq = a370_get_tclk_freq,
+ .get_cpu_freq = a370_get_cpu_freq,
+ .get_clk_ratio = a370_get_clk_ratio,
+ .ratios = a370_xp_core_ratios,
+ .num_ratios = ARRAY_SIZE(a370_xp_core_ratios),
+};
+
+static const u32 __initconst xp_cpu_frequencies[] = {
+ 1000000000,
+ 1066000000,
+ 1200000000,
+ 1333000000,
+ 1500000000,
+ 1666000000,
+ 1800000000,
+ 2000000000,
+ 667000000,
+ 0,
+ 800000000,
+ 1600000000,
+};
+
+/* For Armada XP TCLK frequency is fix: 250MHz */
+static u32 __init xp_get_tclk_freq(void __iomem *sar)
+{
+ return 250 * 1000 * 1000;
+}
+
+static u32 __init xp_get_cpu_freq(void __iomem *sar)
+{
+ u32 cpu_freq;
+ u8 cpu_freq_select = 0;
+
+ cpu_freq_select = ((readl(sar) >> SARL_AXP_PCLK_FREQ_OPT) &
+ SARL_AXP_PCLK_FREQ_OPT_MASK);
+ /*
+ * The upper bit is not contiguous to the other ones and
+ * located in the high part of the SAR registers
+ */
+ cpu_freq_select |= (((readl(sar+4) >> SARH_AXP_PCLK_FREQ_OPT) &
+ SARH_AXP_PCLK_FREQ_OPT_MASK)
+ << SARH_AXP_PCLK_FREQ_OPT_SHIFT);
+ if (cpu_freq_select > ARRAY_SIZE(xp_cpu_frequencies)) {
+ pr_err("CPU freq select unsuported: %d\n", cpu_freq_select);
+ cpu_freq = 0;
+ } else
+ cpu_freq = xp_cpu_frequencies[cpu_freq_select];
+
+ return cpu_freq;
+}
+
+static void __init xp_get_clk_ratio(
+ void __iomem *sar, int id, int *mult, int *div)
+{
+
+ u32 opt = ((readl(sar) >> SARL_AXP_FAB_FREQ_OPT) &
+ SARL_AXP_FAB_FREQ_OPT_MASK);
+ /*
+ * The upper bit is not contiguous to the other ones and
+ * located in the high part of the SAR registers
+ */
+ opt |= (((readl(sar+4) >> SARH_AXP_FAB_FREQ_OPT) &
+ SARH_AXP_FAB_FREQ_OPT_MASK)
+ << SARH_AXP_FAB_FREQ_OPT_SHIFT);
+
+ a370_xp_get_clk_ratio(opt, sar, id, mult, div);
+}
+
+static const struct core_clocks xp_core_clocks = {
+ .get_tclk_freq = xp_get_tclk_freq,
+ .get_cpu_freq = xp_get_cpu_freq,
+ .get_clk_ratio = xp_get_clk_ratio,
+ .ratios = a370_xp_core_ratios,
+ .num_ratios = ARRAY_SIZE(a370_xp_core_ratios),
+};
+
+#endif /* CONFIG_MACH_ARMADA_370_XP */
+
+/*
+ * Dove PLL sample-at-reset configuration
+ *
+ * SAR0[8:5] : CPU frequency
+ * 5 = 1000 MHz
+ * 6 = 933 MHz
+ * 7 = 933 MHz
+ * 8 = 800 MHz
+ * 9 = 800 MHz
+ * 10 = 800 MHz
+ * 11 = 1067 MHz
+ * 12 = 667 MHz
+ * 13 = 533 MHz
+ * 14 = 400 MHz
+ * 15 = 333 MHz
+ * others reserved.
+ *
+ * SAR0[11:9] : CPU to L2 Clock divider ratio
+ * 0 = (1/1) * CPU
+ * 2 = (1/2) * CPU
+ * 4 = (1/3) * CPU
+ * 6 = (1/4) * CPU
+ * others reserved.
+ *
+ * SAR0[15:12] : CPU to DDR DRAM Clock divider ratio
+ * 0 = (1/1) * CPU
+ * 2 = (1/2) * CPU
+ * 3 = (2/5) * CPU
+ * 4 = (1/3) * CPU
+ * 6 = (1/4) * CPU
+ * 8 = (1/5) * CPU
+ * 10 = (1/6) * CPU
+ * 12 = (1/7) * CPU
+ * 14 = (1/8) * CPU
+ * 15 = (1/10) * CPU
+ * others reserved.
+ *
+ * SAR0[24:23] : TCLK frequency
+ * 0 = 166 MHz
+ * 1 = 125 MHz
+ * others reserved.
+ */
+#ifdef CONFIG_ARCH_DOVE
+#define SAR_DOVE_CPU_FREQ 5
+#define SAR_DOVE_CPU_FREQ_MASK 0xf
+#define SAR_DOVE_L2_RATIO 9
+#define SAR_DOVE_L2_RATIO_MASK 0x7
+#define SAR_DOVE_DDR_RATIO 12
+#define SAR_DOVE_DDR_RATIO_MASK 0xf
+#define SAR_DOVE_TCLK_FREQ 23
+#define SAR_DOVE_TCLK_FREQ_MASK 0x3
+
+static const u32 __initconst dove_tclk_frequencies[] = {
+ 166666667,
+ 125000000,
+ 0, 0
+};
+
+static u32 __init dove_get_tclk_freq(void __iomem *sar)
+{
+ u32 opt = (readl(sar) >> SAR_DOVE_TCLK_FREQ) &
+ SAR_DOVE_TCLK_FREQ_MASK;
+ return dove_tclk_frequencies[opt];
+}
+
+static const u32 __initconst dove_cpu_frequencies[] = {
+ 0, 0, 0, 0, 0,
+ 1000000000,
+ 933333333, 933333333,
+ 800000000, 800000000, 800000000,
+ 1066666667,
+ 666666667,
+ 533333333,
+ 400000000,
+ 333333333
+};
+
+static u32 __init dove_get_cpu_freq(void __iomem *sar)
+{
+ u32 opt = (readl(sar) >> SAR_DOVE_CPU_FREQ) &
+ SAR_DOVE_CPU_FREQ_MASK;
+ return dove_cpu_frequencies[opt];
+}
+
+enum { DOVE_CPU_TO_L2, DOVE_CPU_TO_DDR };
+
+static const struct core_ratio __initconst dove_core_ratios[] = {
+ { .id = DOVE_CPU_TO_L2, .name = "l2clk", },
+ { .id = DOVE_CPU_TO_DDR, .name = "ddrclk", }
+};
+
+static const int __initconst dove_cpu_l2_ratios[8][2] = {
+ { 1, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
+ { 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 }
+};
+
+static const int __initconst dove_cpu_ddr_ratios[16][2] = {
+ { 1, 1 }, { 0, 1 }, { 1, 2 }, { 2, 5 },
+ { 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 },
+ { 1, 5 }, { 0, 1 }, { 1, 6 }, { 0, 1 },
+ { 1, 7 }, { 0, 1 }, { 1, 8 }, { 1, 10 }
+};
+
+static void __init dove_get_clk_ratio(
+ void __iomem *sar, int id, int *mult, int *div)
+{
+ switch (id) {
+ case DOVE_CPU_TO_L2:
+ {
+ u32 opt = (readl(sar) >> SAR_DOVE_L2_RATIO) &
+ SAR_DOVE_L2_RATIO_MASK;
+ *mult = dove_cpu_l2_ratios[opt][0];
+ *div = dove_cpu_l2_ratios[opt][1];
+ break;
+ }
+ case DOVE_CPU_TO_DDR:
+ {
+ u32 opt = (readl(sar) >> SAR_DOVE_DDR_RATIO) &
+ SAR_DOVE_DDR_RATIO_MASK;
+ *mult = dove_cpu_ddr_ratios[opt][0];
+ *div = dove_cpu_ddr_ratios[opt][1];
+ break;
+ }
+ }
+}
+
+static const struct core_clocks dove_core_clocks = {
+ .get_tclk_freq = dove_get_tclk_freq,
+ .get_cpu_freq = dove_get_cpu_freq,
+ .get_clk_ratio = dove_get_clk_ratio,
+ .ratios = dove_core_ratios,
+ .num_ratios = ARRAY_SIZE(dove_core_ratios),
+};
+#endif /* CONFIG_ARCH_DOVE */
+
+/*
+ * Kirkwood PLL sample-at-reset configuration
+ * (6180 has different SAR layout than other Kirkwood SoCs)
+ *
+ * SAR0[4:3,22,1] : CPU frequency (6281,6292,6282)
+ * 4 = 600 MHz
+ * 6 = 800 MHz
+ * 7 = 1000 MHz
+ * 9 = 1200 MHz
+ * 12 = 1500 MHz
+ * 13 = 1600 MHz
+ * 14 = 1800 MHz
+ * 15 = 2000 MHz
+ * others reserved.
+ *
+ * SAR0[19,10:9] : CPU to L2 Clock divider ratio (6281,6292,6282)
+ * 1 = (1/2) * CPU
+ * 3 = (1/3) * CPU
+ * 5 = (1/4) * CPU
+ * others reserved.
+ *
+ * SAR0[8:5] : CPU to DDR DRAM Clock divider ratio (6281,6292,6282)
+ * 2 = (1/2) * CPU
+ * 4 = (1/3) * CPU
+ * 6 = (1/4) * CPU
+ * 7 = (2/9) * CPU
+ * 8 = (1/5) * CPU
+ * 9 = (1/6) * CPU
+ * others reserved.
+ *
+ * SAR0[4:2] : Kirkwood 6180 cpu/l2/ddr clock configuration (6180 only)
+ * 5 = [CPU = 600 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/3) * CPU]
+ * 6 = [CPU = 800 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/4) * CPU]
+ * 7 = [CPU = 1000 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/5) * CPU]
+ * others reserved.
+ *
+ * SAR0[21] : TCLK frequency
+ * 0 = 200 MHz
+ * 1 = 166 MHz
+ * others reserved.
+ */
+#ifdef CONFIG_ARCH_KIRKWOOD
+#define SAR_KIRKWOOD_CPU_FREQ(x) \
+ (((x & (1 << 1)) >> 1) | \
+ ((x & (1 << 22)) >> 21) | \
+ ((x & (3 << 3)) >> 1))
+#define SAR_KIRKWOOD_L2_RATIO(x) \
+ (((x & (3 << 9)) >> 9) | \
+ (((x & (1 << 19)) >> 17)))
+#define SAR_KIRKWOOD_DDR_RATIO 5
+#define SAR_KIRKWOOD_DDR_RATIO_MASK 0xf
+#define SAR_MV88F6180_CLK 2
+#define SAR_MV88F6180_CLK_MASK 0x7
+#define SAR_KIRKWOOD_TCLK_FREQ 21
+#define SAR_KIRKWOOD_TCLK_FREQ_MASK 0x1
+
+enum { KIRKWOOD_CPU_TO_L2, KIRKWOOD_CPU_TO_DDR };
+
+static const struct core_ratio __initconst kirkwood_core_ratios[] = {
+ { .id = KIRKWOOD_CPU_TO_L2, .name = "l2clk", },
+ { .id = KIRKWOOD_CPU_TO_DDR, .name = "ddrclk", }
+};
+
+static u32 __init kirkwood_get_tclk_freq(void __iomem *sar)
+{
+ u32 opt = (readl(sar) >> SAR_KIRKWOOD_TCLK_FREQ) &
+ SAR_KIRKWOOD_TCLK_FREQ_MASK;
+ return (opt) ? 166666667 : 200000000;
+}
+
+static const u32 __initconst kirkwood_cpu_frequencies[] = {
+ 0, 0, 0, 0,
+ 600000000,
+ 0,
+ 800000000,
+ 1000000000,
+ 0,
+ 1200000000,
+ 0, 0,
+ 1500000000,
+ 1600000000,
+ 1800000000,
+ 2000000000
+};
+
+static u32 __init kirkwood_get_cpu_freq(void __iomem *sar)
+{
+ u32 opt = SAR_KIRKWOOD_CPU_FREQ(readl(sar));
+ return kirkwood_cpu_frequencies[opt];
+}
+
+static const int __initconst kirkwood_cpu_l2_ratios[8][2] = {
+ { 0, 1 }, { 1, 2 }, { 0, 1 }, { 1, 3 },
+ { 0, 1 }, { 1, 4 }, { 0, 1 }, { 0, 1 }
+};
+
+static const int __initconst kirkwood_cpu_ddr_ratios[16][2] = {
+ { 0, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
+ { 1, 3 }, { 0, 1 }, { 1, 4 }, { 2, 9 },
+ { 1, 5 }, { 1, 6 }, { 0, 1 }, { 0, 1 },
+ { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }
+};
+
+static void __init kirkwood_get_clk_ratio(
+ void __iomem *sar, int id, int *mult, int *div)
+{
+ switch (id) {
+ case KIRKWOOD_CPU_TO_L2:
+ {
+ u32 opt = SAR_KIRKWOOD_L2_RATIO(readl(sar));
+ *mult = kirkwood_cpu_l2_ratios[opt][0];
+ *div = kirkwood_cpu_l2_ratios[opt][1];
+ break;
+ }
+ case KIRKWOOD_CPU_TO_DDR:
+ {
+ u32 opt = (readl(sar) >> SAR_KIRKWOOD_DDR_RATIO) &
+ SAR_KIRKWOOD_DDR_RATIO_MASK;
+ *mult = kirkwood_cpu_ddr_ratios[opt][0];
+ *div = kirkwood_cpu_ddr_ratios[opt][1];
+ break;
+ }
+ }
+}
+
+static const struct core_clocks kirkwood_core_clocks = {
+ .get_tclk_freq = kirkwood_get_tclk_freq,
+ .get_cpu_freq = kirkwood_get_cpu_freq,
+ .get_clk_ratio = kirkwood_get_clk_ratio,
+ .ratios = kirkwood_core_ratios,
+ .num_ratios = ARRAY_SIZE(kirkwood_core_ratios),
+};
+
+static const u32 __initconst mv88f6180_cpu_frequencies[] = {
+ 0, 0, 0, 0, 0,
+ 600000000,
+ 800000000,
+ 1000000000
+};
+
+static u32 __init mv88f6180_get_cpu_freq(void __iomem *sar)
+{
+ u32 opt = (readl(sar) >> SAR_MV88F6180_CLK) & SAR_MV88F6180_CLK_MASK;
+ return mv88f6180_cpu_frequencies[opt];
+}
+
+static const int __initconst mv88f6180_cpu_ddr_ratios[8][2] = {
+ { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 },
+ { 0, 1 }, { 1, 3 }, { 1, 4 }, { 1, 5 }
+};
+
+static void __init mv88f6180_get_clk_ratio(
+ void __iomem *sar, int id, int *mult, int *div)
+{
+ switch (id) {
+ case KIRKWOOD_CPU_TO_L2:
+ {
+ /* mv88f6180 has a fixed 1:2 CPU-to-L2 ratio */
+ *mult = 1;
+ *div = 2;
+ break;
+ }
+ case KIRKWOOD_CPU_TO_DDR:
+ {
+ u32 opt = (readl(sar) >> SAR_MV88F6180_CLK) &
+ SAR_MV88F6180_CLK_MASK;
+ *mult = mv88f6180_cpu_ddr_ratios[opt][0];
+ *div = mv88f6180_cpu_ddr_ratios[opt][1];
+ break;
+ }
+ }
+}
+
+static const struct core_clocks mv88f6180_core_clocks = {
+ .get_tclk_freq = kirkwood_get_tclk_freq,
+ .get_cpu_freq = mv88f6180_get_cpu_freq,
+ .get_clk_ratio = mv88f6180_get_clk_ratio,
+ .ratios = kirkwood_core_ratios,
+ .num_ratios = ARRAY_SIZE(kirkwood_core_ratios),
+};
+#endif /* CONFIG_ARCH_KIRKWOOD */
+
+static const __initdata struct of_device_id clk_core_match[] = {
+#ifdef CONFIG_MACH_ARMADA_370_XP
+ {
+ .compatible = "marvell,370-core-clocks",
+ .data = &a370_core_clocks,
+ },
+ {
+ .compatible = "marvell,xp-core-clocks",
+ .data = &xp_core_clocks,
+ },
+#endif
+#ifdef CONFIG_ARCH_DOVE
+ {
+ .compatible = "marvell,dove-core-clocks",
+ .data = &dove_core_clocks,
+ },
+#endif
+
+#ifdef CONFIG_ARCH_KIRKWOOD
+ {
+ .compatible = "marvell,kirkwood-core-clocks",
+ .data = &kirkwood_core_clocks,
+ },
+ {
+ .compatible = "marvell,mv88f6180-core-clocks",
+ .data = &mv88f6180_core_clocks,
+ },
+#endif
+
+ { }
+};
+
+void __init mvebu_core_clk_init(void)
+{
+ struct device_node *np;
+
+ for_each_matching_node(np, clk_core_match) {
+ const struct of_device_id *match =
+ of_match_node(clk_core_match, np);
+ mvebu_clk_core_setup(np, (struct core_clocks *)match->data);
+ }
+}
diff --git a/drivers/clk/mvebu/clk-core.h b/drivers/clk/mvebu/clk-core.h
new file mode 100644
index 0000000..28b5e02
--- /dev/null
+++ b/drivers/clk/mvebu/clk-core.h
@@ -0,0 +1,18 @@
+/*
+ * * Marvell EBU clock core handling defined at reset
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MVEBU_CLK_CORE_H
+#define __MVEBU_CLK_CORE_H
+
+void __init mvebu_core_clk_init(void);
+
+#endif
diff --git a/drivers/clk/mvebu/clk.c b/drivers/clk/mvebu/clk.c
new file mode 100644
index 0000000..e6742ac
--- /dev/null
+++ b/drivers/clk/mvebu/clk.c
@@ -0,0 +1,23 @@
+/*
+ * Marvell EBU SoC clock handling.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/clk/mvebu.h>
+#include <linux/of.h>
+#include "clk-core.h"
+
+void __init mvebu_clocks_init(void)
+{
+ mvebu_core_clk_init();
+}
diff --git a/include/linux/clk/mvebu.h b/include/linux/clk/mvebu.h
new file mode 100644
index 0000000..8c4ae71
--- /dev/null
+++ b/include/linux/clk/mvebu.h
@@ -0,0 +1,22 @@
+/*
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __CLK_MVEBU_H_
+#define __CLK_MVEBU_H_
+
+void __init mvebu_clocks_init(void);
+
+#endif
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 2/7] clk: mvebu: add armada-370-xp CPU specific clocks
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:28 ` Andrew Lunn
-1 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: mturquette
Cc: Thomas Petazzoni, Gregory Clement, devicetree-discuss,
Jason Cooper, linux ARM
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Add Armada 370/XP specific CPU clocks
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
.../devicetree/bindings/clock/mvebu-core-clock.txt | 18 +--
.../devicetree/bindings/clock/mvebu-cpu-clock.txt | 21 +++
drivers/clk/mvebu/Kconfig | 3 +
drivers/clk/mvebu/Makefile | 1 +
drivers/clk/mvebu/clk-core.c | 4 +-
drivers/clk/mvebu/clk-cpu.c | 155 ++++++++++++++++++++
drivers/clk/mvebu/clk-cpu.h | 18 +++
drivers/clk/mvebu/clk.c | 14 ++
8 files changed, 223 insertions(+), 11 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
create mode 100644 drivers/clk/mvebu/clk-cpu.c
create mode 100644 drivers/clk/mvebu/clk-cpu.h
diff --git a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
index 84cfae7..ffb3d69 100644
--- a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
+++ b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
@@ -4,26 +4,26 @@ Marvell MVEBU SoCs usually allow to determine core clock frequencies by
reading the Sample-At-Reset (SAR) register. The core clock consumer should
specify the desired clock by having the clock ID in its "clocks" phandle cell.
-The following is a list of provided IDs and clock names on Kirkwood and Dove:
- 0 = tclk (Internal Bus clock)
- 1 = cpuclk (CPU0 clock)
- 2 = l2clk (L2 Cache clock derived from CPU0 clock)
- 3 = ddrclk (DDR controller clock derived from CPU0 clock)
-
-The following is a list of provided IDs and clock names on 370/XP:
+The following is a list of provided IDs and clock names on Armada 370/XP:
0 = tclk (Internal Bus clock)
1 = cpuclk (CPU clock)
2 = nbclk (L2 Cache clock)
3 = hclk (DRAM control clock)
4 = dramclk (DDR clock)
+The following is a list of provided IDs and clock names on Kirkwood and Dove:
+ 0 = tclk (Internal Bus clock)
+ 1 = cpuclk (CPU0 clock)
+ 2 = l2clk (L2 Cache clock derived from CPU0 clock)
+ 3 = ddrclk (DDR controller clock derived from CPU0 clock)
+
Required properties:
- compatible : shall be one of the following:
+ "marvell,armada-370-core-clocks" - For Armada 370 SoC core clocks
+ "marvell,armada-xp-core-clocks" - For Armada XP SoC core clocks
"marvell,dove-core-clocks" - for Dove SoC core clocks
"marvell,kirkwood-core-clocks" - for Kirkwood SoC (except mv88f6180)
"marvell,mv88f6180-core-clocks" - for Kirkwood MV88f6180 SoC
- "marvell,370-core-clocks" - For 370 SoC core clocks
- "marvell,xp-core-clocks" - For XP SoC core clocks
- reg : shall be the register address of the Sample-At-Reset (SAR) register
- #clock-cells : from common clock binding; shall be set to 1
diff --git a/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
new file mode 100644
index 0000000..1fb5a64
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
@@ -0,0 +1,21 @@
+Device Tree Clock bindings for cpu clock of Marvell EBU platforms
+
+Required properties:
+- compatible : shall be one of the following:
+ "marvell,armada-xp-cpu-clockctrl" - cpu clocks for Armada XP
+- reg : Address and length of the clock complex register set
+- #clock-cells : should be set to 1.
+- clocks : shall be the input parent clock phandle for the clock.
+
+cpuclk: clock-complex@d0018700 {
+ #clock-cells = <1>;
+ compatible = "marvell,armada-xp-cpu-clockctrl";
+ reg = <0xd0018700 0xA0>;
+ clocks = <&coreclk 1>;
+}
+
+cpu@0 {
+ compatible = "marvell,sheeva-v7";
+ reg = <0>;
+ clocks = <&cpuclk 0>;
+};
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
index fd7bf97..1dd93ad 100644
--- a/drivers/clk/mvebu/Kconfig
+++ b/drivers/clk/mvebu/Kconfig
@@ -1,3 +1,6 @@
config MVEBU_CLK_CORE
bool
+config MVEBU_CLK_CPU
+ bool
+
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
index de1d961..93da083 100644
--- a/drivers/clk/mvebu/Makefile
+++ b/drivers/clk/mvebu/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_MVEBU_CLK_CORE) += clk.o clk-core.o
+obj-$(CONFIG_MVEBU_CLK_CPU) += clk-cpu.o
diff --git a/drivers/clk/mvebu/clk-core.c b/drivers/clk/mvebu/clk-core.c
index 26ba835..1881872 100644
--- a/drivers/clk/mvebu/clk-core.c
+++ b/drivers/clk/mvebu/clk-core.c
@@ -634,11 +634,11 @@ static const struct core_clocks mv88f6180_core_clocks = {
static const __initdata struct of_device_id clk_core_match[] = {
#ifdef CONFIG_MACH_ARMADA_370_XP
{
- .compatible = "marvell,370-core-clocks",
+ .compatible = "marvell,armada-370-core-clocks",
.data = &a370_core_clocks,
},
{
- .compatible = "marvell,xp-core-clocks",
+ .compatible = "marvell,armada-xp-core-clocks",
.data = &xp_core_clocks,
},
#endif
diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c
new file mode 100644
index 0000000..1df027a
--- /dev/null
+++ b/drivers/clk/mvebu/clk-cpu.c
@@ -0,0 +1,155 @@
+/*
+ * Marvell MVEBU CPU clock handling.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+#include "clk-cpu.h"
+
+#define SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET 0x0
+#define SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET 0xC
+#define SYS_CTRL_CLK_DIVIDER_MASK 0x3F
+
+#define MAX_CPU 4
+struct cpu_clk {
+ struct clk_hw hw;
+ int cpu;
+ const char *clk_name;
+ const char *parent_name;
+ void __iomem *reg_base;
+};
+
+static struct clk **clks;
+
+static struct clk_onecell_data clk_data;
+
+#define to_cpu_clk(p) container_of(p, struct cpu_clk, hw)
+
+static unsigned long clk_cpu_recalc_rate(struct clk_hw *hwclk,
+ unsigned long parent_rate)
+{
+ struct cpu_clk *cpuclk = to_cpu_clk(hwclk);
+ u32 reg, div;
+
+ reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET);
+ div = (reg >> (cpuclk->cpu * 8)) & SYS_CTRL_CLK_DIVIDER_MASK;
+ return parent_rate / div;
+}
+
+static long clk_cpu_round_rate(struct clk_hw *hwclk, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ /* Valid ratio are 1:1, 1:2 and 1:3 */
+ u32 div;
+
+ div = *parent_rate / rate;
+ if (div == 0)
+ div = 1;
+ else if (div > 3)
+ div = 3;
+
+ return *parent_rate / div;
+}
+
+static int clk_cpu_set_rate(struct clk_hw *hwclk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct cpu_clk *cpuclk = to_cpu_clk(hwclk);
+ u32 reg, div;
+ u32 reload_mask;
+
+ div = parent_rate / rate;
+ reg = (readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET)
+ & (~(SYS_CTRL_CLK_DIVIDER_MASK << (cpuclk->cpu * 8))))
+ | (div << (cpuclk->cpu * 8));
+ writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET);
+ /* Set clock divider reload smooth bit mask */
+ reload_mask = 1 << (20 + cpuclk->cpu);
+
+ reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET)
+ | reload_mask;
+ writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
+
+ /* Now trigger the clock update */
+ reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET)
+ | 1 << 24;
+ writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
+
+ /* Wait for clocks to settle down then clear reload request */
+ udelay(1000);
+ reg &= ~(reload_mask | 1 << 24);
+ writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
+ udelay(1000);
+
+ return 0;
+}
+
+static const struct clk_ops cpu_ops = {
+ .recalc_rate = clk_cpu_recalc_rate,
+ .round_rate = clk_cpu_round_rate,
+ .set_rate = clk_cpu_set_rate,
+};
+
+void __init of_cpu_clk_setup(struct device_node *node)
+{
+ struct cpu_clk *cpuclk;
+ void __iomem *clock_complex_base = of_iomap(node, 0);
+ int cpu;
+ if (clock_complex_base == NULL) {
+ pr_err("%s: clock-complex base register not set\n",
+ __func__);
+ return;
+ }
+
+ cpuclk = kzalloc(MAX_CPU * sizeof(*cpuclk), GFP_KERNEL);
+ clks = kzalloc(MAX_CPU * sizeof(*clks), GFP_KERNEL);
+
+ if (WARN_ON(!cpuclk))
+ return;
+ for (cpu = 0; cpu < MAX_CPU; cpu++) {
+ struct clk_init_data init;
+ struct clk *clk;
+ struct clk *parent_clk;
+ char *clk_name = kzalloc(5, GFP_KERNEL);
+
+ sprintf(clk_name, "cpu%d", cpu);
+ parent_clk = of_clk_get(node, 0);
+
+ cpuclk[cpu].parent_name = __clk_get_name(parent_clk);
+ cpuclk[cpu].clk_name = clk_name;
+ cpuclk[cpu].cpu = cpu;
+ cpuclk[cpu].reg_base = clock_complex_base;
+ cpuclk[cpu].hw.init = &init;
+
+ init.name = cpuclk[cpu].clk_name;
+ init.ops = &cpu_ops;
+ init.flags = 0;
+ init.parent_names = &cpuclk[cpu].parent_name;
+ init.num_parents = 1;
+
+ clk = clk_register(NULL, &cpuclk[cpu].hw);
+ if (WARN_ON(IS_ERR(clk)))
+ goto bail_out;
+ clks[cpu] = clk;
+ }
+ clk_data.clk_num = MAX_CPU;
+ clk_data.clks = clks;
+ of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
+
+ return;
+bail_out:
+ kfree(clks);
+ kfree(cpuclk);
+}
diff --git a/drivers/clk/mvebu/clk-cpu.h b/drivers/clk/mvebu/clk-cpu.h
new file mode 100644
index 0000000..e208336
--- /dev/null
+++ b/drivers/clk/mvebu/clk-cpu.h
@@ -0,0 +1,18 @@
+/*
+ * Marvell MVEBU CPU clock handling.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MVEBU_CLK_CPU_H
+#define __MVEBU_CLK_CPU_H
+
+void __init of_cpu_clk_setup(struct device_node *node);
+
+#endif
diff --git a/drivers/clk/mvebu/clk.c b/drivers/clk/mvebu/clk.c
index e6742ac..dc310d6 100644
--- a/drivers/clk/mvebu/clk.c
+++ b/drivers/clk/mvebu/clk.c
@@ -16,8 +16,22 @@
#include <linux/clk/mvebu.h>
#include <linux/of.h>
#include "clk-core.h"
+#include "clk-cpu.h"
+
+static const __initconst struct of_device_id clk_match[] = {
+#ifdef CONFIG_MVEBU_CLK_CPU
+ {
+ .compatible = "marvell,armada-xp-cpu-clockctrl",
+ .data = of_cpu_clk_setup,
+ },
+#endif
+ {
+ /* sentinel */
+ }
+};
void __init mvebu_clocks_init(void)
{
mvebu_core_clk_init();
+ of_clk_init(clk_match);
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 2/7] clk: mvebu: add armada-370-xp CPU specific clocks
@ 2012-11-15 21:28 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Add Armada 370/XP specific CPU clocks
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
.../devicetree/bindings/clock/mvebu-core-clock.txt | 18 +--
.../devicetree/bindings/clock/mvebu-cpu-clock.txt | 21 +++
drivers/clk/mvebu/Kconfig | 3 +
drivers/clk/mvebu/Makefile | 1 +
drivers/clk/mvebu/clk-core.c | 4 +-
drivers/clk/mvebu/clk-cpu.c | 155 ++++++++++++++++++++
drivers/clk/mvebu/clk-cpu.h | 18 +++
drivers/clk/mvebu/clk.c | 14 ++
8 files changed, 223 insertions(+), 11 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
create mode 100644 drivers/clk/mvebu/clk-cpu.c
create mode 100644 drivers/clk/mvebu/clk-cpu.h
diff --git a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
index 84cfae7..ffb3d69 100644
--- a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
+++ b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
@@ -4,26 +4,26 @@ Marvell MVEBU SoCs usually allow to determine core clock frequencies by
reading the Sample-At-Reset (SAR) register. The core clock consumer should
specify the desired clock by having the clock ID in its "clocks" phandle cell.
-The following is a list of provided IDs and clock names on Kirkwood and Dove:
- 0 = tclk (Internal Bus clock)
- 1 = cpuclk (CPU0 clock)
- 2 = l2clk (L2 Cache clock derived from CPU0 clock)
- 3 = ddrclk (DDR controller clock derived from CPU0 clock)
-
-The following is a list of provided IDs and clock names on 370/XP:
+The following is a list of provided IDs and clock names on Armada 370/XP:
0 = tclk (Internal Bus clock)
1 = cpuclk (CPU clock)
2 = nbclk (L2 Cache clock)
3 = hclk (DRAM control clock)
4 = dramclk (DDR clock)
+The following is a list of provided IDs and clock names on Kirkwood and Dove:
+ 0 = tclk (Internal Bus clock)
+ 1 = cpuclk (CPU0 clock)
+ 2 = l2clk (L2 Cache clock derived from CPU0 clock)
+ 3 = ddrclk (DDR controller clock derived from CPU0 clock)
+
Required properties:
- compatible : shall be one of the following:
+ "marvell,armada-370-core-clocks" - For Armada 370 SoC core clocks
+ "marvell,armada-xp-core-clocks" - For Armada XP SoC core clocks
"marvell,dove-core-clocks" - for Dove SoC core clocks
"marvell,kirkwood-core-clocks" - for Kirkwood SoC (except mv88f6180)
"marvell,mv88f6180-core-clocks" - for Kirkwood MV88f6180 SoC
- "marvell,370-core-clocks" - For 370 SoC core clocks
- "marvell,xp-core-clocks" - For XP SoC core clocks
- reg : shall be the register address of the Sample-At-Reset (SAR) register
- #clock-cells : from common clock binding; shall be set to 1
diff --git a/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
new file mode 100644
index 0000000..1fb5a64
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
@@ -0,0 +1,21 @@
+Device Tree Clock bindings for cpu clock of Marvell EBU platforms
+
+Required properties:
+- compatible : shall be one of the following:
+ "marvell,armada-xp-cpu-clockctrl" - cpu clocks for Armada XP
+- reg : Address and length of the clock complex register set
+- #clock-cells : should be set to 1.
+- clocks : shall be the input parent clock phandle for the clock.
+
+cpuclk: clock-complex at d0018700 {
+ #clock-cells = <1>;
+ compatible = "marvell,armada-xp-cpu-clockctrl";
+ reg = <0xd0018700 0xA0>;
+ clocks = <&coreclk 1>;
+}
+
+cpu at 0 {
+ compatible = "marvell,sheeva-v7";
+ reg = <0>;
+ clocks = <&cpuclk 0>;
+};
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
index fd7bf97..1dd93ad 100644
--- a/drivers/clk/mvebu/Kconfig
+++ b/drivers/clk/mvebu/Kconfig
@@ -1,3 +1,6 @@
config MVEBU_CLK_CORE
bool
+config MVEBU_CLK_CPU
+ bool
+
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
index de1d961..93da083 100644
--- a/drivers/clk/mvebu/Makefile
+++ b/drivers/clk/mvebu/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_MVEBU_CLK_CORE) += clk.o clk-core.o
+obj-$(CONFIG_MVEBU_CLK_CPU) += clk-cpu.o
diff --git a/drivers/clk/mvebu/clk-core.c b/drivers/clk/mvebu/clk-core.c
index 26ba835..1881872 100644
--- a/drivers/clk/mvebu/clk-core.c
+++ b/drivers/clk/mvebu/clk-core.c
@@ -634,11 +634,11 @@ static const struct core_clocks mv88f6180_core_clocks = {
static const __initdata struct of_device_id clk_core_match[] = {
#ifdef CONFIG_MACH_ARMADA_370_XP
{
- .compatible = "marvell,370-core-clocks",
+ .compatible = "marvell,armada-370-core-clocks",
.data = &a370_core_clocks,
},
{
- .compatible = "marvell,xp-core-clocks",
+ .compatible = "marvell,armada-xp-core-clocks",
.data = &xp_core_clocks,
},
#endif
diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c
new file mode 100644
index 0000000..1df027a
--- /dev/null
+++ b/drivers/clk/mvebu/clk-cpu.c
@@ -0,0 +1,155 @@
+/*
+ * Marvell MVEBU CPU clock handling.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+#include "clk-cpu.h"
+
+#define SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET 0x0
+#define SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET 0xC
+#define SYS_CTRL_CLK_DIVIDER_MASK 0x3F
+
+#define MAX_CPU 4
+struct cpu_clk {
+ struct clk_hw hw;
+ int cpu;
+ const char *clk_name;
+ const char *parent_name;
+ void __iomem *reg_base;
+};
+
+static struct clk **clks;
+
+static struct clk_onecell_data clk_data;
+
+#define to_cpu_clk(p) container_of(p, struct cpu_clk, hw)
+
+static unsigned long clk_cpu_recalc_rate(struct clk_hw *hwclk,
+ unsigned long parent_rate)
+{
+ struct cpu_clk *cpuclk = to_cpu_clk(hwclk);
+ u32 reg, div;
+
+ reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET);
+ div = (reg >> (cpuclk->cpu * 8)) & SYS_CTRL_CLK_DIVIDER_MASK;
+ return parent_rate / div;
+}
+
+static long clk_cpu_round_rate(struct clk_hw *hwclk, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ /* Valid ratio are 1:1, 1:2 and 1:3 */
+ u32 div;
+
+ div = *parent_rate / rate;
+ if (div == 0)
+ div = 1;
+ else if (div > 3)
+ div = 3;
+
+ return *parent_rate / div;
+}
+
+static int clk_cpu_set_rate(struct clk_hw *hwclk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct cpu_clk *cpuclk = to_cpu_clk(hwclk);
+ u32 reg, div;
+ u32 reload_mask;
+
+ div = parent_rate / rate;
+ reg = (readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET)
+ & (~(SYS_CTRL_CLK_DIVIDER_MASK << (cpuclk->cpu * 8))))
+ | (div << (cpuclk->cpu * 8));
+ writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET);
+ /* Set clock divider reload smooth bit mask */
+ reload_mask = 1 << (20 + cpuclk->cpu);
+
+ reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET)
+ | reload_mask;
+ writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
+
+ /* Now trigger the clock update */
+ reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET)
+ | 1 << 24;
+ writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
+
+ /* Wait for clocks to settle down then clear reload request */
+ udelay(1000);
+ reg &= ~(reload_mask | 1 << 24);
+ writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
+ udelay(1000);
+
+ return 0;
+}
+
+static const struct clk_ops cpu_ops = {
+ .recalc_rate = clk_cpu_recalc_rate,
+ .round_rate = clk_cpu_round_rate,
+ .set_rate = clk_cpu_set_rate,
+};
+
+void __init of_cpu_clk_setup(struct device_node *node)
+{
+ struct cpu_clk *cpuclk;
+ void __iomem *clock_complex_base = of_iomap(node, 0);
+ int cpu;
+ if (clock_complex_base == NULL) {
+ pr_err("%s: clock-complex base register not set\n",
+ __func__);
+ return;
+ }
+
+ cpuclk = kzalloc(MAX_CPU * sizeof(*cpuclk), GFP_KERNEL);
+ clks = kzalloc(MAX_CPU * sizeof(*clks), GFP_KERNEL);
+
+ if (WARN_ON(!cpuclk))
+ return;
+ for (cpu = 0; cpu < MAX_CPU; cpu++) {
+ struct clk_init_data init;
+ struct clk *clk;
+ struct clk *parent_clk;
+ char *clk_name = kzalloc(5, GFP_KERNEL);
+
+ sprintf(clk_name, "cpu%d", cpu);
+ parent_clk = of_clk_get(node, 0);
+
+ cpuclk[cpu].parent_name = __clk_get_name(parent_clk);
+ cpuclk[cpu].clk_name = clk_name;
+ cpuclk[cpu].cpu = cpu;
+ cpuclk[cpu].reg_base = clock_complex_base;
+ cpuclk[cpu].hw.init = &init;
+
+ init.name = cpuclk[cpu].clk_name;
+ init.ops = &cpu_ops;
+ init.flags = 0;
+ init.parent_names = &cpuclk[cpu].parent_name;
+ init.num_parents = 1;
+
+ clk = clk_register(NULL, &cpuclk[cpu].hw);
+ if (WARN_ON(IS_ERR(clk)))
+ goto bail_out;
+ clks[cpu] = clk;
+ }
+ clk_data.clk_num = MAX_CPU;
+ clk_data.clks = clks;
+ of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
+
+ return;
+bail_out:
+ kfree(clks);
+ kfree(cpuclk);
+}
diff --git a/drivers/clk/mvebu/clk-cpu.h b/drivers/clk/mvebu/clk-cpu.h
new file mode 100644
index 0000000..e208336
--- /dev/null
+++ b/drivers/clk/mvebu/clk-cpu.h
@@ -0,0 +1,18 @@
+/*
+ * Marvell MVEBU CPU clock handling.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MVEBU_CLK_CPU_H
+#define __MVEBU_CLK_CPU_H
+
+void __init of_cpu_clk_setup(struct device_node *node);
+
+#endif
diff --git a/drivers/clk/mvebu/clk.c b/drivers/clk/mvebu/clk.c
index e6742ac..dc310d6 100644
--- a/drivers/clk/mvebu/clk.c
+++ b/drivers/clk/mvebu/clk.c
@@ -16,8 +16,22 @@
#include <linux/clk/mvebu.h>
#include <linux/of.h>
#include "clk-core.h"
+#include "clk-cpu.h"
+
+static const __initconst struct of_device_id clk_match[] = {
+#ifdef CONFIG_MVEBU_CLK_CPU
+ {
+ .compatible = "marvell,armada-xp-cpu-clockctrl",
+ .data = of_cpu_clk_setup,
+ },
+#endif
+ {
+ /* sentinel */
+ }
+};
void __init mvebu_clocks_init(void)
{
mvebu_core_clk_init();
+ of_clk_init(clk_match);
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 3/7] clk: armada-370-xp: add support for clock framework
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:28 ` Andrew Lunn
-1 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: mturquette
Cc: Thomas Petazzoni, Gregory Clement, devicetree-discuss,
Jason Cooper, linux ARM
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-370.dtsi | 7 ++++++
arch/arm/boot/dts/armada-xp.dtsi | 42 +++++++++++++++++++++++++++++++++++
arch/arm/mach-mvebu/Kconfig | 6 +++++
arch/arm/mach-mvebu/armada-370-xp.c | 9 +++++++-
4 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index 2069151..dae966c 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -75,5 +75,12 @@
#interrupts-cells = <2>;
interrupts = <91>;
};
+
+ coreclk: mvebu-sar@d0018230 {
+ compatible = "marvell,armada-370-core-clocks";
+ reg = <0xd0018230 0x08>;
+ #clock-cells = <1>;
+ };
+
};
};
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index 71d6b5d..f8382a8 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -27,6 +27,35 @@
<0xd0021870 0x58>;
};
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "marvell,sheeva-v7";
+ reg = <0>;
+ clocks = <&cpuclk 0>;
+ };
+
+ cpu@1 {
+ compatible = "marvell,sheeva-v7";
+ reg = <1>;
+ clocks = <&cpuclk 1>;
+ };
+
+ cpu@2 {
+ compatible = "marvell,sheeva-v7";
+ reg = <2>;
+ clocks = <&cpuclk 2>;
+ };
+
+ cpu@3 {
+ compatible = "marvell,sheeva-v7";
+ reg = <3>;
+ clocks = <&cpuclk 3>;
+ };
+ };
+
soc {
serial@d0012200 {
compatible = "ns16550";
@@ -47,6 +76,19 @@
marvell,timer-25Mhz;
};
+ coreclk: mvebu-sar@d0018230 {
+ compatible = "marvell,armada-xp-core-clocks";
+ reg = <0xd0018230 0x08>;
+ #clock-cells = <1>;
+ };
+
+ cpuclk: clock-complex@d0018700 {
+ #clock-cells = <1>;
+ compatible = "marvell,armada-xp-cpu-clockctrl";
+ reg = <0xd0018700 0xA0>;
+ clocks = <&coreclk 1>;
+ };
+
system-controller@d0018200 {
compatible = "marvell,armada-370-xp-system-controller";
reg = <0xd0018200 0x500>;
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 416d46e..e5f0ae2 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -9,11 +9,17 @@ config ARCH_MVEBU
select PINCTRL
select PLAT_ORION
select SPARSE_IRQ
+ select CLKDEV_LOOKUP
+ select MVEBU_CLK_CORE
+ select MVEBU_CLK_CPU
if ARCH_MVEBU
menu "Marvell SOC with device tree"
+config MVEBU_CLK_CPU
+ bool
+
config MACH_ARMADA_370_XP
bool
select ARMADA_370_XP_TIMER
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c
index 49d7915..3292d6d 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.c
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
@@ -17,6 +17,7 @@
#include <linux/of_platform.h>
#include <linux/io.h>
#include <linux/time-armada-370-xp.h>
+#include <linux/clk/mvebu.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
@@ -37,8 +38,14 @@ void __init armada_370_xp_map_io(void)
iotable_init(armada_370_xp_io_desc, ARRAY_SIZE(armada_370_xp_io_desc));
}
+void __init armada_370_xp_timer_and_clk_init(void)
+{
+ mvebu_clocks_init();
+ armada_370_xp_timer_init();
+}
+
struct sys_timer armada_370_xp_timer = {
- .init = armada_370_xp_timer_init,
+ .init = armada_370_xp_timer_and_clk_init,
};
static void __init armada_370_xp_dt_init(void)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 3/7] clk: armada-370-xp: add support for clock framework
@ 2012-11-15 21:28 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-370.dtsi | 7 ++++++
arch/arm/boot/dts/armada-xp.dtsi | 42 +++++++++++++++++++++++++++++++++++
arch/arm/mach-mvebu/Kconfig | 6 +++++
arch/arm/mach-mvebu/armada-370-xp.c | 9 +++++++-
4 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index 2069151..dae966c 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -75,5 +75,12 @@
#interrupts-cells = <2>;
interrupts = <91>;
};
+
+ coreclk: mvebu-sar at d0018230 {
+ compatible = "marvell,armada-370-core-clocks";
+ reg = <0xd0018230 0x08>;
+ #clock-cells = <1>;
+ };
+
};
};
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index 71d6b5d..f8382a8 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -27,6 +27,35 @@
<0xd0021870 0x58>;
};
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu at 0 {
+ compatible = "marvell,sheeva-v7";
+ reg = <0>;
+ clocks = <&cpuclk 0>;
+ };
+
+ cpu at 1 {
+ compatible = "marvell,sheeva-v7";
+ reg = <1>;
+ clocks = <&cpuclk 1>;
+ };
+
+ cpu at 2 {
+ compatible = "marvell,sheeva-v7";
+ reg = <2>;
+ clocks = <&cpuclk 2>;
+ };
+
+ cpu at 3 {
+ compatible = "marvell,sheeva-v7";
+ reg = <3>;
+ clocks = <&cpuclk 3>;
+ };
+ };
+
soc {
serial at d0012200 {
compatible = "ns16550";
@@ -47,6 +76,19 @@
marvell,timer-25Mhz;
};
+ coreclk: mvebu-sar at d0018230 {
+ compatible = "marvell,armada-xp-core-clocks";
+ reg = <0xd0018230 0x08>;
+ #clock-cells = <1>;
+ };
+
+ cpuclk: clock-complex at d0018700 {
+ #clock-cells = <1>;
+ compatible = "marvell,armada-xp-cpu-clockctrl";
+ reg = <0xd0018700 0xA0>;
+ clocks = <&coreclk 1>;
+ };
+
system-controller at d0018200 {
compatible = "marvell,armada-370-xp-system-controller";
reg = <0xd0018200 0x500>;
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 416d46e..e5f0ae2 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -9,11 +9,17 @@ config ARCH_MVEBU
select PINCTRL
select PLAT_ORION
select SPARSE_IRQ
+ select CLKDEV_LOOKUP
+ select MVEBU_CLK_CORE
+ select MVEBU_CLK_CPU
if ARCH_MVEBU
menu "Marvell SOC with device tree"
+config MVEBU_CLK_CPU
+ bool
+
config MACH_ARMADA_370_XP
bool
select ARMADA_370_XP_TIMER
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c
index 49d7915..3292d6d 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.c
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
@@ -17,6 +17,7 @@
#include <linux/of_platform.h>
#include <linux/io.h>
#include <linux/time-armada-370-xp.h>
+#include <linux/clk/mvebu.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
@@ -37,8 +38,14 @@ void __init armada_370_xp_map_io(void)
iotable_init(armada_370_xp_io_desc, ARRAY_SIZE(armada_370_xp_io_desc));
}
+void __init armada_370_xp_timer_and_clk_init(void)
+{
+ mvebu_clocks_init();
+ armada_370_xp_timer_init();
+}
+
struct sys_timer armada_370_xp_timer = {
- .init = armada_370_xp_timer_init,
+ .init = armada_370_xp_timer_and_clk_init,
};
static void __init armada_370_xp_dt_init(void)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 4/7] clocksource: time-armada-370-xp converted to clk framework
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:28 ` Andrew Lunn
-1 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: mturquette-QSEj5FYQhm4dnm+yROfE0A
Cc: Thomas Petazzoni, Jason Cooper, John Stultz,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux ARM
From: Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Signed-off-by: Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
cc: John Stultz <johnstul-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
---
arch/arm/boot/dts/armada-370-db.dts | 4 ----
arch/arm/boot/dts/armada-370-xp.dtsi | 1 +
drivers/clocksource/time-armada-370-xp.c | 11 ++++++-----
3 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
index fffd5c2..4a31b03 100644
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -34,9 +34,5 @@
clock-frequency = <200000000>;
status = "okay";
};
- timer@d0020300 {
- clock-frequency = <600000000>;
- status = "okay";
- };
};
};
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 16cc82c..94b4b9e 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -62,6 +62,7 @@
compatible = "marvell,armada-370-xp-timer";
reg = <0xd0020300 0x30>;
interrupts = <37>, <38>, <39>, <40>;
+ clocks = <&coreclk 2>;
};
addr-decoding@d0020000 {
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c
index 4674f94..a4605fd 100644
--- a/drivers/clocksource/time-armada-370-xp.c
+++ b/drivers/clocksource/time-armada-370-xp.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
+#include <linux/clk.h>
#include <linux/timer.h>
#include <linux/clockchips.h>
#include <linux/interrupt.h>
@@ -167,7 +168,6 @@ void __init armada_370_xp_timer_init(void)
u32 u;
struct device_node *np;
unsigned int timer_clk;
- int ret;
np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-timer");
timer_base = of_iomap(np, 0);
WARN_ON(!timer_base);
@@ -179,13 +179,14 @@ void __init armada_370_xp_timer_init(void)
timer_base + TIMER_CTRL_OFF);
timer_clk = 25000000;
} else {
- u32 clk = 0;
- ret = of_property_read_u32(np, "clock-frequency", &clk);
- WARN_ON(!clk || ret < 0);
+ unsigned long rate = 0;
+ struct clk *clk = of_clk_get(np, 0);
+ WARN_ON(IS_ERR(clk));
+ rate = clk_get_rate(clk);
u = readl(timer_base + TIMER_CTRL_OFF);
writel(u & ~(TIMER0_25MHZ | TIMER1_25MHZ),
timer_base + TIMER_CTRL_OFF);
- timer_clk = clk / TIMER_DIVIDER;
+ timer_clk = rate / TIMER_DIVIDER;
}
/* We use timer 0 as clocksource, and timer 1 for
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 4/7] clocksource: time-armada-370-xp converted to clk framework
@ 2012-11-15 21:28 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
cc: John Stultz <johnstul@us.ibm.com>
---
arch/arm/boot/dts/armada-370-db.dts | 4 ----
arch/arm/boot/dts/armada-370-xp.dtsi | 1 +
drivers/clocksource/time-armada-370-xp.c | 11 ++++++-----
3 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
index fffd5c2..4a31b03 100644
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -34,9 +34,5 @@
clock-frequency = <200000000>;
status = "okay";
};
- timer at d0020300 {
- clock-frequency = <600000000>;
- status = "okay";
- };
};
};
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 16cc82c..94b4b9e 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -62,6 +62,7 @@
compatible = "marvell,armada-370-xp-timer";
reg = <0xd0020300 0x30>;
interrupts = <37>, <38>, <39>, <40>;
+ clocks = <&coreclk 2>;
};
addr-decoding at d0020000 {
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c
index 4674f94..a4605fd 100644
--- a/drivers/clocksource/time-armada-370-xp.c
+++ b/drivers/clocksource/time-armada-370-xp.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
+#include <linux/clk.h>
#include <linux/timer.h>
#include <linux/clockchips.h>
#include <linux/interrupt.h>
@@ -167,7 +168,6 @@ void __init armada_370_xp_timer_init(void)
u32 u;
struct device_node *np;
unsigned int timer_clk;
- int ret;
np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-timer");
timer_base = of_iomap(np, 0);
WARN_ON(!timer_base);
@@ -179,13 +179,14 @@ void __init armada_370_xp_timer_init(void)
timer_base + TIMER_CTRL_OFF);
timer_clk = 25000000;
} else {
- u32 clk = 0;
- ret = of_property_read_u32(np, "clock-frequency", &clk);
- WARN_ON(!clk || ret < 0);
+ unsigned long rate = 0;
+ struct clk *clk = of_clk_get(np, 0);
+ WARN_ON(IS_ERR(clk));
+ rate = clk_get_rate(clk);
u = readl(timer_base + TIMER_CTRL_OFF);
writel(u & ~(TIMER0_25MHZ | TIMER1_25MHZ),
timer_base + TIMER_CTRL_OFF);
- timer_clk = clk / TIMER_DIVIDER;
+ timer_clk = rate / TIMER_DIVIDER;
}
/* We use timer 0 as clocksource, and timer 1 for
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 5/7] clk: mvebu: add clock gating control provider for DT
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:28 ` Andrew Lunn
-1 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: mturquette-QSEj5FYQhm4dnm+yROfE0A
Cc: Thomas Petazzoni, Jason Cooper,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux ARM,
Sebastian Hesselbarth
From: Sebastian Hesselbarth <sebastian.hesselbarth-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
This driver allows to provide DT clocks for clock gates found on
Marvell Dove and Kirkwood SoCs. The clock gates are referenced by
the phandle index of the corresponding bit in the clock gating control
register to ease lookup in the datasheet.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
.../bindings/clock/mvebu-gated-clock.txt | 76 +++++++++
drivers/clk/mvebu/Kconfig | 2 +
drivers/clk/mvebu/Makefile | 1 +
drivers/clk/mvebu/clk-gating-ctrl.c | 177 ++++++++++++++++++++
include/linux/clk/mvebu.h | 1 +
5 files changed, 257 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
create mode 100644 drivers/clk/mvebu/clk-gating-ctrl.c
diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
new file mode 100644
index 0000000..7497cc0
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
@@ -0,0 +1,76 @@
+* Gated Clock bindings for Marvell Orion SoCs
+
+Marvell Dove and Kirkwood allow some peripheral clocks to be gated to save
+some power. The clock consumer should specify the desired clock by having
+the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to
+the corresponding clock gating control bit in HW to ease manual clock lookup
+in datasheet.
+
+The following is a list of provided IDs for Dove:
+ID Clock Peripheral
+-----------------------------------
+0 usb0 USB Host 0
+1 usb1 USB Host 1
+2 ge Gigabit Ethernet
+3 sata SATA Host
+4 pex0 PCIe Cntrl 0
+5 pex1 PCIe Cntrl 1
+8 sdio0 SDHCI Host 0
+9 sdio1 SDHCI Host 1
+10 nand NAND Cntrl
+11 camera Camera Cntrl
+12 i2s0 I2S Cntrl 0
+13 i2s1 I2S Cntrl 1
+15 crypto CESA engine
+21 ac97 AC97 Cntrl
+22 pdma Peripheral DMA
+23 xor0 XOR DMA 0
+24 xor1 XOR DMA 1
+30 gephy Gigabit Ethernel PHY
+Note: gephy(30) is implemented as a parent clock of ge(2)
+
+The following is a list of provided IDs for Kirkwood:
+ID Clock Peripheral
+-----------------------------------
+0 ge0 Gigabit Ethernet 0
+2 pex0 PCIe Cntrl 0
+3 usb0 USB Host 0
+4 sdio SDIO Cntrl
+5 tsu Transp. Stream Unit
+6 dunit SDRAM Cntrl
+7 runit Runit
+8 xor0 XOR DMA 0
+9 audio I2S Cntrl 0
+14 sata0 SATA Host 0
+15 sata1 SATA Host 1
+16 xor1 XOR DMA 1
+17 crypto CESA engine
+18 pex1 PCIe Cntrl 1
+19 ge1 Gigabit Ethernet 0
+20 tdm Time Division Mplx
+
+Required properties:
+- compatible : shall be one of the following:
+ "marvell,dove-clock-gating" - for Dove SoC clock gating
+ "marvell,kirkwood-clock-gating" - for Kirkwood SoC clock gating
+- reg : shall be the register address of the Clock Gating Control register
+- #clock-cells : from common clock binding; shall be set to 1
+
+Optional properties:
+- clocks : default parent clock phandle (e.g. tclk)
+
+Example:
+
+clk_gate: clock-gating-control@d0038 {
+ compatible = "marvell,dove-clock-gating";
+ reg = <0xd0038 0x4>;
+ /* default parent clock is tclk */
+ clocks = <&core_clk 0>;
+ #clock-cells = <1>;
+};
+
+sdio0: sdio@92000 {
+ compatible = "marvell,dove-sdhci";
+ /* get clk gate bit 8 (sdio0) */
+ clocks = <&clk_gate 8>;
+};
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
index 1dd93ad..57323fd 100644
--- a/drivers/clk/mvebu/Kconfig
+++ b/drivers/clk/mvebu/Kconfig
@@ -4,3 +4,5 @@ config MVEBU_CLK_CORE
config MVEBU_CLK_CPU
bool
+config MVEBU_CLK_GATING
+ bool
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
index 93da083..58df3dc 100644
--- a/drivers/clk/mvebu/Makefile
+++ b/drivers/clk/mvebu/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_MVEBU_CLK_CORE) += clk.o clk-core.o
obj-$(CONFIG_MVEBU_CLK_CPU) += clk-cpu.o
+obj-$(CONFIG_MVEBU_CLK_GATING) += clk-gating-ctrl.o
diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c
new file mode 100644
index 0000000..3ac7607
--- /dev/null
+++ b/drivers/clk/mvebu/clk-gating-ctrl.c
@@ -0,0 +1,177 @@
+/*
+ * Marvell MVEBU clock gating control.
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ * Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/mvebu.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+struct mvebu_gating_ctrl {
+ spinlock_t lock;
+ struct clk **gates;
+ int num_gates;
+};
+
+struct mvebu_soc_descr {
+ const char *name;
+ const char *parent;
+ int bit_idx;
+};
+
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
+
+static struct clk __init *mvebu_clk_gating_get_src(
+ struct of_phandle_args *clkspec, void *data)
+{
+ struct mvebu_gating_ctrl *ctrl = (struct mvebu_gating_ctrl *)data;
+ int n;
+
+ if (clkspec->args_count < 1)
+ return ERR_PTR(-EINVAL);
+
+ for (n = 0; n < ctrl->num_gates; n++) {
+ struct clk_gate *gate =
+ to_clk_gate(__clk_get_hw(ctrl->gates[n]));
+ if (clkspec->args[0] == gate->bit_idx)
+ return ctrl->gates[n];
+ }
+ return ERR_PTR(-ENODEV);
+}
+
+static void __init mvebu_clk_gating_setup(
+ struct device_node *np, const struct mvebu_soc_descr *descr)
+{
+ struct mvebu_gating_ctrl *ctrl;
+ struct clk *clk;
+ void __iomem *base;
+ const char *default_parent = NULL;
+ int n;
+
+ base = of_iomap(np, 0);
+
+ clk = of_clk_get(np, 0);
+ if (!IS_ERR(clk)) {
+ default_parent = __clk_get_name(clk);
+ clk_put(clk);
+ }
+
+ ctrl = kzalloc(sizeof(struct mvebu_gating_ctrl), GFP_KERNEL);
+ if (WARN_ON(!ctrl))
+ return;
+
+ spin_lock_init(&ctrl->lock);
+
+ /*
+ * Count, allocate, and register clock gates
+ */
+ for (n = 0; descr[n].name;)
+ n++;
+
+ ctrl->num_gates = n;
+ ctrl->gates = kzalloc(ctrl->num_gates * sizeof(struct clk *),
+ GFP_KERNEL);
+ if (WARN_ON(!ctrl->gates)) {
+ kfree(ctrl);
+ return;
+ }
+
+ for (n = 0; n < ctrl->num_gates; n++) {
+ const char *parent =
+ (descr[n].parent) ? descr[n].parent : default_parent;
+ ctrl->gates[n] = clk_register_gate(NULL, descr[n].name, parent,
+ 0, base, descr[n].bit_idx, 0, &ctrl->lock);
+ WARN_ON(IS_ERR(ctrl->gates[n]));
+ }
+ of_clk_add_provider(np, mvebu_clk_gating_get_src, ctrl);
+}
+
+/*
+ * SoC specific clock gating control
+ */
+
+#ifdef CONFIG_ARCH_DOVE
+static const struct mvebu_soc_descr __initconst dove_gating_descr[] = {
+ { "usb0", NULL, 0 },
+ { "usb1", NULL, 1 },
+ { "ge", "gephy", 2 },
+ { "sata", NULL, 3 },
+ { "pex0", NULL, 4 },
+ { "pex1", NULL, 5 },
+ { "sdio0", NULL, 8 },
+ { "sdio1", NULL, 9 },
+ { "nand", NULL, 10 },
+ { "camera", NULL, 11 },
+ { "i2s0", NULL, 12 },
+ { "i2s1", NULL, 13 },
+ { "crypto", NULL, 15 },
+ { "ac97", NULL, 21 },
+ { "pdma", NULL, 22 },
+ { "xor0", NULL, 23 },
+ { "xor1", NULL, 24 },
+ { "gephy", NULL, 30 },
+ { }
+};
+#endif
+
+#ifdef CONFIG_ARCH_KIRKWOOD
+static const struct mvebu_soc_descr __initconst kirkwood_gating_descr[] = {
+ { "ge0", NULL, 0 },
+ { "pex0", NULL, 2 },
+ { "usb0", NULL, 3 },
+ { "sdio", NULL, 4 },
+ { "tsu", NULL, 5 },
+ { "runit", NULL, 7 },
+ { "xor0", NULL, 8 },
+ { "audio", NULL, 9 },
+ { "sata0", NULL, 14 },
+ { "sata1", NULL, 15 },
+ { "xor1", NULL, 16 },
+ { "crypto", NULL, 17 },
+ { "pex1", NULL, 18 },
+ { "ge1", NULL, 19 },
+ { "tdm", NULL, 20 },
+ { }
+};
+#endif
+
+static const __initdata struct of_device_id clk_gating_match[] = {
+#ifdef CONFIG_ARCH_DOVE
+ {
+ .compatible = "marvell,dove-clock-gating",
+ .data = dove_gating_descr,
+ },
+#endif
+
+#ifdef CONFIG_ARCH_KIRKWOOD
+ {
+ .compatible = "marvell,kirkwood-clock-gating",
+ .data = kirkwood_gating_descr,
+ },
+#endif
+
+ { }
+};
+
+void __init mvebu_clk_gating_init(void)
+{
+ struct device_node *np;
+
+ for_each_matching_node(np, clk_gating_match) {
+ const struct of_device_id *match =
+ of_match_node(clk_gating_match, np);
+ mvebu_clk_gating_setup(np,
+ (const struct mvebu_soc_descr *)match->data);
+ }
+}
diff --git a/include/linux/clk/mvebu.h b/include/linux/clk/mvebu.h
index 8c4ae71..70c366f 100644
--- a/include/linux/clk/mvebu.h
+++ b/include/linux/clk/mvebu.h
@@ -18,5 +18,6 @@
#define __CLK_MVEBU_H_
void __init mvebu_clocks_init(void);
+void mvebu_clk_gating_init(void);
#endif
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 5/7] clk: mvebu: add clock gating control provider for DT
@ 2012-11-15 21:28 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
This driver allows to provide DT clocks for clock gates found on
Marvell Dove and Kirkwood SoCs. The clock gates are referenced by
the phandle index of the corresponding bit in the clock gating control
register to ease lookup in the datasheet.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
.../bindings/clock/mvebu-gated-clock.txt | 76 +++++++++
drivers/clk/mvebu/Kconfig | 2 +
drivers/clk/mvebu/Makefile | 1 +
drivers/clk/mvebu/clk-gating-ctrl.c | 177 ++++++++++++++++++++
include/linux/clk/mvebu.h | 1 +
5 files changed, 257 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
create mode 100644 drivers/clk/mvebu/clk-gating-ctrl.c
diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
new file mode 100644
index 0000000..7497cc0
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
@@ -0,0 +1,76 @@
+* Gated Clock bindings for Marvell Orion SoCs
+
+Marvell Dove and Kirkwood allow some peripheral clocks to be gated to save
+some power. The clock consumer should specify the desired clock by having
+the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to
+the corresponding clock gating control bit in HW to ease manual clock lookup
+in datasheet.
+
+The following is a list of provided IDs for Dove:
+ID Clock Peripheral
+-----------------------------------
+0 usb0 USB Host 0
+1 usb1 USB Host 1
+2 ge Gigabit Ethernet
+3 sata SATA Host
+4 pex0 PCIe Cntrl 0
+5 pex1 PCIe Cntrl 1
+8 sdio0 SDHCI Host 0
+9 sdio1 SDHCI Host 1
+10 nand NAND Cntrl
+11 camera Camera Cntrl
+12 i2s0 I2S Cntrl 0
+13 i2s1 I2S Cntrl 1
+15 crypto CESA engine
+21 ac97 AC97 Cntrl
+22 pdma Peripheral DMA
+23 xor0 XOR DMA 0
+24 xor1 XOR DMA 1
+30 gephy Gigabit Ethernel PHY
+Note: gephy(30) is implemented as a parent clock of ge(2)
+
+The following is a list of provided IDs for Kirkwood:
+ID Clock Peripheral
+-----------------------------------
+0 ge0 Gigabit Ethernet 0
+2 pex0 PCIe Cntrl 0
+3 usb0 USB Host 0
+4 sdio SDIO Cntrl
+5 tsu Transp. Stream Unit
+6 dunit SDRAM Cntrl
+7 runit Runit
+8 xor0 XOR DMA 0
+9 audio I2S Cntrl 0
+14 sata0 SATA Host 0
+15 sata1 SATA Host 1
+16 xor1 XOR DMA 1
+17 crypto CESA engine
+18 pex1 PCIe Cntrl 1
+19 ge1 Gigabit Ethernet 0
+20 tdm Time Division Mplx
+
+Required properties:
+- compatible : shall be one of the following:
+ "marvell,dove-clock-gating" - for Dove SoC clock gating
+ "marvell,kirkwood-clock-gating" - for Kirkwood SoC clock gating
+- reg : shall be the register address of the Clock Gating Control register
+- #clock-cells : from common clock binding; shall be set to 1
+
+Optional properties:
+- clocks : default parent clock phandle (e.g. tclk)
+
+Example:
+
+clk_gate: clock-gating-control at d0038 {
+ compatible = "marvell,dove-clock-gating";
+ reg = <0xd0038 0x4>;
+ /* default parent clock is tclk */
+ clocks = <&core_clk 0>;
+ #clock-cells = <1>;
+};
+
+sdio0: sdio at 92000 {
+ compatible = "marvell,dove-sdhci";
+ /* get clk gate bit 8 (sdio0) */
+ clocks = <&clk_gate 8>;
+};
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
index 1dd93ad..57323fd 100644
--- a/drivers/clk/mvebu/Kconfig
+++ b/drivers/clk/mvebu/Kconfig
@@ -4,3 +4,5 @@ config MVEBU_CLK_CORE
config MVEBU_CLK_CPU
bool
+config MVEBU_CLK_GATING
+ bool
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
index 93da083..58df3dc 100644
--- a/drivers/clk/mvebu/Makefile
+++ b/drivers/clk/mvebu/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_MVEBU_CLK_CORE) += clk.o clk-core.o
obj-$(CONFIG_MVEBU_CLK_CPU) += clk-cpu.o
+obj-$(CONFIG_MVEBU_CLK_GATING) += clk-gating-ctrl.o
diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c
new file mode 100644
index 0000000..3ac7607
--- /dev/null
+++ b/drivers/clk/mvebu/clk-gating-ctrl.c
@@ -0,0 +1,177 @@
+/*
+ * Marvell MVEBU clock gating control.
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/mvebu.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+struct mvebu_gating_ctrl {
+ spinlock_t lock;
+ struct clk **gates;
+ int num_gates;
+};
+
+struct mvebu_soc_descr {
+ const char *name;
+ const char *parent;
+ int bit_idx;
+};
+
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
+
+static struct clk __init *mvebu_clk_gating_get_src(
+ struct of_phandle_args *clkspec, void *data)
+{
+ struct mvebu_gating_ctrl *ctrl = (struct mvebu_gating_ctrl *)data;
+ int n;
+
+ if (clkspec->args_count < 1)
+ return ERR_PTR(-EINVAL);
+
+ for (n = 0; n < ctrl->num_gates; n++) {
+ struct clk_gate *gate =
+ to_clk_gate(__clk_get_hw(ctrl->gates[n]));
+ if (clkspec->args[0] == gate->bit_idx)
+ return ctrl->gates[n];
+ }
+ return ERR_PTR(-ENODEV);
+}
+
+static void __init mvebu_clk_gating_setup(
+ struct device_node *np, const struct mvebu_soc_descr *descr)
+{
+ struct mvebu_gating_ctrl *ctrl;
+ struct clk *clk;
+ void __iomem *base;
+ const char *default_parent = NULL;
+ int n;
+
+ base = of_iomap(np, 0);
+
+ clk = of_clk_get(np, 0);
+ if (!IS_ERR(clk)) {
+ default_parent = __clk_get_name(clk);
+ clk_put(clk);
+ }
+
+ ctrl = kzalloc(sizeof(struct mvebu_gating_ctrl), GFP_KERNEL);
+ if (WARN_ON(!ctrl))
+ return;
+
+ spin_lock_init(&ctrl->lock);
+
+ /*
+ * Count, allocate, and register clock gates
+ */
+ for (n = 0; descr[n].name;)
+ n++;
+
+ ctrl->num_gates = n;
+ ctrl->gates = kzalloc(ctrl->num_gates * sizeof(struct clk *),
+ GFP_KERNEL);
+ if (WARN_ON(!ctrl->gates)) {
+ kfree(ctrl);
+ return;
+ }
+
+ for (n = 0; n < ctrl->num_gates; n++) {
+ const char *parent =
+ (descr[n].parent) ? descr[n].parent : default_parent;
+ ctrl->gates[n] = clk_register_gate(NULL, descr[n].name, parent,
+ 0, base, descr[n].bit_idx, 0, &ctrl->lock);
+ WARN_ON(IS_ERR(ctrl->gates[n]));
+ }
+ of_clk_add_provider(np, mvebu_clk_gating_get_src, ctrl);
+}
+
+/*
+ * SoC specific clock gating control
+ */
+
+#ifdef CONFIG_ARCH_DOVE
+static const struct mvebu_soc_descr __initconst dove_gating_descr[] = {
+ { "usb0", NULL, 0 },
+ { "usb1", NULL, 1 },
+ { "ge", "gephy", 2 },
+ { "sata", NULL, 3 },
+ { "pex0", NULL, 4 },
+ { "pex1", NULL, 5 },
+ { "sdio0", NULL, 8 },
+ { "sdio1", NULL, 9 },
+ { "nand", NULL, 10 },
+ { "camera", NULL, 11 },
+ { "i2s0", NULL, 12 },
+ { "i2s1", NULL, 13 },
+ { "crypto", NULL, 15 },
+ { "ac97", NULL, 21 },
+ { "pdma", NULL, 22 },
+ { "xor0", NULL, 23 },
+ { "xor1", NULL, 24 },
+ { "gephy", NULL, 30 },
+ { }
+};
+#endif
+
+#ifdef CONFIG_ARCH_KIRKWOOD
+static const struct mvebu_soc_descr __initconst kirkwood_gating_descr[] = {
+ { "ge0", NULL, 0 },
+ { "pex0", NULL, 2 },
+ { "usb0", NULL, 3 },
+ { "sdio", NULL, 4 },
+ { "tsu", NULL, 5 },
+ { "runit", NULL, 7 },
+ { "xor0", NULL, 8 },
+ { "audio", NULL, 9 },
+ { "sata0", NULL, 14 },
+ { "sata1", NULL, 15 },
+ { "xor1", NULL, 16 },
+ { "crypto", NULL, 17 },
+ { "pex1", NULL, 18 },
+ { "ge1", NULL, 19 },
+ { "tdm", NULL, 20 },
+ { }
+};
+#endif
+
+static const __initdata struct of_device_id clk_gating_match[] = {
+#ifdef CONFIG_ARCH_DOVE
+ {
+ .compatible = "marvell,dove-clock-gating",
+ .data = dove_gating_descr,
+ },
+#endif
+
+#ifdef CONFIG_ARCH_KIRKWOOD
+ {
+ .compatible = "marvell,kirkwood-clock-gating",
+ .data = kirkwood_gating_descr,
+ },
+#endif
+
+ { }
+};
+
+void __init mvebu_clk_gating_init(void)
+{
+ struct device_node *np;
+
+ for_each_matching_node(np, clk_gating_match) {
+ const struct of_device_id *match =
+ of_match_node(clk_gating_match, np);
+ mvebu_clk_gating_setup(np,
+ (const struct mvebu_soc_descr *)match->data);
+ }
+}
diff --git a/include/linux/clk/mvebu.h b/include/linux/clk/mvebu.h
index 8c4ae71..70c366f 100644
--- a/include/linux/clk/mvebu.h
+++ b/include/linux/clk/mvebu.h
@@ -18,5 +18,6 @@
#define __CLK_MVEBU_H_
void __init mvebu_clocks_init(void);
+void mvebu_clk_gating_init(void);
#endif
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 6/7] ARM: dove: switch to DT clock providers
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:28 ` Andrew Lunn
-1 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: mturquette-QSEj5FYQhm4dnm+yROfE0A
Cc: Thomas Petazzoni, Jason Cooper,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux ARM,
Sebastian Hesselbarth
From: Sebastian Hesselbarth <sebastian.hesselbarth-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
With true DT clock providers available switch Dove clock setup in DT-
enabled boards. While AUXDATA can be removed completely from bus probing,
some devices still don't know about DT at all. Therefore, some clock
aliases are created until the devices also move to DT.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
arch/arm/Kconfig | 1 +
arch/arm/boot/dts/dove.dtsi | 20 ++++++++++++++
arch/arm/mach-dove/Kconfig | 2 ++
arch/arm/mach-dove/common.c | 64 +++++++++++++++++++++++++++++++++----------
4 files changed, 72 insertions(+), 15 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ade7e92..0590099 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -533,6 +533,7 @@ config ARCH_IXP4XX
config ARCH_DOVE
bool "Marvell Dove"
select ARCH_REQUIRE_GPIOLIB
+ select COMMON_CLK_DOVE
select CPU_V7
select GENERIC_CLOCKEVENTS
select MIGHT_HAVE_PCI
diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
index 5a00022..6c3919a 100644
--- a/arch/arm/boot/dts/dove.dtsi
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -31,6 +31,19 @@
reg = <0x20204 0x04>, <0x20214 0x04>;
};
+ core_clk: core-clocks@d0214 {
+ compatible = "marvell,dove-core-clocks";
+ reg = <0xd0214 0x4>;
+ #clock-cells = <1>;
+ };
+
+ clk_gate: clock-gating-control@d0038 {
+ compatible = "marvell,dove-clock-gating";
+ reg = <0xd0038 0x4>;
+ clocks = <&core_clk 0>;
+ #clock-cells = <1>;
+ };
+
uart0: serial@12000 {
compatible = "ns16550a";
reg = <0x12000 0x100>;
@@ -100,6 +113,7 @@
cell-index = <0>;
interrupts = <6>;
reg = <0x10600 0x28>;
+ clocks = <&core_clk 0>;
status = "disabled";
};
@@ -110,6 +124,7 @@
cell-index = <1>;
interrupts = <5>;
reg = <0x14600 0x28>;
+ clocks = <&core_clk 0>;
status = "disabled";
};
@@ -121,6 +136,7 @@
interrupts = <11>;
clock-frequency = <400000>;
timeout-ms = <1000>;
+ clocks = <&core_clk 0>;
status = "disabled";
};
@@ -128,6 +144,7 @@
compatible = "marvell,dove-sdhci";
reg = <0x92000 0x100>;
interrupts = <35>, <37>;
+ clocks = <&clk_gate 8>;
status = "disabled";
};
@@ -135,6 +152,7 @@
compatible = "marvell,dove-sdhci";
reg = <0x90000 0x100>;
interrupts = <36>, <38>;
+ clocks = <&clk_gate 9>;
status = "disabled";
};
@@ -142,6 +160,7 @@
compatible = "marvell,orion-sata";
reg = <0xa0000 0x2400>;
interrupts = <62>;
+ clocks = <&clk_gate 3>;
nr-ports = <1>;
status = "disabled";
};
@@ -152,6 +171,7 @@
<0xc8000000 0x800>;
reg-names = "regs", "sram";
interrupts = <31>;
+ clocks = <&clk_gate 15>;
status = "okay";
};
};
diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig
index 00154e7..603c5fd 100644
--- a/arch/arm/mach-dove/Kconfig
+++ b/arch/arm/mach-dove/Kconfig
@@ -17,6 +17,8 @@ config MACH_CM_A510
config MACH_DOVE_DT
bool "Marvell Dove Flattened Device Tree"
+ select MVEBU_CLK_CORE
+ select MVEBU_CLK_GATING
select USE_OF
help
Say 'Y' here if you want your kernel to support the
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
index f723fe1..96b40e3 100644
--- a/arch/arm/mach-dove/common.c
+++ b/arch/arm/mach-dove/common.c
@@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/clk-provider.h>
+#include <linux/clk/mvebu.h>
#include <linux/ata_platform.h>
#include <linux/gpio.h>
#include <linux/of.h>
@@ -376,19 +377,53 @@ void dove_restart(char mode, const char *cmd)
#if defined(CONFIG_MACH_DOVE_DT)
/*
- * Auxdata required until real OF clock provider
+ * There are still devices that doesn't even know about DT,
+ * get clock gates here and add a clock lookup.
*/
-struct of_dev_auxdata dove_auxdata_lookup[] __initdata = {
- OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
- OF_DEV_AUXDATA("marvell,orion-spi", 0xf1014600, "orion_spi.1", NULL),
- OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
- OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
- NULL),
- OF_DEV_AUXDATA("marvell,orion-sata", 0xf10a0000, "sata_mv.0", NULL),
- OF_DEV_AUXDATA("marvell,dove-sdhci", 0xf1092000, "sdhci-dove.0", NULL),
- OF_DEV_AUXDATA("marvell,dove-sdhci", 0xf1090000, "sdhci-dove.1", NULL),
- {},
-};
+static void __init dove_legacy_clk_init(void)
+{
+ struct device_node *np = of_find_compatible_node(NULL, NULL,
+ "marvell,dove-clock-gating");
+ struct of_phandle_args clkspec;
+
+ clkspec.np = np;
+ clkspec.args_count = 1;
+
+ clkspec.args[0] = CLOCK_GATING_BIT_USB0;
+ orion_clkdev_add(NULL, "orion-ehci.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_USB1;
+ orion_clkdev_add(NULL, "orion-ehci.1",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_GBE;
+ orion_clkdev_add(NULL, "mv643xx_eth_port.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_PCIE0;
+ orion_clkdev_add("0", "pcie",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_PCIE1;
+ orion_clkdev_add("1", "pcie",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_XOR0;
+ orion_clkdev_add(NULL, "mv_xor_shared.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_XOR1;
+ orion_clkdev_add(NULL, "mv_xor_shared.1",
+ of_clk_get_from_provider(&clkspec));
+}
+
+static void __init dove_of_clk_init(void)
+{
+ mvebu_clocks_init();
+ mvebu_clk_gating_init();
+ dove_legacy_clk_init();
+}
static struct mv643xx_eth_platform_data dove_dt_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT,
@@ -405,7 +440,7 @@ static void __init dove_dt_init(void)
dove_setup_cpu_mbus();
/* Setup root of clk tree */
- dove_clk_init();
+ dove_of_clk_init();
/* Internal devices not ported to DT yet */
dove_rtc_init();
@@ -417,8 +452,7 @@ static void __init dove_dt_init(void)
dove_ehci1_init();
dove_pcie_init(1, 1);
- of_platform_populate(NULL, of_default_bus_match_table,
- dove_auxdata_lookup, NULL);
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
static const char * const dove_dt_board_compat[] = {
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 6/7] ARM: dove: switch to DT clock providers
@ 2012-11-15 21:28 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
With true DT clock providers available switch Dove clock setup in DT-
enabled boards. While AUXDATA can be removed completely from bus probing,
some devices still don't know about DT at all. Therefore, some clock
aliases are created until the devices also move to DT.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/Kconfig | 1 +
arch/arm/boot/dts/dove.dtsi | 20 ++++++++++++++
arch/arm/mach-dove/Kconfig | 2 ++
arch/arm/mach-dove/common.c | 64 +++++++++++++++++++++++++++++++++----------
4 files changed, 72 insertions(+), 15 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ade7e92..0590099 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -533,6 +533,7 @@ config ARCH_IXP4XX
config ARCH_DOVE
bool "Marvell Dove"
select ARCH_REQUIRE_GPIOLIB
+ select COMMON_CLK_DOVE
select CPU_V7
select GENERIC_CLOCKEVENTS
select MIGHT_HAVE_PCI
diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
index 5a00022..6c3919a 100644
--- a/arch/arm/boot/dts/dove.dtsi
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -31,6 +31,19 @@
reg = <0x20204 0x04>, <0x20214 0x04>;
};
+ core_clk: core-clocks at d0214 {
+ compatible = "marvell,dove-core-clocks";
+ reg = <0xd0214 0x4>;
+ #clock-cells = <1>;
+ };
+
+ clk_gate: clock-gating-control at d0038 {
+ compatible = "marvell,dove-clock-gating";
+ reg = <0xd0038 0x4>;
+ clocks = <&core_clk 0>;
+ #clock-cells = <1>;
+ };
+
uart0: serial at 12000 {
compatible = "ns16550a";
reg = <0x12000 0x100>;
@@ -100,6 +113,7 @@
cell-index = <0>;
interrupts = <6>;
reg = <0x10600 0x28>;
+ clocks = <&core_clk 0>;
status = "disabled";
};
@@ -110,6 +124,7 @@
cell-index = <1>;
interrupts = <5>;
reg = <0x14600 0x28>;
+ clocks = <&core_clk 0>;
status = "disabled";
};
@@ -121,6 +136,7 @@
interrupts = <11>;
clock-frequency = <400000>;
timeout-ms = <1000>;
+ clocks = <&core_clk 0>;
status = "disabled";
};
@@ -128,6 +144,7 @@
compatible = "marvell,dove-sdhci";
reg = <0x92000 0x100>;
interrupts = <35>, <37>;
+ clocks = <&clk_gate 8>;
status = "disabled";
};
@@ -135,6 +152,7 @@
compatible = "marvell,dove-sdhci";
reg = <0x90000 0x100>;
interrupts = <36>, <38>;
+ clocks = <&clk_gate 9>;
status = "disabled";
};
@@ -142,6 +160,7 @@
compatible = "marvell,orion-sata";
reg = <0xa0000 0x2400>;
interrupts = <62>;
+ clocks = <&clk_gate 3>;
nr-ports = <1>;
status = "disabled";
};
@@ -152,6 +171,7 @@
<0xc8000000 0x800>;
reg-names = "regs", "sram";
interrupts = <31>;
+ clocks = <&clk_gate 15>;
status = "okay";
};
};
diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig
index 00154e7..603c5fd 100644
--- a/arch/arm/mach-dove/Kconfig
+++ b/arch/arm/mach-dove/Kconfig
@@ -17,6 +17,8 @@ config MACH_CM_A510
config MACH_DOVE_DT
bool "Marvell Dove Flattened Device Tree"
+ select MVEBU_CLK_CORE
+ select MVEBU_CLK_GATING
select USE_OF
help
Say 'Y' here if you want your kernel to support the
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
index f723fe1..96b40e3 100644
--- a/arch/arm/mach-dove/common.c
+++ b/arch/arm/mach-dove/common.c
@@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/clk-provider.h>
+#include <linux/clk/mvebu.h>
#include <linux/ata_platform.h>
#include <linux/gpio.h>
#include <linux/of.h>
@@ -376,19 +377,53 @@ void dove_restart(char mode, const char *cmd)
#if defined(CONFIG_MACH_DOVE_DT)
/*
- * Auxdata required until real OF clock provider
+ * There are still devices that doesn't even know about DT,
+ * get clock gates here and add a clock lookup.
*/
-struct of_dev_auxdata dove_auxdata_lookup[] __initdata = {
- OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
- OF_DEV_AUXDATA("marvell,orion-spi", 0xf1014600, "orion_spi.1", NULL),
- OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
- OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
- NULL),
- OF_DEV_AUXDATA("marvell,orion-sata", 0xf10a0000, "sata_mv.0", NULL),
- OF_DEV_AUXDATA("marvell,dove-sdhci", 0xf1092000, "sdhci-dove.0", NULL),
- OF_DEV_AUXDATA("marvell,dove-sdhci", 0xf1090000, "sdhci-dove.1", NULL),
- {},
-};
+static void __init dove_legacy_clk_init(void)
+{
+ struct device_node *np = of_find_compatible_node(NULL, NULL,
+ "marvell,dove-clock-gating");
+ struct of_phandle_args clkspec;
+
+ clkspec.np = np;
+ clkspec.args_count = 1;
+
+ clkspec.args[0] = CLOCK_GATING_BIT_USB0;
+ orion_clkdev_add(NULL, "orion-ehci.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_USB1;
+ orion_clkdev_add(NULL, "orion-ehci.1",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_GBE;
+ orion_clkdev_add(NULL, "mv643xx_eth_port.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_PCIE0;
+ orion_clkdev_add("0", "pcie",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_PCIE1;
+ orion_clkdev_add("1", "pcie",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_XOR0;
+ orion_clkdev_add(NULL, "mv_xor_shared.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CLOCK_GATING_BIT_XOR1;
+ orion_clkdev_add(NULL, "mv_xor_shared.1",
+ of_clk_get_from_provider(&clkspec));
+}
+
+static void __init dove_of_clk_init(void)
+{
+ mvebu_clocks_init();
+ mvebu_clk_gating_init();
+ dove_legacy_clk_init();
+}
static struct mv643xx_eth_platform_data dove_dt_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT,
@@ -405,7 +440,7 @@ static void __init dove_dt_init(void)
dove_setup_cpu_mbus();
/* Setup root of clk tree */
- dove_clk_init();
+ dove_of_clk_init();
/* Internal devices not ported to DT yet */
dove_rtc_init();
@@ -417,8 +452,7 @@ static void __init dove_dt_init(void)
dove_ehci1_init();
dove_pcie_init(1, 1);
- of_platform_populate(NULL, of_default_bus_match_table,
- dove_auxdata_lookup, NULL);
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
static const char * const dove_dt_board_compat[] = {
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 7/7] ARM: Kirkwood: switch to DT clock providers
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:28 ` Andrew Lunn
-1 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: mturquette-QSEj5FYQhm4dnm+yROfE0A
Cc: Thomas Petazzoni, Andrew Lunn, Jason Cooper,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux ARM
With true DT clock providers available switch Kirkwood clock setup in
DT- enabled boards. While AUXDATA can be removed completely from bus
probing, some devices still don't know about DT. Therefore, some clkdev
aliases are created until these devices also move to DT.
Signed-off-by: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>
---
arch/arm/boot/dts/kirkwood.dtsi | 22 +++++++++
arch/arm/mach-kirkwood/Kconfig | 2 +
arch/arm/mach-kirkwood/board-dt.c | 72 +++++++++++++++++++++++------
arch/arm/plat-orion/include/plat/common.h | 1 +
4 files changed, 84 insertions(+), 13 deletions(-)
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index 4e5b815..5c85a57 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -19,6 +19,12 @@
#address-cells = <1>;
#size-cells = <1>;
+ core_clk: core-clocks@10030 {
+ compatible = "marvell,kirkwood-core-clocks";
+ reg = <0x10030 0x4>;
+ #clock-cells = <1>;
+ };
+
gpio0: gpio@10100 {
compatible = "marvell,orion-gpio";
#gpio-cells = <2>;
@@ -42,6 +48,7 @@
reg = <0x12000 0x100>;
reg-shift = <2>;
interrupts = <33>;
+ clocks = <&clk_gate 7>;
/* set clock-frequency in board dts */
status = "disabled";
};
@@ -51,6 +58,7 @@
reg = <0x12100 0x100>;
reg-shift = <2>;
interrupts = <34>;
+ clocks = <&clk_gate 7>;
/* set clock-frequency in board dts */
status = "disabled";
};
@@ -68,12 +76,21 @@
cell-index = <0>;
interrupts = <23>;
reg = <0x10600 0x28>;
+ clocks = <&clk_gate 7>;
status = "disabled";
};
+ clk_gate: clock-gating-control@2011c {
+ compatible = "marvell,kirkwood-clock-gating";
+ reg = <0x2011c 0x4>;
+ clocks = <&core_clk 0>;
+ #clock-cells = <1>;
+ };
+
wdt@20300 {
compatible = "marvell,orion-wdt";
reg = <0x20300 0x28>;
+ clocks = <&clk_gate 7>;
status = "okay";
};
@@ -81,6 +98,8 @@
compatible = "marvell,orion-sata";
reg = <0x80000 0x5000>;
interrupts = <21>;
+ clocks = <&clk_gate 14>, <&clk_gate 15>;
+ clock-names = "0", "1";
status = "disabled";
};
@@ -94,6 +113,7 @@
reg = <0x3000000 0x400>;
chip-delay = <25>;
/* set partition map and/or chip-delay in board dts */
+ clocks = <&clk_gate 7>;
status = "disabled";
};
@@ -104,6 +124,7 @@
#size-cells = <0>;
interrupts = <29>;
clock-frequency = <100000>;
+ clocks = <&clk_gate 7>;
status = "disabled";
};
@@ -113,6 +134,7 @@
<0xf5000000 0x800>;
reg-names = "regs", "sram";
interrupts = <22>;
+ clocks = <&clk_gate 17>;
status = "okay";
};
};
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index 50bca50..2833492 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -46,6 +46,8 @@ config MACH_GURUPLUG
config ARCH_KIRKWOOD_DT
bool "Marvell Kirkwood Flattened Device Tree"
+ select MVEBU_CLK_CORE
+ select MVEBU_CLK_GATING
select USE_OF
help
Say 'Y' here if you want your kernel to support the
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index d94872f..0129cdc 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -14,11 +14,15 @@
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/mvebu.h>
#include <linux/kexec.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/bridge-regs.h>
+#include <linux/platform_data/usb-ehci-orion.h>
#include <plat/irq.h>
+#include <plat/common.h>
#include "common.h"
static struct of_device_id kirkwood_dt_match_table[] __initdata = {
@@ -26,16 +30,59 @@ static struct of_device_id kirkwood_dt_match_table[] __initdata = {
{ }
};
-struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
- OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
- OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
- NULL),
- OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
- OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL),
- OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL),
- OF_DEV_AUXDATA("marvell,orion-crypto", 0xf1030000, "mv_crypto", NULL),
- {},
-};
+/*
+ * There are still devices that doesn't know about DT yet. Get clock
+ * gates here and add a clock lookup alias, so that old platform
+ * devices still work.
+*/
+
+static void __init kirkwood_legacy_clk_init(void)
+{
+
+ struct device_node *np = of_find_compatible_node(NULL, NULL,
+ "marvell,kirkwood-clock-gating");
+
+ struct of_phandle_args clkspec;
+
+ clkspec.np = np;
+ clkspec.args_count = 1;
+
+ clkspec.args[0] = CGC_BIT_GE0;
+ orion_clkdev_add(NULL, "mv643xx_eth_port.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_PEX0;
+ orion_clkdev_add("0", "pcie",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_USB0;
+ orion_clkdev_add(NULL, "orion-ehci.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_XOR0;
+ orion_clkdev_add(NULL, "mv_xor_shared.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_XOR1;
+ orion_clkdev_add(NULL, "mv_xor_shared.1",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_PEX1;
+ orion_clkdev_add("1", "pcie",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_GE1;
+ orion_clkdev_add(NULL, "mv643xx_eth_port.1",
+ of_clk_get_from_provider(&clkspec));
+
+}
+
+static void __init kirkwood_of_clk_init(void)
+{
+ mvebu_clocks_init();
+ mvebu_clk_gating_init();
+ kirkwood_legacy_clk_init();
+}
static void __init kirkwood_dt_init(void)
{
@@ -54,7 +101,7 @@ static void __init kirkwood_dt_init(void)
kirkwood_l2_init();
/* Setup root of clk tree */
- kirkwood_clk_init();
+ kirkwood_of_clk_init();
/* internal devices that every board has */
kirkwood_xor0_init();
@@ -94,8 +141,7 @@ static void __init kirkwood_dt_init(void)
if (of_machine_is_compatible("keymile,km_kirkwood"))
km_kirkwood_init();
- of_platform_populate(NULL, kirkwood_dt_match_table,
- kirkwood_auxdata_lookup, NULL);
+ of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL);
}
static const char *kirkwood_dt_board_compat[] = {
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
index 6bbc3fe..e06fc5f 100644
--- a/arch/arm/plat-orion/include/plat/common.h
+++ b/arch/arm/plat-orion/include/plat/common.h
@@ -12,6 +12,7 @@
#include <linux/mv643xx_eth.h>
struct dsa_platform_data;
+struct mv_sata_platform_data;
void __init orion_uart0_init(void __iomem *membase,
resource_size_t mapbase,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 7/7] ARM: Kirkwood: switch to DT clock providers
@ 2012-11-15 21:28 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-15 21:28 UTC (permalink / raw)
To: linux-arm-kernel
With true DT clock providers available switch Kirkwood clock setup in
DT- enabled boards. While AUXDATA can be removed completely from bus
probing, some devices still don't know about DT. Therefore, some clkdev
aliases are created until these devices also move to DT.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
arch/arm/boot/dts/kirkwood.dtsi | 22 +++++++++
arch/arm/mach-kirkwood/Kconfig | 2 +
arch/arm/mach-kirkwood/board-dt.c | 72 +++++++++++++++++++++++------
arch/arm/plat-orion/include/plat/common.h | 1 +
4 files changed, 84 insertions(+), 13 deletions(-)
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index 4e5b815..5c85a57 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -19,6 +19,12 @@
#address-cells = <1>;
#size-cells = <1>;
+ core_clk: core-clocks at 10030 {
+ compatible = "marvell,kirkwood-core-clocks";
+ reg = <0x10030 0x4>;
+ #clock-cells = <1>;
+ };
+
gpio0: gpio at 10100 {
compatible = "marvell,orion-gpio";
#gpio-cells = <2>;
@@ -42,6 +48,7 @@
reg = <0x12000 0x100>;
reg-shift = <2>;
interrupts = <33>;
+ clocks = <&clk_gate 7>;
/* set clock-frequency in board dts */
status = "disabled";
};
@@ -51,6 +58,7 @@
reg = <0x12100 0x100>;
reg-shift = <2>;
interrupts = <34>;
+ clocks = <&clk_gate 7>;
/* set clock-frequency in board dts */
status = "disabled";
};
@@ -68,12 +76,21 @@
cell-index = <0>;
interrupts = <23>;
reg = <0x10600 0x28>;
+ clocks = <&clk_gate 7>;
status = "disabled";
};
+ clk_gate: clock-gating-control at 2011c {
+ compatible = "marvell,kirkwood-clock-gating";
+ reg = <0x2011c 0x4>;
+ clocks = <&core_clk 0>;
+ #clock-cells = <1>;
+ };
+
wdt at 20300 {
compatible = "marvell,orion-wdt";
reg = <0x20300 0x28>;
+ clocks = <&clk_gate 7>;
status = "okay";
};
@@ -81,6 +98,8 @@
compatible = "marvell,orion-sata";
reg = <0x80000 0x5000>;
interrupts = <21>;
+ clocks = <&clk_gate 14>, <&clk_gate 15>;
+ clock-names = "0", "1";
status = "disabled";
};
@@ -94,6 +113,7 @@
reg = <0x3000000 0x400>;
chip-delay = <25>;
/* set partition map and/or chip-delay in board dts */
+ clocks = <&clk_gate 7>;
status = "disabled";
};
@@ -104,6 +124,7 @@
#size-cells = <0>;
interrupts = <29>;
clock-frequency = <100000>;
+ clocks = <&clk_gate 7>;
status = "disabled";
};
@@ -113,6 +134,7 @@
<0xf5000000 0x800>;
reg-names = "regs", "sram";
interrupts = <22>;
+ clocks = <&clk_gate 17>;
status = "okay";
};
};
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index 50bca50..2833492 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -46,6 +46,8 @@ config MACH_GURUPLUG
config ARCH_KIRKWOOD_DT
bool "Marvell Kirkwood Flattened Device Tree"
+ select MVEBU_CLK_CORE
+ select MVEBU_CLK_GATING
select USE_OF
help
Say 'Y' here if you want your kernel to support the
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index d94872f..0129cdc 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -14,11 +14,15 @@
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/mvebu.h>
#include <linux/kexec.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/bridge-regs.h>
+#include <linux/platform_data/usb-ehci-orion.h>
#include <plat/irq.h>
+#include <plat/common.h>
#include "common.h"
static struct of_device_id kirkwood_dt_match_table[] __initdata = {
@@ -26,16 +30,59 @@ static struct of_device_id kirkwood_dt_match_table[] __initdata = {
{ }
};
-struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
- OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
- OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
- NULL),
- OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
- OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL),
- OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL),
- OF_DEV_AUXDATA("marvell,orion-crypto", 0xf1030000, "mv_crypto", NULL),
- {},
-};
+/*
+ * There are still devices that doesn't know about DT yet. Get clock
+ * gates here and add a clock lookup alias, so that old platform
+ * devices still work.
+*/
+
+static void __init kirkwood_legacy_clk_init(void)
+{
+
+ struct device_node *np = of_find_compatible_node(NULL, NULL,
+ "marvell,kirkwood-clock-gating");
+
+ struct of_phandle_args clkspec;
+
+ clkspec.np = np;
+ clkspec.args_count = 1;
+
+ clkspec.args[0] = CGC_BIT_GE0;
+ orion_clkdev_add(NULL, "mv643xx_eth_port.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_PEX0;
+ orion_clkdev_add("0", "pcie",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_USB0;
+ orion_clkdev_add(NULL, "orion-ehci.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_XOR0;
+ orion_clkdev_add(NULL, "mv_xor_shared.0",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_XOR1;
+ orion_clkdev_add(NULL, "mv_xor_shared.1",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_PEX1;
+ orion_clkdev_add("1", "pcie",
+ of_clk_get_from_provider(&clkspec));
+
+ clkspec.args[0] = CGC_BIT_GE1;
+ orion_clkdev_add(NULL, "mv643xx_eth_port.1",
+ of_clk_get_from_provider(&clkspec));
+
+}
+
+static void __init kirkwood_of_clk_init(void)
+{
+ mvebu_clocks_init();
+ mvebu_clk_gating_init();
+ kirkwood_legacy_clk_init();
+}
static void __init kirkwood_dt_init(void)
{
@@ -54,7 +101,7 @@ static void __init kirkwood_dt_init(void)
kirkwood_l2_init();
/* Setup root of clk tree */
- kirkwood_clk_init();
+ kirkwood_of_clk_init();
/* internal devices that every board has */
kirkwood_xor0_init();
@@ -94,8 +141,7 @@ static void __init kirkwood_dt_init(void)
if (of_machine_is_compatible("keymile,km_kirkwood"))
km_kirkwood_init();
- of_platform_populate(NULL, kirkwood_dt_match_table,
- kirkwood_auxdata_lookup, NULL);
+ of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL);
}
static const char *kirkwood_dt_board_compat[] = {
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
index 6bbc3fe..e06fc5f 100644
--- a/arch/arm/plat-orion/include/plat/common.h
+++ b/arch/arm/plat-orion/include/plat/common.h
@@ -12,6 +12,7 @@
#include <linux/mv643xx_eth.h>
struct dsa_platform_data;
+struct mv_sata_platform_data;
void __init orion_uart0_init(void __iomem *membase,
resource_size_t mapbase,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCH 2/7] clk: mvebu: add armada-370-xp CPU specific clocks
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:44 ` Thomas Petazzoni
-1 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-15 21:44 UTC (permalink / raw)
To: Andrew Lunn
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
mturquette-QSEj5FYQhm4dnm+yROfE0A, Jason Cooper, linux ARM
Dear Andrew Lunn,
On Thu, 15 Nov 2012 22:28:21 +0100, Andrew Lunn wrote:
> From: Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
>
> Add Armada 370/XP specific CPU clocks
>
> Signed-off-by: Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
> .../devicetree/bindings/clock/mvebu-core-clock.txt | 18 +--
The changes to this file.
> .../devicetree/bindings/clock/mvebu-cpu-clock.txt | 21 +++
> drivers/clk/mvebu/Kconfig | 3 +
> drivers/clk/mvebu/Makefile | 1 +
> drivers/clk/mvebu/clk-core.c | 4 +-
And this one don't appear to belong in this commit, do they?
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 2/7] clk: mvebu: add armada-370-xp CPU specific clocks
@ 2012-11-15 21:44 ` Thomas Petazzoni
0 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-15 21:44 UTC (permalink / raw)
To: linux-arm-kernel
Dear Andrew Lunn,
On Thu, 15 Nov 2012 22:28:21 +0100, Andrew Lunn wrote:
> From: Gregory CLEMENT <gregory.clement@free-electrons.com>
>
> Add Armada 370/XP specific CPU clocks
>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> .../devicetree/bindings/clock/mvebu-core-clock.txt | 18 +--
The changes to this file.
> .../devicetree/bindings/clock/mvebu-cpu-clock.txt | 21 +++
> drivers/clk/mvebu/Kconfig | 3 +
> drivers/clk/mvebu/Makefile | 1 +
> drivers/clk/mvebu/clk-core.c | 4 +-
And this one don't appear to belong in this commit, do they?
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 3/7] clk: armada-370-xp: add support for clock framework
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:46 ` Thomas Petazzoni
-1 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-15 21:46 UTC (permalink / raw)
To: Andrew Lunn
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
mturquette-QSEj5FYQhm4dnm+yROfE0A, Jason Cooper, linux ARM
Dear Andrew Lunn,
On Thu, 15 Nov 2012 22:28:22 +0100, Andrew Lunn wrote:
> diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
> index 416d46e..e5f0ae2 100644
> --- a/arch/arm/mach-mvebu/Kconfig
> +++ b/arch/arm/mach-mvebu/Kconfig
> @@ -9,11 +9,17 @@ config ARCH_MVEBU
> select PINCTRL
> select PLAT_ORION
> select SPARSE_IRQ
> + select CLKDEV_LOOKUP
> + select MVEBU_CLK_CORE
> + select MVEBU_CLK_CPU
>
> if ARCH_MVEBU
>
> menu "Marvell SOC with device tree"
>
> +config MVEBU_CLK_CPU
> + bool
> +
This config option is added to drivers/clk/mvebu/Kconfig in patch 2/7,
so I think it shouldn't be added here in patch 3/7.
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 3/7] clk: armada-370-xp: add support for clock framework
@ 2012-11-15 21:46 ` Thomas Petazzoni
0 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-15 21:46 UTC (permalink / raw)
To: linux-arm-kernel
Dear Andrew Lunn,
On Thu, 15 Nov 2012 22:28:22 +0100, Andrew Lunn wrote:
> diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
> index 416d46e..e5f0ae2 100644
> --- a/arch/arm/mach-mvebu/Kconfig
> +++ b/arch/arm/mach-mvebu/Kconfig
> @@ -9,11 +9,17 @@ config ARCH_MVEBU
> select PINCTRL
> select PLAT_ORION
> select SPARSE_IRQ
> + select CLKDEV_LOOKUP
> + select MVEBU_CLK_CORE
> + select MVEBU_CLK_CPU
>
> if ARCH_MVEBU
>
> menu "Marvell SOC with device tree"
>
> +config MVEBU_CLK_CPU
> + bool
> +
This config option is added to drivers/clk/mvebu/Kconfig in patch 2/7,
so I think it shouldn't be added here in patch 3/7.
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 4/7] clocksource: time-armada-370-xp converted to clk framework
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:49 ` Thomas Petazzoni
-1 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-15 21:49 UTC (permalink / raw)
To: Andrew Lunn
Cc: mturquette-QSEj5FYQhm4dnm+yROfE0A, Jason Cooper, John Stultz,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux ARM
Dear Andrew Lunn,
Title should be "clocksource: convert time-armada-370-xp to the clk
framework".
On Thu, 15 Nov 2012 22:28:23 +0100, Andrew Lunn wrote:
> diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c
> index 4674f94..a4605fd 100644
> --- a/drivers/clocksource/time-armada-370-xp.c
> +++ b/drivers/clocksource/time-armada-370-xp.c
> @@ -18,6 +18,7 @@
> #include <linux/init.h>
> #include <linux/platform_device.h>
> #include <linux/kernel.h>
> +#include <linux/clk.h>
> #include <linux/timer.h>
> #include <linux/clockchips.h>
> #include <linux/interrupt.h>
> @@ -167,7 +168,6 @@ void __init armada_370_xp_timer_init(void)
> u32 u;
> struct device_node *np;
> unsigned int timer_clk;
> - int ret;
> np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-timer");
> timer_base = of_iomap(np, 0);
> WARN_ON(!timer_base);
> @@ -179,13 +179,14 @@ void __init armada_370_xp_timer_init(void)
> timer_base + TIMER_CTRL_OFF);
> timer_clk = 25000000;
> } else {
> - u32 clk = 0;
> - ret = of_property_read_u32(np, "clock-frequency", &clk);
> - WARN_ON(!clk || ret < 0);
> + unsigned long rate = 0;
> + struct clk *clk = of_clk_get(np, 0);
> + WARN_ON(IS_ERR(clk));
> + rate = clk_get_rate(clk);
> u = readl(timer_base + TIMER_CTRL_OFF);
> writel(u & ~(TIMER0_25MHZ | TIMER1_25MHZ),
> timer_base + TIMER_CTRL_OFF);
> - timer_clk = clk / TIMER_DIVIDER;
> + timer_clk = rate / TIMER_DIVIDER;
> }
>
> /* We use timer 0 as clocksource, and timer 1 for
This change requires an update to
Documentation/devicetree/bindings/arm/armada-370-xp-timer.txt. The
previous clock-frequency property was not documented, but maybe the new
clocks property should.
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 4/7] clocksource: time-armada-370-xp converted to clk framework
@ 2012-11-15 21:49 ` Thomas Petazzoni
0 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-15 21:49 UTC (permalink / raw)
To: linux-arm-kernel
Dear Andrew Lunn,
Title should be "clocksource: convert time-armada-370-xp to the clk
framework".
On Thu, 15 Nov 2012 22:28:23 +0100, Andrew Lunn wrote:
> diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c
> index 4674f94..a4605fd 100644
> --- a/drivers/clocksource/time-armada-370-xp.c
> +++ b/drivers/clocksource/time-armada-370-xp.c
> @@ -18,6 +18,7 @@
> #include <linux/init.h>
> #include <linux/platform_device.h>
> #include <linux/kernel.h>
> +#include <linux/clk.h>
> #include <linux/timer.h>
> #include <linux/clockchips.h>
> #include <linux/interrupt.h>
> @@ -167,7 +168,6 @@ void __init armada_370_xp_timer_init(void)
> u32 u;
> struct device_node *np;
> unsigned int timer_clk;
> - int ret;
> np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-timer");
> timer_base = of_iomap(np, 0);
> WARN_ON(!timer_base);
> @@ -179,13 +179,14 @@ void __init armada_370_xp_timer_init(void)
> timer_base + TIMER_CTRL_OFF);
> timer_clk = 25000000;
> } else {
> - u32 clk = 0;
> - ret = of_property_read_u32(np, "clock-frequency", &clk);
> - WARN_ON(!clk || ret < 0);
> + unsigned long rate = 0;
> + struct clk *clk = of_clk_get(np, 0);
> + WARN_ON(IS_ERR(clk));
> + rate = clk_get_rate(clk);
> u = readl(timer_base + TIMER_CTRL_OFF);
> writel(u & ~(TIMER0_25MHZ | TIMER1_25MHZ),
> timer_base + TIMER_CTRL_OFF);
> - timer_clk = clk / TIMER_DIVIDER;
> + timer_clk = rate / TIMER_DIVIDER;
> }
>
> /* We use timer 0 as clocksource, and timer 1 for
This change requires an update to
Documentation/devicetree/bindings/arm/armada-370-xp-timer.txt. The
previous clock-frequency property was not documented, but maybe the new
clocks property should.
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 6/7] ARM: dove: switch to DT clock providers
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:52 ` Thomas Petazzoni
-1 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-15 21:52 UTC (permalink / raw)
To: Andrew Lunn
Cc: mturquette-QSEj5FYQhm4dnm+yROfE0A, Jason Cooper,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux ARM,
Sebastian Hesselbarth
Dear Andrew Lunn,
On Thu, 15 Nov 2012 22:28:25 +0100, Andrew Lunn wrote:
> + core_clk: core-clocks@d0214 {
> + compatible = "marvell,dove-core-clocks";
> + reg = <0xd0214 0x4>;
> + #clock-cells = <1>;
> + };
> +
> + clk_gate: clock-gating-control@d0038 {
> + compatible = "marvell,dove-clock-gating";
> + reg = <0xd0038 0x4>;
> + clocks = <&core_clk 0>;
> + #clock-cells = <1>;
> + };
I'm nitpicking maybe, but names lack a bit of coherency here:
core_clk vs. clk_gate
marvell,dove-core-clocks vs. marvell,dove-clock-gating
Maybe:
core_clk / gate_clk
marvell,dove-core-clocks / marvell,dove-gating-clocks
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 6/7] ARM: dove: switch to DT clock providers
@ 2012-11-15 21:52 ` Thomas Petazzoni
0 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-15 21:52 UTC (permalink / raw)
To: linux-arm-kernel
Dear Andrew Lunn,
On Thu, 15 Nov 2012 22:28:25 +0100, Andrew Lunn wrote:
> + core_clk: core-clocks at d0214 {
> + compatible = "marvell,dove-core-clocks";
> + reg = <0xd0214 0x4>;
> + #clock-cells = <1>;
> + };
> +
> + clk_gate: clock-gating-control at d0038 {
> + compatible = "marvell,dove-clock-gating";
> + reg = <0xd0038 0x4>;
> + clocks = <&core_clk 0>;
> + #clock-cells = <1>;
> + };
I'm nitpicking maybe, but names lack a bit of coherency here:
core_clk vs. clk_gate
marvell,dove-core-clocks vs. marvell,dove-clock-gating
Maybe:
core_clk / gate_clk
marvell,dove-core-clocks / marvell,dove-gating-clocks
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 0/7] core, cpu and gated clocks for mvebu
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-15 21:54 ` Thomas Petazzoni
-1 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-15 21:54 UTC (permalink / raw)
To: Andrew Lunn
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
mturquette-QSEj5FYQhm4dnm+yROfE0A, Jason Cooper, linux ARM
Dear Andrew Lunn,
On Thu, 15 Nov 2012 22:28:19 +0100, Andrew Lunn wrote:
> This patchset combines code from Gregory Clement, Sebastian
> Hesselbarth and myself to implement core clks, cpu clock and gated
> clocks on Marvel MVEBU SoCs.
>
> The Armada 370/XP core clock code is a refactored version of the
> already submitted and ACKed code from Gregory. It has been made to fit
> inside a framework developed by Sebastian which can handle all MVEBU
> SoCs. The Armarda 370/XP SoCs have more core clocks than the older SoCs, and
> the framework needs to handle this. Rather than specify the clock
> frequencies in DT, a Sample At Reset register is used, which describes
> each core clock frequency.
>
> Armarda XP is an SMP processor, with each CPU having its own
> clock. Gregories code for this has been taken as is.
>
> The Armarda 370/XP clock source has been converted to the common clock
> framework.
>
> Dove, Kirkword, and probably Armarda 370/XP have the ability to gate
> clocks to various blocks. A clk-gate clock is created for each of the
> gateable clocks on Dove and Kirkwood. Armarda 370/XP clock gates are
> currently unimplemented. Dove and Kirkwood board-dt.c and DT
> descriptions are then modified to make use of these clk gates.
I had a quick look and made a few comments, but overall, it looks
really great. I really hope we can get this in 3.8.
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 0/7] core, cpu and gated clocks for mvebu
@ 2012-11-15 21:54 ` Thomas Petazzoni
0 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-15 21:54 UTC (permalink / raw)
To: linux-arm-kernel
Dear Andrew Lunn,
On Thu, 15 Nov 2012 22:28:19 +0100, Andrew Lunn wrote:
> This patchset combines code from Gregory Clement, Sebastian
> Hesselbarth and myself to implement core clks, cpu clock and gated
> clocks on Marvel MVEBU SoCs.
>
> The Armada 370/XP core clock code is a refactored version of the
> already submitted and ACKed code from Gregory. It has been made to fit
> inside a framework developed by Sebastian which can handle all MVEBU
> SoCs. The Armarda 370/XP SoCs have more core clocks than the older SoCs, and
> the framework needs to handle this. Rather than specify the clock
> frequencies in DT, a Sample At Reset register is used, which describes
> each core clock frequency.
>
> Armarda XP is an SMP processor, with each CPU having its own
> clock. Gregories code for this has been taken as is.
>
> The Armarda 370/XP clock source has been converted to the common clock
> framework.
>
> Dove, Kirkword, and probably Armarda 370/XP have the ability to gate
> clocks to various blocks. A clk-gate clock is created for each of the
> gateable clocks on Dove and Kirkwood. Armarda 370/XP clock gates are
> currently unimplemented. Dove and Kirkwood board-dt.c and DT
> descriptions are then modified to make use of these clk gates.
I had a quick look and made a few comments, but overall, it looks
really great. I really hope we can get this in 3.8.
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 0/7] core, cpu and gated clocks for mvebu
2012-11-15 21:54 ` Thomas Petazzoni
@ 2012-11-16 7:32 ` Andrew Lunn
-1 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-16 7:32 UTC (permalink / raw)
To: Thomas Petazzoni
Cc: Andrew Lunn, mturquette-QSEj5FYQhm4dnm+yROfE0A, Jason Cooper,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux ARM
> I had a quick look and made a few comments, but overall, it looks
> really great. I really hope we can get this in 3.8.
Hi Thomas
Thanks for the quick feedback.
It looks like i squashed some patches from Sebastian in the wrong
place. I will fix this and your other comments. I will probably send
out a new version tomorrow to give others chance to comment.
Andrew
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 0/7] core, cpu and gated clocks for mvebu
@ 2012-11-16 7:32 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-16 7:32 UTC (permalink / raw)
To: linux-arm-kernel
> I had a quick look and made a few comments, but overall, it looks
> really great. I really hope we can get this in 3.8.
Hi Thomas
Thanks for the quick feedback.
It looks like i squashed some patches from Sebastian in the wrong
place. I will fix this and your other comments. I will probably send
out a new version tomorrow to give others chance to comment.
Andrew
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 0/7] core, cpu and gated clocks for mvebu
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-16 12:51 ` Gregory CLEMENT
-1 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 12:51 UTC (permalink / raw)
To: Andrew Lunn, mturquette-QSEj5FYQhm4dnm+yROfE0A
Cc: Thomas Petazzoni, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
Jason Cooper, linux ARM
On 11/15/2012 10:28 PM, Andrew Lunn wrote:
> This patchset combines code from Gregory Clement, Sebastian
> Hesselbarth and myself to implement core clks, cpu clock and gated
> clocks on Marvel MVEBU SoCs.
>
> The Armada 370/XP core clock code is a refactored version of the
> already submitted and ACKed code from Gregory. It has been made to fit
> inside a framework developed by Sebastian which can handle all MVEBU
> SoCs. The Armarda 370/XP SoCs have more core clocks than the older SoCs, and
> the framework needs to handle this. Rather than specify the clock
> frequencies in DT, a Sample At Reset register is used, which describes
> each core clock frequency.
>
> Armarda XP is an SMP processor, with each CPU having its own
> clock. Gregories code for this has been taken as is.
>
> The Armarda 370/XP clock source has been converted to the common clock
> framework.
>
> Dove, Kirkword, and probably Armarda 370/XP have the ability to gate
> clocks to various blocks. A clk-gate clock is created for each of the
> gateable clocks on Dove and Kirkwood. Armarda 370/XP clock gates are
> currently unimplemented. Dove and Kirkwood board-dt.c and DT
> descriptions are then modified to make use of these clk gates.
>
> This code has been tested on:
>
> Kirkwood based QNAP TS219
> Armarda 370 based mirabox
> Armara XP based OpenBlocks
>
> and by Sebastian on:
>
> Dove based Cubox.
>
Hi Andrew,
great job!
I have only few comments on the first patch.
Besides this I have tested the whole series on my Armada 370 and
Armada XP development boards. With these boards I had the possibility
to change the frequency configuration. I also enable to
COMMON_CLK_DEBUG to check the clock rate value, and after having done
the tests on few combination and I didn't see any regression.
For the first 4 patches you can add my
Tested-by Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>.
Mike I hope you will be able to have a look on the next version. With
the few incoming changes in the next version, this series will be at
least as good as mine and the only notable difference for the first
patches of this series is just adding new SoCs with more or less the
same framework.
Thanks
> Andrew Lunn (1):
> ARM: Kirkwood: switch to DT clock providers
>
> Gregory CLEMENT (3):
> clk: mvebu: add armada-370-xp CPU specific clocks
> clk: armada-370-xp: add support for clock framework
> clocksource: time-armada-370-xp converted to clk framework
>
> Sebastian Hesselbarth (3):
> clk: mvebu: add mvebu core clocks.
> clk: mvebu: add clock gating control provider for DT
> ARM: dove: switch to DT clock providers
>
> .../devicetree/bindings/clock/mvebu-core-clock.txt | 47 ++
> .../devicetree/bindings/clock/mvebu-cpu-clock.txt | 21 +
> .../bindings/clock/mvebu-gated-clock.txt | 76 +++
> arch/arm/Kconfig | 1 +
> arch/arm/boot/dts/armada-370-db.dts | 4 -
> arch/arm/boot/dts/armada-370-xp.dtsi | 1 +
> arch/arm/boot/dts/armada-370.dtsi | 7 +
> arch/arm/boot/dts/armada-xp.dtsi | 42 ++
> arch/arm/boot/dts/dove.dtsi | 20 +
> arch/arm/boot/dts/kirkwood.dtsi | 22 +
> arch/arm/mach-dove/Kconfig | 2 +
> arch/arm/mach-dove/common.c | 64 +-
> arch/arm/mach-kirkwood/Kconfig | 2 +
> arch/arm/mach-kirkwood/board-dt.c | 72 ++-
> arch/arm/mach-mvebu/Kconfig | 6 +
> arch/arm/mach-mvebu/armada-370-xp.c | 9 +-
> arch/arm/plat-orion/include/plat/common.h | 1 +
> drivers/clk/Kconfig | 2 +
> drivers/clk/Makefile | 1 +
> drivers/clk/mvebu/Kconfig | 8 +
> drivers/clk/mvebu/Makefile | 3 +
> drivers/clk/mvebu/clk-core.c | 675 ++++++++++++++++++++
> drivers/clk/mvebu/clk-core.h | 18 +
> drivers/clk/mvebu/clk-cpu.c | 155 +++++
> drivers/clk/mvebu/clk-cpu.h | 18 +
> drivers/clk/mvebu/clk-gating-ctrl.c | 177 +++++
> drivers/clk/mvebu/clk.c | 37 ++
> drivers/clocksource/time-armada-370-xp.c | 11 +-
> include/linux/clk/mvebu.h | 23 +
> 29 files changed, 1487 insertions(+), 38 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
> create mode 100644 Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
> create mode 100644 Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
> create mode 100644 drivers/clk/mvebu/Kconfig
> create mode 100644 drivers/clk/mvebu/Makefile
> create mode 100644 drivers/clk/mvebu/clk-core.c
> create mode 100644 drivers/clk/mvebu/clk-core.h
> create mode 100644 drivers/clk/mvebu/clk-cpu.c
> create mode 100644 drivers/clk/mvebu/clk-cpu.h
> create mode 100644 drivers/clk/mvebu/clk-gating-ctrl.c
> create mode 100644 drivers/clk/mvebu/clk.c
> create mode 100644 include/linux/clk/mvebu.h
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 0/7] core, cpu and gated clocks for mvebu
@ 2012-11-16 12:51 ` Gregory CLEMENT
0 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 12:51 UTC (permalink / raw)
To: linux-arm-kernel
On 11/15/2012 10:28 PM, Andrew Lunn wrote:
> This patchset combines code from Gregory Clement, Sebastian
> Hesselbarth and myself to implement core clks, cpu clock and gated
> clocks on Marvel MVEBU SoCs.
>
> The Armada 370/XP core clock code is a refactored version of the
> already submitted and ACKed code from Gregory. It has been made to fit
> inside a framework developed by Sebastian which can handle all MVEBU
> SoCs. The Armarda 370/XP SoCs have more core clocks than the older SoCs, and
> the framework needs to handle this. Rather than specify the clock
> frequencies in DT, a Sample At Reset register is used, which describes
> each core clock frequency.
>
> Armarda XP is an SMP processor, with each CPU having its own
> clock. Gregories code for this has been taken as is.
>
> The Armarda 370/XP clock source has been converted to the common clock
> framework.
>
> Dove, Kirkword, and probably Armarda 370/XP have the ability to gate
> clocks to various blocks. A clk-gate clock is created for each of the
> gateable clocks on Dove and Kirkwood. Armarda 370/XP clock gates are
> currently unimplemented. Dove and Kirkwood board-dt.c and DT
> descriptions are then modified to make use of these clk gates.
>
> This code has been tested on:
>
> Kirkwood based QNAP TS219
> Armarda 370 based mirabox
> Armara XP based OpenBlocks
>
> and by Sebastian on:
>
> Dove based Cubox.
>
Hi Andrew,
great job!
I have only few comments on the first patch.
Besides this I have tested the whole series on my Armada 370 and
Armada XP development boards. With these boards I had the possibility
to change the frequency configuration. I also enable to
COMMON_CLK_DEBUG to check the clock rate value, and after having done
the tests on few combination and I didn't see any regression.
For the first 4 patches you can add my
Tested-by Gregory CLEMENT <gregory.clement@free-electrons.com>.
Mike I hope you will be able to have a look on the next version. With
the few incoming changes in the next version, this series will be at
least as good as mine and the only notable difference for the first
patches of this series is just adding new SoCs with more or less the
same framework.
Thanks
> Andrew Lunn (1):
> ARM: Kirkwood: switch to DT clock providers
>
> Gregory CLEMENT (3):
> clk: mvebu: add armada-370-xp CPU specific clocks
> clk: armada-370-xp: add support for clock framework
> clocksource: time-armada-370-xp converted to clk framework
>
> Sebastian Hesselbarth (3):
> clk: mvebu: add mvebu core clocks.
> clk: mvebu: add clock gating control provider for DT
> ARM: dove: switch to DT clock providers
>
> .../devicetree/bindings/clock/mvebu-core-clock.txt | 47 ++
> .../devicetree/bindings/clock/mvebu-cpu-clock.txt | 21 +
> .../bindings/clock/mvebu-gated-clock.txt | 76 +++
> arch/arm/Kconfig | 1 +
> arch/arm/boot/dts/armada-370-db.dts | 4 -
> arch/arm/boot/dts/armada-370-xp.dtsi | 1 +
> arch/arm/boot/dts/armada-370.dtsi | 7 +
> arch/arm/boot/dts/armada-xp.dtsi | 42 ++
> arch/arm/boot/dts/dove.dtsi | 20 +
> arch/arm/boot/dts/kirkwood.dtsi | 22 +
> arch/arm/mach-dove/Kconfig | 2 +
> arch/arm/mach-dove/common.c | 64 +-
> arch/arm/mach-kirkwood/Kconfig | 2 +
> arch/arm/mach-kirkwood/board-dt.c | 72 ++-
> arch/arm/mach-mvebu/Kconfig | 6 +
> arch/arm/mach-mvebu/armada-370-xp.c | 9 +-
> arch/arm/plat-orion/include/plat/common.h | 1 +
> drivers/clk/Kconfig | 2 +
> drivers/clk/Makefile | 1 +
> drivers/clk/mvebu/Kconfig | 8 +
> drivers/clk/mvebu/Makefile | 3 +
> drivers/clk/mvebu/clk-core.c | 675 ++++++++++++++++++++
> drivers/clk/mvebu/clk-core.h | 18 +
> drivers/clk/mvebu/clk-cpu.c | 155 +++++
> drivers/clk/mvebu/clk-cpu.h | 18 +
> drivers/clk/mvebu/clk-gating-ctrl.c | 177 +++++
> drivers/clk/mvebu/clk.c | 37 ++
> drivers/clocksource/time-armada-370-xp.c | 11 +-
> include/linux/clk/mvebu.h | 23 +
> 29 files changed, 1487 insertions(+), 38 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
> create mode 100644 Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
> create mode 100644 Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
> create mode 100644 drivers/clk/mvebu/Kconfig
> create mode 100644 drivers/clk/mvebu/Makefile
> create mode 100644 drivers/clk/mvebu/clk-core.c
> create mode 100644 drivers/clk/mvebu/clk-core.h
> create mode 100644 drivers/clk/mvebu/clk-cpu.c
> create mode 100644 drivers/clk/mvebu/clk-cpu.h
> create mode 100644 drivers/clk/mvebu/clk-gating-ctrl.c
> create mode 100644 drivers/clk/mvebu/clk.c
> create mode 100644 include/linux/clk/mvebu.h
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 1/7] clk: mvebu: add mvebu core clocks.
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-16 12:52 ` Gregory CLEMENT
-1 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 12:52 UTC (permalink / raw)
To: Andrew Lunn
Cc: Thomas Petazzoni, mturquette-QSEj5FYQhm4dnm+yROfE0A,
Jason Cooper, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux ARM, Sebastian Hesselbarth
Hi Andrew,
On 11/15/2012 10:28 PM, Andrew Lunn wrote:
> From: Sebastian Hesselbarth <sebastian.hesselbarth-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
> This driver allows to provide DT clocks for core clocks found on
> Marvell Kirkwood, Dove & 370/XP SoCs. The core clock frequencies and
> ratios are determined by decoding the Sample-At-Reset registers.
>
> Although technically correct, using a divider of 0 will lead to
> div_by_zero panic. Let's use a ratio of 0/1 instead to fail later
> with a zero clock.
>
> Signed-off-by: Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>
> ---
> .../devicetree/bindings/clock/mvebu-core-clock.txt | 47 ++
> drivers/clk/Kconfig | 2 +
> drivers/clk/Makefile | 1 +
> drivers/clk/mvebu/Kconfig | 3 +
> drivers/clk/mvebu/Makefile | 1 +
> drivers/clk/mvebu/clk-core.c | 675 ++++++++++++++++++++
> drivers/clk/mvebu/clk-core.h | 18 +
> drivers/clk/mvebu/clk.c | 23 +
> include/linux/clk/mvebu.h | 22 +
> 9 files changed, 792 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
> create mode 100644 drivers/clk/mvebu/Kconfig
> create mode 100644 drivers/clk/mvebu/Makefile
> create mode 100644 drivers/clk/mvebu/clk-core.c
> create mode 100644 drivers/clk/mvebu/clk-core.h
> create mode 100644 drivers/clk/mvebu/clk.c
> create mode 100644 include/linux/clk/mvebu.h
>
> diff --git a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
> new file mode 100644
> index 0000000..84cfae7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
> @@ -0,0 +1,47 @@
> +* Core Clock bindings for Marvell MVEBU SoCs
> +
> +Marvell MVEBU SoCs usually allow to determine core clock frequencies by
> +reading the Sample-At-Reset (SAR) register. The core clock consumer should
> +specify the desired clock by having the clock ID in its "clocks" phandle cell.
> +
> +The following is a list of provided IDs and clock names on Kirkwood and Dove:
> + 0 = tclk (Internal Bus clock)
> + 1 = cpuclk (CPU0 clock)
> + 2 = l2clk (L2 Cache clock derived from CPU0 clock)
> + 3 = ddrclk (DDR controller clock derived from CPU0 clock)
> +
> +The following is a list of provided IDs and clock names on 370/XP:
You should call them Aramda 370 and Aramda XP. You do this modification
in the 2nd patch but it should be squashed in this patch.
> + 0 = tclk (Internal Bus clock)
> + 1 = cpuclk (CPU clock)
> + 2 = nbclk (L2 Cache clock)
> + 3 = hclk (DRAM control clock)
> + 4 = dramclk (DDR clock)
> +
> +Required properties:
> +- compatible : shall be one of the following:
> + "marvell,dove-core-clocks" - for Dove SoC core clocks
> + "marvell,kirkwood-core-clocks" - for Kirkwood SoC (except mv88f6180)
> + "marvell,mv88f6180-core-clocks" - for Kirkwood MV88f6180 SoC
> + "marvell,370-core-clocks" - For 370 SoC core clocks
> + "marvell,xp-core-clocks" - For XP SoC core clocks
Same here.
> +- reg : shall be the register address of the Sample-At-Reset (SAR) register
> +- #clock-cells : from common clock binding; shall be set to 1
> +
> +Optional properties:
> +- clock-output-names : from common clock binding; allows overwrite default clock
> + output names ("tclk", "cpuclk", "l2clk", "ddrclk")
> +
> +Example:
> +
> +core_clk: core-clocks@d0214 {
> + compatible = "marvell,dove-core-clocks";
> + reg = <0xd0214 0x4>;
> + #clock-cells = <1>;
> +};
> +
> +spi0: spi@10600 {
> + compatible = "marvell,orion-spi";
> + /* ... */
> + /* get tclk from core clock provider */
> + clocks = <&core_clk 0>;
> +};
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index bace9e9..60427c0 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -54,3 +54,5 @@ config COMMON_CLK_MAX77686
> This driver supports Maxim 77686 crystal oscillator clock.
>
> endmenu
> +
> +source "drivers/clk/mvebu/Kconfig"
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 71a25b9..d0a14ae 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/
> obj-$(CONFIG_ARCH_U300) += clk-u300.o
> obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
> obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o
> +obj-$(CONFIG_PLAT_ORION) += mvebu/
> ifeq ($(CONFIG_COMMON_CLK), y)
> obj-$(CONFIG_ARCH_MMP) += mmp/
> endif
> diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
> new file mode 100644
> index 0000000..fd7bf97
> --- /dev/null
> +++ b/drivers/clk/mvebu/Kconfig
> @@ -0,0 +1,3 @@
> +config MVEBU_CLK_CORE
> + bool
> +
> diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
> new file mode 100644
> index 0000000..de1d961
> --- /dev/null
> +++ b/drivers/clk/mvebu/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_MVEBU_CLK_CORE) += clk.o clk-core.o
> diff --git a/drivers/clk/mvebu/clk-core.c b/drivers/clk/mvebu/clk-core.c
> new file mode 100644
> index 0000000..26ba835
> --- /dev/null
> +++ b/drivers/clk/mvebu/clk-core.c
> @@ -0,0 +1,675 @@
> +/*
> + * Marvell EBU clock core handling defined at reset
> + *
> + * Copyright (C) 2012 Marvell
> + *
> + * Gregory CLEMENT <gregory.clement-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> + * Sebastian Hesselbarth <sebastian.hesselbarth-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +#include <linux/kernel.h>
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of_address.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include "clk-core.h"
> +
> +struct core_ratio {
> + int id;
> + const char *name;
> +};
> +
> +struct core_clocks {
> + u32 (*get_tclk_freq)(void __iomem *sar);
> + u32 (*get_cpu_freq)(void __iomem *sar);
> + void (*get_clk_ratio)(void __iomem *sar, int id, int *mult, int *div);
> + const struct core_ratio *ratios;
> + int num_ratios;
> +};
> +
> +static struct clk_onecell_data clk_data;
> +
> +static void __init mvebu_clk_core_setup(struct device_node *np,
> + struct core_clocks *coreclk)
> +{
> + const char *tclk_name = "tclk";
> + const char *cpuclk_name = "cpuclk";
> + void __iomem *base;
> + unsigned long rate;
> + int n;
> +
> + base = of_iomap(np, 0);
> + if (WARN_ON(!base))
> + return;
> +
> + /*
> + * Allocate struct for TCLK, cpu clk, and core ratio clocks
> + */
> + clk_data.clk_num = 2 + coreclk->num_ratios;
> + clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *),
> + GFP_KERNEL);
> + if (WARN_ON(!clk_data.clks))
> + return;
> +
> + /*
> + * Register TCLK
> + */
> + of_property_read_string_index(np, "clock-output-names", 0,
> + &tclk_name);
> + rate = coreclk->get_tclk_freq(base);
> + clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL,
> + CLK_IS_ROOT, rate);
> + WARN_ON(IS_ERR(clk_data.clks[0]));
> +
> + /*
> + * Register CPU clock
> + */
> + of_property_read_string_index(np, "clock-output-names", 1,
> + &cpuclk_name);
> + rate = coreclk->get_cpu_freq(base);
> + clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL,
> + CLK_IS_ROOT, rate);
> + WARN_ON(IS_ERR(clk_data.clks[1]));
> +
> + /*
> + * Register fixed-factor clocks derived from CPU clock
> + */
> + for (n = 0; n < coreclk->num_ratios; n++) {
> + const char *rclk_name = coreclk->ratios[n].name;
> + int mult, div;
> +
> + of_property_read_string_index(np, "clock-output-names",
> + 2+n, &rclk_name);
> + coreclk->get_clk_ratio(base, coreclk->ratios[n].id,
> + &mult, &div);
> + clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name,
> + cpuclk_name, 0, mult, div);
> + WARN_ON(IS_ERR(clk_data.clks[2+n]));
> + };
> +
> + /*
> + * SAR register isn't needed anymore
> + */
> + iounmap(base);
> +
> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> +}
> +
> +#ifdef CONFIG_MACH_ARMADA_370_XP
> +/*
> + * 370/XP Sample At Reset is a 64 bit bitfiled split in two register
Add "Armada" in front of 370/XP please.
> + * of 32 bits
> + */
> +
> +#define SARL 0 /* Low part [0:31] */
> +#define SARL_AXP_PCLK_FREQ_OPT 21
> +#define SARL_AXP_PCLK_FREQ_OPT_MASK 0x7
> +#define SARL_A370_PCLK_FREQ_OPT 11
> +#define SARL_A370_PCLK_FREQ_OPT_MASK 0xF
> +#define SARL_AXP_FAB_FREQ_OPT 24
> +#define SARL_AXP_FAB_FREQ_OPT_MASK 0xF
> +#define SARL_A370_FAB_FREQ_OPT 15
> +#define SARL_A370_FAB_FREQ_OPT_MASK 0x1F
> +#define SARL_A370_TCLK_FREQ_OPT 20
> +#define SARL_A370_TCLK_FREQ_OPT_MASK 0x1
> +#define SARH 4 /* High part [32:63] */
> +#define SARH_AXP_PCLK_FREQ_OPT (52-32)
> +#define SARH_AXP_PCLK_FREQ_OPT_MASK 0x1
> +#define SARH_AXP_PCLK_FREQ_OPT_SHIFT 3
> +#define SARH_AXP_FAB_FREQ_OPT (51-32)
> +#define SARH_AXP_FAB_FREQ_OPT_MASK 0x1
> +#define SARH_AXP_FAB_FREQ_OPT_SHIFT 4
> +
> +static const u32 __initconst a370_tclk_frequencies[] = {
In all other part in the kernel the relatives functions to
Armada 370 or Armada XP are suffixed by armada_370 or armada_xp.
Could we do the same here for being consistent?
It will help when one wants to grep code relative to the armada
370 or the armada XP.
> + 16600000,
> + 20000000,
> +};
> +
> +static u32 __init a370_get_tclk_freq(void __iomem *sar)
Same here.
> +{
> + u8 tclk_freq_select = 0;
> +
> + tclk_freq_select = ((readl(sar) >> SARL_A370_TCLK_FREQ_OPT) &
> + SARL_A370_TCLK_FREQ_OPT_MASK);
> + return a370_tclk_frequencies[tclk_freq_select];
> +}
> +
> +static const u32 __initconst a370_cpu_frequencies[] = {
> + 400000000,
> + 533000000,
> + 667000000,
> + 800000000,
> + 1000000000,
> + 1067000000,
> + 1200000000,
> +};
> +
> +static u32 __init a370_get_cpu_freq(void __iomem *sar)
> +{
> + u32 cpu_freq;
> + u8 cpu_freq_select = 0;
> +
> + cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) &
> + SARL_A370_PCLK_FREQ_OPT_MASK);
> + if (cpu_freq_select > ARRAY_SIZE(a370_cpu_frequencies)) {
> + pr_err("CPU freq select unsuported %d\n", cpu_freq_select);
> + cpu_freq = 0;
> + } else
> + cpu_freq = a370_cpu_frequencies[cpu_freq_select];
> +
> + return cpu_freq;
> +}
> +
> +enum { A370_XP_NBCLK, A370_XP_HCLK, A370_XP_DRAMCLK };
> +
> +static const struct core_ratio __initconst a370_xp_core_ratios[] = {
> + { .id = A370_XP_NBCLK, .name = "nbclk" },
> + { .id = A370_XP_HCLK, .name = "hclk" },
> + { .id = A370_XP_DRAMCLK, .name = "dramclk" },
> +};
> +
> +static const int __initconst a370_xp_nbclk_ratios[32][2] = {
> + {0, 1}, {1, 2}, {2, 2}, {2, 2},
> + {1, 2}, {1, 2}, {1, 1}, {2, 3},
> + {0, 1}, {1, 2}, {2, 4}, {0, 1},
> + {1, 2}, {0, 1}, {0, 1}, {2, 2},
> + {0, 1}, {0, 1}, {0, 1}, {1, 1},
> + {2, 3}, {0, 1}, {0, 1}, {0, 1},
> + {0, 1}, {0, 1}, {0, 1}, {1, 1},
> + {0, 1}, {0, 1}, {0, 1}, {0, 1},
> +};
> +
> +static const int __initconst a370_xp_hclk_ratios[32][2] = {
> + {0, 1}, {1, 2}, {2, 6}, {2, 3},
> + {1, 3}, {1, 4}, {1, 2}, {2, 6},
> + {0, 1}, {1, 6}, {2, 10}, {0, 1},
> + {1, 4}, {0, 1}, {0, 1}, {2, 5},
> + {0, 1}, {0, 1}, {0, 1}, {1, 2},
> + {2, 6}, {0, 1}, {0, 1}, {0, 1},
> + {0, 1}, {0, 1}, {0, 1}, {1, 1},
> + {0, 1}, {0, 1}, {0, 1}, {0, 1},
> +};
> +
> +static const int __initconst a370_xp_dramclk_ratios[32][2] = {
> + {0, 1}, {1, 2}, {2, 3}, {2, 3},
> + {1, 3}, {1, 2}, {1, 2}, {2, 6},
> + {0, 1}, {1, 3}, {2, 5}, {0, 1},
> + {1, 4}, {0, 1}, {0, 1}, {2, 5},
> + {0, 1}, {0, 1}, {0, 1}, {1, 1},
> + {2, 3}, {0, 1}, {0, 1}, {0, 1},
> + {0, 1}, {0, 1}, {0, 1}, {1, 1},
> + {0, 1}, {0, 1}, {0, 1}, {0, 1},
> +};
> +
> +static void __init a370_xp_get_clk_ratio(u32 opt,
> + void __iomem *sar, int id, int *mult, int *div)
> +{
> + switch (id) {
> + case A370_XP_NBCLK:
> + *mult = a370_xp_nbclk_ratios[opt][0];
> + *div = a370_xp_nbclk_ratios[opt][1];
> + break;
> + case A370_XP_HCLK:
> + *mult = a370_xp_hclk_ratios[opt][0];
> + *div = a370_xp_hclk_ratios[opt][1];
> + break;
> + case A370_XP_DRAMCLK:
> + *mult = a370_xp_dramclk_ratios[opt][0];
> + *div = a370_xp_dramclk_ratios[opt][1];
> + break;
> + }
> +}
> +
> +static void __init a370_get_clk_ratio(
> + void __iomem *sar, int id, int *mult, int *div)
> +{
> + u32 opt = ((readl(sar) >> SARL_A370_FAB_FREQ_OPT) &
> + SARL_A370_FAB_FREQ_OPT_MASK);
> +
> + a370_xp_get_clk_ratio(opt, sar, id, mult, div);
> +}
> +
> +
> +static const struct core_clocks a370_core_clocks = {
> + .get_tclk_freq = a370_get_tclk_freq,
> + .get_cpu_freq = a370_get_cpu_freq,
> + .get_clk_ratio = a370_get_clk_ratio,
> + .ratios = a370_xp_core_ratios,
> + .num_ratios = ARRAY_SIZE(a370_xp_core_ratios),
> +};
> +
> +static const u32 __initconst xp_cpu_frequencies[] = {
And for Armada XP even the 'a' disappeared!
Gregory
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/7] clk: mvebu: add mvebu core clocks.
@ 2012-11-16 12:52 ` Gregory CLEMENT
0 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 12:52 UTC (permalink / raw)
To: linux-arm-kernel
Hi Andrew,
On 11/15/2012 10:28 PM, Andrew Lunn wrote:
> From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
>
> This driver allows to provide DT clocks for core clocks found on
> Marvell Kirkwood, Dove & 370/XP SoCs. The core clock frequencies and
> ratios are determined by decoding the Sample-At-Reset registers.
>
> Although technically correct, using a divider of 0 will lead to
> div_by_zero panic. Let's use a ratio of 0/1 instead to fail later
> with a zero clock.
>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> .../devicetree/bindings/clock/mvebu-core-clock.txt | 47 ++
> drivers/clk/Kconfig | 2 +
> drivers/clk/Makefile | 1 +
> drivers/clk/mvebu/Kconfig | 3 +
> drivers/clk/mvebu/Makefile | 1 +
> drivers/clk/mvebu/clk-core.c | 675 ++++++++++++++++++++
> drivers/clk/mvebu/clk-core.h | 18 +
> drivers/clk/mvebu/clk.c | 23 +
> include/linux/clk/mvebu.h | 22 +
> 9 files changed, 792 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
> create mode 100644 drivers/clk/mvebu/Kconfig
> create mode 100644 drivers/clk/mvebu/Makefile
> create mode 100644 drivers/clk/mvebu/clk-core.c
> create mode 100644 drivers/clk/mvebu/clk-core.h
> create mode 100644 drivers/clk/mvebu/clk.c
> create mode 100644 include/linux/clk/mvebu.h
>
> diff --git a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
> new file mode 100644
> index 0000000..84cfae7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
> @@ -0,0 +1,47 @@
> +* Core Clock bindings for Marvell MVEBU SoCs
> +
> +Marvell MVEBU SoCs usually allow to determine core clock frequencies by
> +reading the Sample-At-Reset (SAR) register. The core clock consumer should
> +specify the desired clock by having the clock ID in its "clocks" phandle cell.
> +
> +The following is a list of provided IDs and clock names on Kirkwood and Dove:
> + 0 = tclk (Internal Bus clock)
> + 1 = cpuclk (CPU0 clock)
> + 2 = l2clk (L2 Cache clock derived from CPU0 clock)
> + 3 = ddrclk (DDR controller clock derived from CPU0 clock)
> +
> +The following is a list of provided IDs and clock names on 370/XP:
You should call them Aramda 370 and Aramda XP. You do this modification
in the 2nd patch but it should be squashed in this patch.
> + 0 = tclk (Internal Bus clock)
> + 1 = cpuclk (CPU clock)
> + 2 = nbclk (L2 Cache clock)
> + 3 = hclk (DRAM control clock)
> + 4 = dramclk (DDR clock)
> +
> +Required properties:
> +- compatible : shall be one of the following:
> + "marvell,dove-core-clocks" - for Dove SoC core clocks
> + "marvell,kirkwood-core-clocks" - for Kirkwood SoC (except mv88f6180)
> + "marvell,mv88f6180-core-clocks" - for Kirkwood MV88f6180 SoC
> + "marvell,370-core-clocks" - For 370 SoC core clocks
> + "marvell,xp-core-clocks" - For XP SoC core clocks
Same here.
> +- reg : shall be the register address of the Sample-At-Reset (SAR) register
> +- #clock-cells : from common clock binding; shall be set to 1
> +
> +Optional properties:
> +- clock-output-names : from common clock binding; allows overwrite default clock
> + output names ("tclk", "cpuclk", "l2clk", "ddrclk")
> +
> +Example:
> +
> +core_clk: core-clocks at d0214 {
> + compatible = "marvell,dove-core-clocks";
> + reg = <0xd0214 0x4>;
> + #clock-cells = <1>;
> +};
> +
> +spi0: spi at 10600 {
> + compatible = "marvell,orion-spi";
> + /* ... */
> + /* get tclk from core clock provider */
> + clocks = <&core_clk 0>;
> +};
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index bace9e9..60427c0 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -54,3 +54,5 @@ config COMMON_CLK_MAX77686
> This driver supports Maxim 77686 crystal oscillator clock.
>
> endmenu
> +
> +source "drivers/clk/mvebu/Kconfig"
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 71a25b9..d0a14ae 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/
> obj-$(CONFIG_ARCH_U300) += clk-u300.o
> obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
> obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o
> +obj-$(CONFIG_PLAT_ORION) += mvebu/
> ifeq ($(CONFIG_COMMON_CLK), y)
> obj-$(CONFIG_ARCH_MMP) += mmp/
> endif
> diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
> new file mode 100644
> index 0000000..fd7bf97
> --- /dev/null
> +++ b/drivers/clk/mvebu/Kconfig
> @@ -0,0 +1,3 @@
> +config MVEBU_CLK_CORE
> + bool
> +
> diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
> new file mode 100644
> index 0000000..de1d961
> --- /dev/null
> +++ b/drivers/clk/mvebu/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_MVEBU_CLK_CORE) += clk.o clk-core.o
> diff --git a/drivers/clk/mvebu/clk-core.c b/drivers/clk/mvebu/clk-core.c
> new file mode 100644
> index 0000000..26ba835
> --- /dev/null
> +++ b/drivers/clk/mvebu/clk-core.c
> @@ -0,0 +1,675 @@
> +/*
> + * Marvell EBU clock core handling defined at reset
> + *
> + * Copyright (C) 2012 Marvell
> + *
> + * Gregory CLEMENT <gregory.clement@free-electrons.com>
> + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +#include <linux/kernel.h>
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of_address.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include "clk-core.h"
> +
> +struct core_ratio {
> + int id;
> + const char *name;
> +};
> +
> +struct core_clocks {
> + u32 (*get_tclk_freq)(void __iomem *sar);
> + u32 (*get_cpu_freq)(void __iomem *sar);
> + void (*get_clk_ratio)(void __iomem *sar, int id, int *mult, int *div);
> + const struct core_ratio *ratios;
> + int num_ratios;
> +};
> +
> +static struct clk_onecell_data clk_data;
> +
> +static void __init mvebu_clk_core_setup(struct device_node *np,
> + struct core_clocks *coreclk)
> +{
> + const char *tclk_name = "tclk";
> + const char *cpuclk_name = "cpuclk";
> + void __iomem *base;
> + unsigned long rate;
> + int n;
> +
> + base = of_iomap(np, 0);
> + if (WARN_ON(!base))
> + return;
> +
> + /*
> + * Allocate struct for TCLK, cpu clk, and core ratio clocks
> + */
> + clk_data.clk_num = 2 + coreclk->num_ratios;
> + clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *),
> + GFP_KERNEL);
> + if (WARN_ON(!clk_data.clks))
> + return;
> +
> + /*
> + * Register TCLK
> + */
> + of_property_read_string_index(np, "clock-output-names", 0,
> + &tclk_name);
> + rate = coreclk->get_tclk_freq(base);
> + clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL,
> + CLK_IS_ROOT, rate);
> + WARN_ON(IS_ERR(clk_data.clks[0]));
> +
> + /*
> + * Register CPU clock
> + */
> + of_property_read_string_index(np, "clock-output-names", 1,
> + &cpuclk_name);
> + rate = coreclk->get_cpu_freq(base);
> + clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL,
> + CLK_IS_ROOT, rate);
> + WARN_ON(IS_ERR(clk_data.clks[1]));
> +
> + /*
> + * Register fixed-factor clocks derived from CPU clock
> + */
> + for (n = 0; n < coreclk->num_ratios; n++) {
> + const char *rclk_name = coreclk->ratios[n].name;
> + int mult, div;
> +
> + of_property_read_string_index(np, "clock-output-names",
> + 2+n, &rclk_name);
> + coreclk->get_clk_ratio(base, coreclk->ratios[n].id,
> + &mult, &div);
> + clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name,
> + cpuclk_name, 0, mult, div);
> + WARN_ON(IS_ERR(clk_data.clks[2+n]));
> + };
> +
> + /*
> + * SAR register isn't needed anymore
> + */
> + iounmap(base);
> +
> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> +}
> +
> +#ifdef CONFIG_MACH_ARMADA_370_XP
> +/*
> + * 370/XP Sample At Reset is a 64 bit bitfiled split in two register
Add "Armada" in front of 370/XP please.
> + * of 32 bits
> + */
> +
> +#define SARL 0 /* Low part [0:31] */
> +#define SARL_AXP_PCLK_FREQ_OPT 21
> +#define SARL_AXP_PCLK_FREQ_OPT_MASK 0x7
> +#define SARL_A370_PCLK_FREQ_OPT 11
> +#define SARL_A370_PCLK_FREQ_OPT_MASK 0xF
> +#define SARL_AXP_FAB_FREQ_OPT 24
> +#define SARL_AXP_FAB_FREQ_OPT_MASK 0xF
> +#define SARL_A370_FAB_FREQ_OPT 15
> +#define SARL_A370_FAB_FREQ_OPT_MASK 0x1F
> +#define SARL_A370_TCLK_FREQ_OPT 20
> +#define SARL_A370_TCLK_FREQ_OPT_MASK 0x1
> +#define SARH 4 /* High part [32:63] */
> +#define SARH_AXP_PCLK_FREQ_OPT (52-32)
> +#define SARH_AXP_PCLK_FREQ_OPT_MASK 0x1
> +#define SARH_AXP_PCLK_FREQ_OPT_SHIFT 3
> +#define SARH_AXP_FAB_FREQ_OPT (51-32)
> +#define SARH_AXP_FAB_FREQ_OPT_MASK 0x1
> +#define SARH_AXP_FAB_FREQ_OPT_SHIFT 4
> +
> +static const u32 __initconst a370_tclk_frequencies[] = {
In all other part in the kernel the relatives functions to
Armada 370 or Armada XP are suffixed by armada_370 or armada_xp.
Could we do the same here for being consistent?
It will help when one wants to grep code relative to the armada
370 or the armada XP.
> + 16600000,
> + 20000000,
> +};
> +
> +static u32 __init a370_get_tclk_freq(void __iomem *sar)
Same here.
> +{
> + u8 tclk_freq_select = 0;
> +
> + tclk_freq_select = ((readl(sar) >> SARL_A370_TCLK_FREQ_OPT) &
> + SARL_A370_TCLK_FREQ_OPT_MASK);
> + return a370_tclk_frequencies[tclk_freq_select];
> +}
> +
> +static const u32 __initconst a370_cpu_frequencies[] = {
> + 400000000,
> + 533000000,
> + 667000000,
> + 800000000,
> + 1000000000,
> + 1067000000,
> + 1200000000,
> +};
> +
> +static u32 __init a370_get_cpu_freq(void __iomem *sar)
> +{
> + u32 cpu_freq;
> + u8 cpu_freq_select = 0;
> +
> + cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) &
> + SARL_A370_PCLK_FREQ_OPT_MASK);
> + if (cpu_freq_select > ARRAY_SIZE(a370_cpu_frequencies)) {
> + pr_err("CPU freq select unsuported %d\n", cpu_freq_select);
> + cpu_freq = 0;
> + } else
> + cpu_freq = a370_cpu_frequencies[cpu_freq_select];
> +
> + return cpu_freq;
> +}
> +
> +enum { A370_XP_NBCLK, A370_XP_HCLK, A370_XP_DRAMCLK };
> +
> +static const struct core_ratio __initconst a370_xp_core_ratios[] = {
> + { .id = A370_XP_NBCLK, .name = "nbclk" },
> + { .id = A370_XP_HCLK, .name = "hclk" },
> + { .id = A370_XP_DRAMCLK, .name = "dramclk" },
> +};
> +
> +static const int __initconst a370_xp_nbclk_ratios[32][2] = {
> + {0, 1}, {1, 2}, {2, 2}, {2, 2},
> + {1, 2}, {1, 2}, {1, 1}, {2, 3},
> + {0, 1}, {1, 2}, {2, 4}, {0, 1},
> + {1, 2}, {0, 1}, {0, 1}, {2, 2},
> + {0, 1}, {0, 1}, {0, 1}, {1, 1},
> + {2, 3}, {0, 1}, {0, 1}, {0, 1},
> + {0, 1}, {0, 1}, {0, 1}, {1, 1},
> + {0, 1}, {0, 1}, {0, 1}, {0, 1},
> +};
> +
> +static const int __initconst a370_xp_hclk_ratios[32][2] = {
> + {0, 1}, {1, 2}, {2, 6}, {2, 3},
> + {1, 3}, {1, 4}, {1, 2}, {2, 6},
> + {0, 1}, {1, 6}, {2, 10}, {0, 1},
> + {1, 4}, {0, 1}, {0, 1}, {2, 5},
> + {0, 1}, {0, 1}, {0, 1}, {1, 2},
> + {2, 6}, {0, 1}, {0, 1}, {0, 1},
> + {0, 1}, {0, 1}, {0, 1}, {1, 1},
> + {0, 1}, {0, 1}, {0, 1}, {0, 1},
> +};
> +
> +static const int __initconst a370_xp_dramclk_ratios[32][2] = {
> + {0, 1}, {1, 2}, {2, 3}, {2, 3},
> + {1, 3}, {1, 2}, {1, 2}, {2, 6},
> + {0, 1}, {1, 3}, {2, 5}, {0, 1},
> + {1, 4}, {0, 1}, {0, 1}, {2, 5},
> + {0, 1}, {0, 1}, {0, 1}, {1, 1},
> + {2, 3}, {0, 1}, {0, 1}, {0, 1},
> + {0, 1}, {0, 1}, {0, 1}, {1, 1},
> + {0, 1}, {0, 1}, {0, 1}, {0, 1},
> +};
> +
> +static void __init a370_xp_get_clk_ratio(u32 opt,
> + void __iomem *sar, int id, int *mult, int *div)
> +{
> + switch (id) {
> + case A370_XP_NBCLK:
> + *mult = a370_xp_nbclk_ratios[opt][0];
> + *div = a370_xp_nbclk_ratios[opt][1];
> + break;
> + case A370_XP_HCLK:
> + *mult = a370_xp_hclk_ratios[opt][0];
> + *div = a370_xp_hclk_ratios[opt][1];
> + break;
> + case A370_XP_DRAMCLK:
> + *mult = a370_xp_dramclk_ratios[opt][0];
> + *div = a370_xp_dramclk_ratios[opt][1];
> + break;
> + }
> +}
> +
> +static void __init a370_get_clk_ratio(
> + void __iomem *sar, int id, int *mult, int *div)
> +{
> + u32 opt = ((readl(sar) >> SARL_A370_FAB_FREQ_OPT) &
> + SARL_A370_FAB_FREQ_OPT_MASK);
> +
> + a370_xp_get_clk_ratio(opt, sar, id, mult, div);
> +}
> +
> +
> +static const struct core_clocks a370_core_clocks = {
> + .get_tclk_freq = a370_get_tclk_freq,
> + .get_cpu_freq = a370_get_cpu_freq,
> + .get_clk_ratio = a370_get_clk_ratio,
> + .ratios = a370_xp_core_ratios,
> + .num_ratios = ARRAY_SIZE(a370_xp_core_ratios),
> +};
> +
> +static const u32 __initconst xp_cpu_frequencies[] = {
And for Armada XP even the 'a' disappeared!
Gregory
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 7/7] ARM: Kirkwood: switch to DT clock providers
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-16 17:33 ` Gregory CLEMENT
-1 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 17:33 UTC (permalink / raw)
To: Andrew Lunn
Cc: Thomas Petazzoni, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
mturquette-QSEj5FYQhm4dnm+yROfE0A, Jason Cooper, linux ARM
On 11/15/2012 10:28 PM, Andrew Lunn wrote:
> With true DT clock providers available switch Kirkwood clock setup in
> DT- enabled boards. While AUXDATA can be removed completely from bus
> probing, some devices still don't know about DT. Therefore, some clkdev
> aliases are created until these devices also move to DT.
>
> Signed-off-by: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>
> ---
> arch/arm/boot/dts/kirkwood.dtsi | 22 +++++++++
> arch/arm/mach-kirkwood/Kconfig | 2 +
> arch/arm/mach-kirkwood/board-dt.c | 72 +++++++++++++++++++++++------
> arch/arm/plat-orion/include/plat/common.h | 1 +
> 4 files changed, 84 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
> index 4e5b815..5c85a57 100644
> --- a/arch/arm/boot/dts/kirkwood.dtsi
> +++ b/arch/arm/boot/dts/kirkwood.dtsi
> @@ -19,6 +19,12 @@
> #address-cells = <1>;
> #size-cells = <1>;
>
> + core_clk: core-clocks@10030 {
> + compatible = "marvell,kirkwood-core-clocks";
> + reg = <0x10030 0x4>;
> + #clock-cells = <1>;
> + };
> +
> gpio0: gpio@10100 {
> compatible = "marvell,orion-gpio";
> #gpio-cells = <2>;
> @@ -42,6 +48,7 @@
> reg = <0x12000 0x100>;
> reg-shift = <2>;
> interrupts = <33>;
> + clocks = <&clk_gate 7>;
> /* set clock-frequency in board dts */
> status = "disabled";
> };
> @@ -51,6 +58,7 @@
> reg = <0x12100 0x100>;
> reg-shift = <2>;
> interrupts = <34>;
> + clocks = <&clk_gate 7>;
> /* set clock-frequency in board dts */
> status = "disabled";
> };
> @@ -68,12 +76,21 @@
> cell-index = <0>;
> interrupts = <23>;
> reg = <0x10600 0x28>;
> + clocks = <&clk_gate 7>;
> status = "disabled";
> };
>
> + clk_gate: clock-gating-control@2011c {
> + compatible = "marvell,kirkwood-clock-gating";
> + reg = <0x2011c 0x4>;
> + clocks = <&core_clk 0>;
> + #clock-cells = <1>;
> + };
> +
> wdt@20300 {
> compatible = "marvell,orion-wdt";
> reg = <0x20300 0x28>;
> + clocks = <&clk_gate 7>;
> status = "okay";
> };
>
> @@ -81,6 +98,8 @@
> compatible = "marvell,orion-sata";
> reg = <0x80000 0x5000>;
> interrupts = <21>;
> + clocks = <&clk_gate 14>, <&clk_gate 15>;
> + clock-names = "0", "1";
> status = "disabled";
> };
>
> @@ -94,6 +113,7 @@
> reg = <0x3000000 0x400>;
> chip-delay = <25>;
> /* set partition map and/or chip-delay in board dts */
> + clocks = <&clk_gate 7>;
> status = "disabled";
> };
>
> @@ -104,6 +124,7 @@
> #size-cells = <0>;
> interrupts = <29>;
> clock-frequency = <100000>;
> + clocks = <&clk_gate 7>;
> status = "disabled";
> };
>
> @@ -113,6 +134,7 @@
> <0xf5000000 0x800>;
> reg-names = "regs", "sram";
> interrupts = <22>;
> + clocks = <&clk_gate 17>;
> status = "okay";
> };
> };
> diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
> index 50bca50..2833492 100644
> --- a/arch/arm/mach-kirkwood/Kconfig
> +++ b/arch/arm/mach-kirkwood/Kconfig
> @@ -46,6 +46,8 @@ config MACH_GURUPLUG
>
> config ARCH_KIRKWOOD_DT
> bool "Marvell Kirkwood Flattened Device Tree"
> + select MVEBU_CLK_CORE
> + select MVEBU_CLK_GATING
> select USE_OF
> help
> Say 'Y' here if you want your kernel to support the
> diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
> index d94872f..0129cdc 100644
> --- a/arch/arm/mach-kirkwood/board-dt.c
> +++ b/arch/arm/mach-kirkwood/board-dt.c
> @@ -14,11 +14,15 @@
> #include <linux/init.h>
> #include <linux/of.h>
> #include <linux/of_platform.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clk/mvebu.h>
> #include <linux/kexec.h>
> #include <asm/mach/arch.h>
> #include <asm/mach/map.h>
> #include <mach/bridge-regs.h>
> +#include <linux/platform_data/usb-ehci-orion.h>
> #include <plat/irq.h>
> +#include <plat/common.h>
> #include "common.h"
>
> static struct of_device_id kirkwood_dt_match_table[] __initdata = {
> @@ -26,16 +30,59 @@ static struct of_device_id kirkwood_dt_match_table[] __initdata = {
> { }
> };
>
> -struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
> - OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
> - OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
> - NULL),
> - OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
> - OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL),
> - OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL),
> - OF_DEV_AUXDATA("marvell,orion-crypto", 0xf1030000, "mv_crypto", NULL),
> - {},
> -};
> +/*
> + * There are still devices that doesn't know about DT yet. Get clock
> + * gates here and add a clock lookup alias, so that old platform
> + * devices still work.
> +*/
> +
> +static void __init kirkwood_legacy_clk_init(void)
> +{
> +
> + struct device_node *np = of_find_compatible_node(NULL, NULL,
> + "marvell,kirkwood-clock-gating");
> +
> + struct of_phandle_args clkspec;
> +
> + clkspec.np = np;
> + clkspec.args_count = 1;
> +
> + clkspec.args[0] = CGC_BIT_GE0;
> + orion_clkdev_add(NULL, "mv643xx_eth_port.0",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_PEX0;
> + orion_clkdev_add("0", "pcie",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_USB0;
> + orion_clkdev_add(NULL, "orion-ehci.0",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_XOR0;
> + orion_clkdev_add(NULL, "mv_xor_shared.0",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_XOR1;
> + orion_clkdev_add(NULL, "mv_xor_shared.1",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_PEX1;
> + orion_clkdev_add("1", "pcie",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_GE1;
> + orion_clkdev_add(NULL, "mv643xx_eth_port.1",
> + of_clk_get_from_provider(&clkspec));
> +
> +}
> +
> +static void __init kirkwood_of_clk_init(void)
> +{
> + mvebu_clocks_init();
> + mvebu_clk_gating_init();
What do you think about moving mvebu_clk_gating_init()
inside mvebu_clocks_init ?
It is what we have done for the cpu_clk.
> + kirkwood_legacy_clk_init();
> +}
>
> static void __init kirkwood_dt_init(void)
> {
> @@ -54,7 +101,7 @@ static void __init kirkwood_dt_init(void)
> kirkwood_l2_init();
>
> /* Setup root of clk tree */
> - kirkwood_clk_init();
> + kirkwood_of_clk_init();
>
> /* internal devices that every board has */
> kirkwood_xor0_init();
> @@ -94,8 +141,7 @@ static void __init kirkwood_dt_init(void)
> if (of_machine_is_compatible("keymile,km_kirkwood"))
> km_kirkwood_init();
>
> - of_platform_populate(NULL, kirkwood_dt_match_table,
> - kirkwood_auxdata_lookup, NULL);
> + of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL);
> }
>
> static const char *kirkwood_dt_board_compat[] = {
> diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
> index 6bbc3fe..e06fc5f 100644
> --- a/arch/arm/plat-orion/include/plat/common.h
> +++ b/arch/arm/plat-orion/include/plat/common.h
> @@ -12,6 +12,7 @@
> #include <linux/mv643xx_eth.h>
>
> struct dsa_platform_data;
> +struct mv_sata_platform_data;
>
> void __init orion_uart0_init(void __iomem *membase,
> resource_size_t mapbase,
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 7/7] ARM: Kirkwood: switch to DT clock providers
@ 2012-11-16 17:33 ` Gregory CLEMENT
0 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 17:33 UTC (permalink / raw)
To: linux-arm-kernel
On 11/15/2012 10:28 PM, Andrew Lunn wrote:
> With true DT clock providers available switch Kirkwood clock setup in
> DT- enabled boards. While AUXDATA can be removed completely from bus
> probing, some devices still don't know about DT. Therefore, some clkdev
> aliases are created until these devices also move to DT.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> arch/arm/boot/dts/kirkwood.dtsi | 22 +++++++++
> arch/arm/mach-kirkwood/Kconfig | 2 +
> arch/arm/mach-kirkwood/board-dt.c | 72 +++++++++++++++++++++++------
> arch/arm/plat-orion/include/plat/common.h | 1 +
> 4 files changed, 84 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
> index 4e5b815..5c85a57 100644
> --- a/arch/arm/boot/dts/kirkwood.dtsi
> +++ b/arch/arm/boot/dts/kirkwood.dtsi
> @@ -19,6 +19,12 @@
> #address-cells = <1>;
> #size-cells = <1>;
>
> + core_clk: core-clocks at 10030 {
> + compatible = "marvell,kirkwood-core-clocks";
> + reg = <0x10030 0x4>;
> + #clock-cells = <1>;
> + };
> +
> gpio0: gpio at 10100 {
> compatible = "marvell,orion-gpio";
> #gpio-cells = <2>;
> @@ -42,6 +48,7 @@
> reg = <0x12000 0x100>;
> reg-shift = <2>;
> interrupts = <33>;
> + clocks = <&clk_gate 7>;
> /* set clock-frequency in board dts */
> status = "disabled";
> };
> @@ -51,6 +58,7 @@
> reg = <0x12100 0x100>;
> reg-shift = <2>;
> interrupts = <34>;
> + clocks = <&clk_gate 7>;
> /* set clock-frequency in board dts */
> status = "disabled";
> };
> @@ -68,12 +76,21 @@
> cell-index = <0>;
> interrupts = <23>;
> reg = <0x10600 0x28>;
> + clocks = <&clk_gate 7>;
> status = "disabled";
> };
>
> + clk_gate: clock-gating-control at 2011c {
> + compatible = "marvell,kirkwood-clock-gating";
> + reg = <0x2011c 0x4>;
> + clocks = <&core_clk 0>;
> + #clock-cells = <1>;
> + };
> +
> wdt at 20300 {
> compatible = "marvell,orion-wdt";
> reg = <0x20300 0x28>;
> + clocks = <&clk_gate 7>;
> status = "okay";
> };
>
> @@ -81,6 +98,8 @@
> compatible = "marvell,orion-sata";
> reg = <0x80000 0x5000>;
> interrupts = <21>;
> + clocks = <&clk_gate 14>, <&clk_gate 15>;
> + clock-names = "0", "1";
> status = "disabled";
> };
>
> @@ -94,6 +113,7 @@
> reg = <0x3000000 0x400>;
> chip-delay = <25>;
> /* set partition map and/or chip-delay in board dts */
> + clocks = <&clk_gate 7>;
> status = "disabled";
> };
>
> @@ -104,6 +124,7 @@
> #size-cells = <0>;
> interrupts = <29>;
> clock-frequency = <100000>;
> + clocks = <&clk_gate 7>;
> status = "disabled";
> };
>
> @@ -113,6 +134,7 @@
> <0xf5000000 0x800>;
> reg-names = "regs", "sram";
> interrupts = <22>;
> + clocks = <&clk_gate 17>;
> status = "okay";
> };
> };
> diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
> index 50bca50..2833492 100644
> --- a/arch/arm/mach-kirkwood/Kconfig
> +++ b/arch/arm/mach-kirkwood/Kconfig
> @@ -46,6 +46,8 @@ config MACH_GURUPLUG
>
> config ARCH_KIRKWOOD_DT
> bool "Marvell Kirkwood Flattened Device Tree"
> + select MVEBU_CLK_CORE
> + select MVEBU_CLK_GATING
> select USE_OF
> help
> Say 'Y' here if you want your kernel to support the
> diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
> index d94872f..0129cdc 100644
> --- a/arch/arm/mach-kirkwood/board-dt.c
> +++ b/arch/arm/mach-kirkwood/board-dt.c
> @@ -14,11 +14,15 @@
> #include <linux/init.h>
> #include <linux/of.h>
> #include <linux/of_platform.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clk/mvebu.h>
> #include <linux/kexec.h>
> #include <asm/mach/arch.h>
> #include <asm/mach/map.h>
> #include <mach/bridge-regs.h>
> +#include <linux/platform_data/usb-ehci-orion.h>
> #include <plat/irq.h>
> +#include <plat/common.h>
> #include "common.h"
>
> static struct of_device_id kirkwood_dt_match_table[] __initdata = {
> @@ -26,16 +30,59 @@ static struct of_device_id kirkwood_dt_match_table[] __initdata = {
> { }
> };
>
> -struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
> - OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
> - OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
> - NULL),
> - OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
> - OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL),
> - OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL),
> - OF_DEV_AUXDATA("marvell,orion-crypto", 0xf1030000, "mv_crypto", NULL),
> - {},
> -};
> +/*
> + * There are still devices that doesn't know about DT yet. Get clock
> + * gates here and add a clock lookup alias, so that old platform
> + * devices still work.
> +*/
> +
> +static void __init kirkwood_legacy_clk_init(void)
> +{
> +
> + struct device_node *np = of_find_compatible_node(NULL, NULL,
> + "marvell,kirkwood-clock-gating");
> +
> + struct of_phandle_args clkspec;
> +
> + clkspec.np = np;
> + clkspec.args_count = 1;
> +
> + clkspec.args[0] = CGC_BIT_GE0;
> + orion_clkdev_add(NULL, "mv643xx_eth_port.0",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_PEX0;
> + orion_clkdev_add("0", "pcie",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_USB0;
> + orion_clkdev_add(NULL, "orion-ehci.0",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_XOR0;
> + orion_clkdev_add(NULL, "mv_xor_shared.0",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_XOR1;
> + orion_clkdev_add(NULL, "mv_xor_shared.1",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_PEX1;
> + orion_clkdev_add("1", "pcie",
> + of_clk_get_from_provider(&clkspec));
> +
> + clkspec.args[0] = CGC_BIT_GE1;
> + orion_clkdev_add(NULL, "mv643xx_eth_port.1",
> + of_clk_get_from_provider(&clkspec));
> +
> +}
> +
> +static void __init kirkwood_of_clk_init(void)
> +{
> + mvebu_clocks_init();
> + mvebu_clk_gating_init();
What do you think about moving mvebu_clk_gating_init()
inside mvebu_clocks_init ?
It is what we have done for the cpu_clk.
> + kirkwood_legacy_clk_init();
> +}
>
> static void __init kirkwood_dt_init(void)
> {
> @@ -54,7 +101,7 @@ static void __init kirkwood_dt_init(void)
> kirkwood_l2_init();
>
> /* Setup root of clk tree */
> - kirkwood_clk_init();
> + kirkwood_of_clk_init();
>
> /* internal devices that every board has */
> kirkwood_xor0_init();
> @@ -94,8 +141,7 @@ static void __init kirkwood_dt_init(void)
> if (of_machine_is_compatible("keymile,km_kirkwood"))
> km_kirkwood_init();
>
> - of_platform_populate(NULL, kirkwood_dt_match_table,
> - kirkwood_auxdata_lookup, NULL);
> + of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL);
> }
>
> static const char *kirkwood_dt_board_compat[] = {
> diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
> index 6bbc3fe..e06fc5f 100644
> --- a/arch/arm/plat-orion/include/plat/common.h
> +++ b/arch/arm/plat-orion/include/plat/common.h
> @@ -12,6 +12,7 @@
> #include <linux/mv643xx_eth.h>
>
> struct dsa_platform_data;
> +struct mv_sata_platform_data;
>
> void __init orion_uart0_init(void __iomem *membase,
> resource_size_t mapbase,
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 0/2] Add clock gating support for Armada 370/XP
2012-11-15 21:28 ` Andrew Lunn
@ 2012-11-16 18:01 ` Gregory CLEMENT
-1 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 18:01 UTC (permalink / raw)
To: Andrew Lunn
Cc: linux-arm-kernel, Sebastian Hesselbarth, linux-kernel, Gregory CLEMENT
Hi Andrew,
With this 2 patches I added clock gating support for Armada 370 and
Armada XP. I compiled and tested on the boards, and managed to see the
new clock using debugfs.
Feel free to squash them in your series if you want.
Regards,
Gregory CLEMENT (2):
clk: mvebu: armada 370/XP add clock gating control provider for DT
arm: mvebu: armada 370/XP adding clock gating support: dt binding
.../bindings/clock/mvebu-gated-clock.txt | 43 ++++++++++++++
arch/arm/boot/dts/armada-370.dtsi | 8 +++
arch/arm/boot/dts/armada-xp.dtsi | 7 +++
arch/arm/mach-mvebu/Kconfig | 1 +
drivers/clk/mvebu/clk-gating-ctrl.c | 61 ++++++++++++++++++++
5 files changed, 120 insertions(+)
--
1.7.9.5
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 0/2] Add clock gating support for Armada 370/XP
@ 2012-11-16 18:01 ` Gregory CLEMENT
0 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 18:01 UTC (permalink / raw)
To: linux-arm-kernel
Hi Andrew,
With this 2 patches I added clock gating support for Armada 370 and
Armada XP. I compiled and tested on the boards, and managed to see the
new clock using debugfs.
Feel free to squash them in your series if you want.
Regards,
Gregory CLEMENT (2):
clk: mvebu: armada 370/XP add clock gating control provider for DT
arm: mvebu: armada 370/XP adding clock gating support: dt binding
.../bindings/clock/mvebu-gated-clock.txt | 43 ++++++++++++++
arch/arm/boot/dts/armada-370.dtsi | 8 +++
arch/arm/boot/dts/armada-xp.dtsi | 7 +++
arch/arm/mach-mvebu/Kconfig | 1 +
drivers/clk/mvebu/clk-gating-ctrl.c | 61 ++++++++++++++++++++
5 files changed, 120 insertions(+)
--
1.7.9.5
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
2012-11-16 18:01 ` Gregory CLEMENT
@ 2012-11-16 18:01 ` Gregory CLEMENT
-1 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 18:01 UTC (permalink / raw)
To: Andrew Lunn
Cc: linux-arm-kernel, Sebastian Hesselbarth, linux-kernel, Gregory CLEMENT
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
.../bindings/clock/mvebu-gated-clock.txt | 43 ++++++++++++++
arch/arm/mach-mvebu/Kconfig | 1 +
drivers/clk/mvebu/clk-gating-ctrl.c | 61 ++++++++++++++++++++
3 files changed, 105 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
index 7497cc0..9dbcdd9 100644
--- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
+++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
@@ -6,6 +6,49 @@ the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to
the corresponding clock gating control bit in HW to ease manual clock lookup
in datasheet.
+The following is a list of provided IDs for Armada XP:
+ID Clock Peripheral
+-----------------------------------
+0 Audio AC97 Cntrl
+1 pex0_en PCIe 0 Clock out
+2 pex1_en PCIe 1 Clock out
+3 ge1 Gigabit Ethernet 1
+4 ge0 Gigabit Ethernet 0
+5 pex0 PCIe Cntrl 0
+9 pex1 PCIe Cntrl 1
+15 sata0 SATA Host 0
+17 sdio SDHCI Host
+25 tdm Time Division Mplx
+28 ddr DDR Cntrl
+30 sata1 SATA Host 0
+
+The following is a list of provided IDs for Armada XP:
+ID Clock Peripheral
+-----------------------------------
+0 audio Audio Cntrl
+1 ge3 Gigabit Ethernet 3
+2 ge2 Gigabit Ethernet 2
+3 ge1 Gigabit Ethernet 1
+4 ge0 Gigabit Ethernet 0
+5 pex0 PCIe Cntrl 0
+6 pex1 PCIe Cntrl 1
+7 pex2 PCIe Cntrl 2
+8 pex3 PCIe Cntrl 3
+13 bp
+14 sata0lnk
+15 sata0 SATA Host 0
+16 lcd LCD Cntrl
+17 sdio SDHCI Host
+18 usb0 USB Host 0
+19 usb1 USB Host 1
+20 usb2 USB Host 2
+22 xor0 XOR DMA 0
+23 crypto CESA engine
+25 tdm Time Division Mplx
+28 xor1 XOR DMA 1
+29 sata1lnk
+30 sata1 SATA Host 0
+
The following is a list of provided IDs for Dove:
ID Clock Peripheral
-----------------------------------
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index ad38b64..dc009d5 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -12,6 +12,7 @@ config ARCH_MVEBU
select CLKDEV_LOOKUP
select MVEBU_CLK_CORE
select MVEBU_CLK_CPU
+ select MVEBU_CLK_GATING
if ARCH_MVEBU
diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c
index 3ac7607..7f04e8b 100644
--- a/drivers/clk/mvebu/clk-gating-ctrl.c
+++ b/drivers/clk/mvebu/clk-gating-ctrl.c
@@ -101,6 +101,53 @@ static void __init mvebu_clk_gating_setup(
* SoC specific clock gating control
*/
+#ifdef CONFIG_MACH_ARMADA_370
+static const struct mvebu_soc_descr __initconst armada_370_gating_descr[] = {
+ { "audio", NULL, 0 },
+ { "pex0_en", NULL, 1 },
+ { "pex1_en", NULL, 2 },
+ { "ge1", NULL, 3 },
+ { "ge0", NULL, 4 },
+ { "pex0", NULL, 5 },
+ { "pex1", NULL, 9 },
+ { "sata0", NULL, 15 },
+ { "sdio", NULL, 17 },
+ { "tdm", NULL, 25 },
+ { "ddr", NULL, 28 },
+ { "sata1", NULL, 30 },
+ { }
+};
+#endif
+
+#ifdef CONFIG_MACH_ARMADA_XP
+static const struct mvebu_soc_descr __initconst armada_xp_gating_descr[] = {
+ { "audio", NULL, 0 },
+ { "ge3", NULL, 1 },
+ { "ge2", NULL, 2 },
+ { "ge1", NULL, 3 },
+ { "ge0", NULL, 4 },
+ { "pex0", NULL, 5 },
+ { "pex1", NULL, 6 },
+ { "pex2", NULL, 7 },
+ { "pex3", NULL, 8 },
+ { "bp", NULL, 13 },
+ { "sata0lnk", NULL, 14 },
+ { "sata0", NULL, 15 },
+ { "lcd", NULL, 16 },
+ { "sdio", NULL, 17 },
+ { "usb0", NULL, 18 },
+ { "usb1", NULL, 19 },
+ { "usb2", NULL, 20 },
+ { "xor0", NULL, 22 },
+ { "crypto", NULL, 23 },
+ { "tdm", NULL, 25 },
+ { "xor1", NULL, 28 },
+ { "sata1lnk", NULL, 29 },
+ { "sata1", NULL, 30 },
+ { }
+};
+#endif
+
#ifdef CONFIG_ARCH_DOVE
static const struct mvebu_soc_descr __initconst dove_gating_descr[] = {
{ "usb0", NULL, 0 },
@@ -147,6 +194,20 @@ static const struct mvebu_soc_descr __initconst kirkwood_gating_descr[] = {
#endif
static const __initdata struct of_device_id clk_gating_match[] = {
+#ifdef CONFIG_MACH_ARMADA_370
+ {
+ .compatible = "marvell,armada-370-clock-gating",
+ .data = armada_370_gating_descr,
+ },
+#endif
+
+#ifdef CONFIG_MACH_ARMADA_XP
+ {
+ .compatible = "marvell,armada-xp-clock-gating",
+ .data = armada_xp_gating_descr,
+ },
+#endif
+
#ifdef CONFIG_ARCH_DOVE
{
.compatible = "marvell,dove-clock-gating",
--
1.7.9.5
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
@ 2012-11-16 18:01 ` Gregory CLEMENT
0 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 18:01 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
.../bindings/clock/mvebu-gated-clock.txt | 43 ++++++++++++++
arch/arm/mach-mvebu/Kconfig | 1 +
drivers/clk/mvebu/clk-gating-ctrl.c | 61 ++++++++++++++++++++
3 files changed, 105 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
index 7497cc0..9dbcdd9 100644
--- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
+++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
@@ -6,6 +6,49 @@ the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to
the corresponding clock gating control bit in HW to ease manual clock lookup
in datasheet.
+The following is a list of provided IDs for Armada XP:
+ID Clock Peripheral
+-----------------------------------
+0 Audio AC97 Cntrl
+1 pex0_en PCIe 0 Clock out
+2 pex1_en PCIe 1 Clock out
+3 ge1 Gigabit Ethernet 1
+4 ge0 Gigabit Ethernet 0
+5 pex0 PCIe Cntrl 0
+9 pex1 PCIe Cntrl 1
+15 sata0 SATA Host 0
+17 sdio SDHCI Host
+25 tdm Time Division Mplx
+28 ddr DDR Cntrl
+30 sata1 SATA Host 0
+
+The following is a list of provided IDs for Armada XP:
+ID Clock Peripheral
+-----------------------------------
+0 audio Audio Cntrl
+1 ge3 Gigabit Ethernet 3
+2 ge2 Gigabit Ethernet 2
+3 ge1 Gigabit Ethernet 1
+4 ge0 Gigabit Ethernet 0
+5 pex0 PCIe Cntrl 0
+6 pex1 PCIe Cntrl 1
+7 pex2 PCIe Cntrl 2
+8 pex3 PCIe Cntrl 3
+13 bp
+14 sata0lnk
+15 sata0 SATA Host 0
+16 lcd LCD Cntrl
+17 sdio SDHCI Host
+18 usb0 USB Host 0
+19 usb1 USB Host 1
+20 usb2 USB Host 2
+22 xor0 XOR DMA 0
+23 crypto CESA engine
+25 tdm Time Division Mplx
+28 xor1 XOR DMA 1
+29 sata1lnk
+30 sata1 SATA Host 0
+
The following is a list of provided IDs for Dove:
ID Clock Peripheral
-----------------------------------
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index ad38b64..dc009d5 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -12,6 +12,7 @@ config ARCH_MVEBU
select CLKDEV_LOOKUP
select MVEBU_CLK_CORE
select MVEBU_CLK_CPU
+ select MVEBU_CLK_GATING
if ARCH_MVEBU
diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c
index 3ac7607..7f04e8b 100644
--- a/drivers/clk/mvebu/clk-gating-ctrl.c
+++ b/drivers/clk/mvebu/clk-gating-ctrl.c
@@ -101,6 +101,53 @@ static void __init mvebu_clk_gating_setup(
* SoC specific clock gating control
*/
+#ifdef CONFIG_MACH_ARMADA_370
+static const struct mvebu_soc_descr __initconst armada_370_gating_descr[] = {
+ { "audio", NULL, 0 },
+ { "pex0_en", NULL, 1 },
+ { "pex1_en", NULL, 2 },
+ { "ge1", NULL, 3 },
+ { "ge0", NULL, 4 },
+ { "pex0", NULL, 5 },
+ { "pex1", NULL, 9 },
+ { "sata0", NULL, 15 },
+ { "sdio", NULL, 17 },
+ { "tdm", NULL, 25 },
+ { "ddr", NULL, 28 },
+ { "sata1", NULL, 30 },
+ { }
+};
+#endif
+
+#ifdef CONFIG_MACH_ARMADA_XP
+static const struct mvebu_soc_descr __initconst armada_xp_gating_descr[] = {
+ { "audio", NULL, 0 },
+ { "ge3", NULL, 1 },
+ { "ge2", NULL, 2 },
+ { "ge1", NULL, 3 },
+ { "ge0", NULL, 4 },
+ { "pex0", NULL, 5 },
+ { "pex1", NULL, 6 },
+ { "pex2", NULL, 7 },
+ { "pex3", NULL, 8 },
+ { "bp", NULL, 13 },
+ { "sata0lnk", NULL, 14 },
+ { "sata0", NULL, 15 },
+ { "lcd", NULL, 16 },
+ { "sdio", NULL, 17 },
+ { "usb0", NULL, 18 },
+ { "usb1", NULL, 19 },
+ { "usb2", NULL, 20 },
+ { "xor0", NULL, 22 },
+ { "crypto", NULL, 23 },
+ { "tdm", NULL, 25 },
+ { "xor1", NULL, 28 },
+ { "sata1lnk", NULL, 29 },
+ { "sata1", NULL, 30 },
+ { }
+};
+#endif
+
#ifdef CONFIG_ARCH_DOVE
static const struct mvebu_soc_descr __initconst dove_gating_descr[] = {
{ "usb0", NULL, 0 },
@@ -147,6 +194,20 @@ static const struct mvebu_soc_descr __initconst kirkwood_gating_descr[] = {
#endif
static const __initdata struct of_device_id clk_gating_match[] = {
+#ifdef CONFIG_MACH_ARMADA_370
+ {
+ .compatible = "marvell,armada-370-clock-gating",
+ .data = armada_370_gating_descr,
+ },
+#endif
+
+#ifdef CONFIG_MACH_ARMADA_XP
+ {
+ .compatible = "marvell,armada-xp-clock-gating",
+ .data = armada_xp_gating_descr,
+ },
+#endif
+
#ifdef CONFIG_ARCH_DOVE
{
.compatible = "marvell,dove-clock-gating",
--
1.7.9.5
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 2/2] arm: mvebu: armada 370/XP adding clock gating support: dt binding
2012-11-16 18:01 ` Gregory CLEMENT
@ 2012-11-16 18:02 ` Gregory CLEMENT
-1 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 18:02 UTC (permalink / raw)
To: Andrew Lunn
Cc: linux-arm-kernel, Sebastian Hesselbarth, linux-kernel, Gregory CLEMENT
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-370.dtsi | 8 ++++++++
arch/arm/boot/dts/armada-xp.dtsi | 7 +++++++
2 files changed, 15 insertions(+)
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index dae966c..25524eb 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -82,5 +82,13 @@
#clock-cells = <1>;
};
+ clk_gate: clock-gating-control@d0018220 {
+ compatible = "marvell,armada-370-clock-gating";
+ reg = <0xd0018220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
+
+
};
};
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index b3c9fbc..82ea5e4 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -99,6 +99,13 @@
clocks = <&coreclk 1>;
};
+ clk_gate: clock-gating-control@d001821c {
+ compatible = "marvell,armada-xp-clock-gating";
+ reg = <0xd001821c 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
+
system-controller@d0018200 {
compatible = "marvell,armada-370-xp-system-controller";
reg = <0xd0018200 0x500>;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH 2/2] arm: mvebu: armada 370/XP adding clock gating support: dt binding
@ 2012-11-16 18:02 ` Gregory CLEMENT
0 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-16 18:02 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-370.dtsi | 8 ++++++++
arch/arm/boot/dts/armada-xp.dtsi | 7 +++++++
2 files changed, 15 insertions(+)
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index dae966c..25524eb 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -82,5 +82,13 @@
#clock-cells = <1>;
};
+ clk_gate: clock-gating-control at d0018220 {
+ compatible = "marvell,armada-370-clock-gating";
+ reg = <0xd0018220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
+
+
};
};
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index b3c9fbc..82ea5e4 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -99,6 +99,13 @@
clocks = <&coreclk 1>;
};
+ clk_gate: clock-gating-control at d001821c {
+ compatible = "marvell,armada-xp-clock-gating";
+ reg = <0xd001821c 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
+
system-controller at d0018200 {
compatible = "marvell,armada-370-xp-system-controller";
reg = <0xd0018200 0x500>;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
2012-11-16 18:01 ` Gregory CLEMENT
@ 2012-11-17 8:26 ` Andrew Lunn
-1 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-17 8:26 UTC (permalink / raw)
To: Gregory CLEMENT
Cc: Andrew Lunn, linux-arm-kernel, Sebastian Hesselbarth, linux-kernel
Hi Gregory
Nice work
On Fri, Nov 16, 2012 at 07:01:59PM +0100, Gregory CLEMENT wrote:
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> .../bindings/clock/mvebu-gated-clock.txt | 43 ++++++++++++++
> arch/arm/mach-mvebu/Kconfig | 1 +
> drivers/clk/mvebu/clk-gating-ctrl.c | 61 ++++++++++++++++++++
> 3 files changed, 105 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
> index 7497cc0..9dbcdd9 100644
> --- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
> +++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
> @@ -6,6 +6,49 @@ the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to
> the corresponding clock gating control bit in HW to ease manual clock lookup
> in datasheet.
>
> +The following is a list of provided IDs for Armada XP:
Should that the 370, not XP?
> +ID Clock Peripheral
> +-----------------------------------
> +0 Audio AC97 Cntrl
> +1 pex0_en PCIe 0 Clock out
> +2 pex1_en PCIe 1 Clock out
> +3 ge1 Gigabit Ethernet 1
> +4 ge0 Gigabit Ethernet 0
> +5 pex0 PCIe Cntrl 0
> +9 pex1 PCIe Cntrl 1
> +15 sata0 SATA Host 0
> +17 sdio SDHCI Host
> +25 tdm Time Division Mplx
> +28 ddr DDR Cntrl
> +30 sata1 SATA Host 0
Not many clocks there. USB? XOR? Crypto?
What is the ddr clock for? Does bad things happen if you turn it off?
Kirkwood has a similar clock, dunit, which i decided not to export,
since when you turn it off, the whole SoC locks up.
Thanks
Andrew
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
@ 2012-11-17 8:26 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-17 8:26 UTC (permalink / raw)
To: linux-arm-kernel
Hi Gregory
Nice work
On Fri, Nov 16, 2012 at 07:01:59PM +0100, Gregory CLEMENT wrote:
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> .../bindings/clock/mvebu-gated-clock.txt | 43 ++++++++++++++
> arch/arm/mach-mvebu/Kconfig | 1 +
> drivers/clk/mvebu/clk-gating-ctrl.c | 61 ++++++++++++++++++++
> 3 files changed, 105 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
> index 7497cc0..9dbcdd9 100644
> --- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
> +++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
> @@ -6,6 +6,49 @@ the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to
> the corresponding clock gating control bit in HW to ease manual clock lookup
> in datasheet.
>
> +The following is a list of provided IDs for Armada XP:
Should that the 370, not XP?
> +ID Clock Peripheral
> +-----------------------------------
> +0 Audio AC97 Cntrl
> +1 pex0_en PCIe 0 Clock out
> +2 pex1_en PCIe 1 Clock out
> +3 ge1 Gigabit Ethernet 1
> +4 ge0 Gigabit Ethernet 0
> +5 pex0 PCIe Cntrl 0
> +9 pex1 PCIe Cntrl 1
> +15 sata0 SATA Host 0
> +17 sdio SDHCI Host
> +25 tdm Time Division Mplx
> +28 ddr DDR Cntrl
> +30 sata1 SATA Host 0
Not many clocks there. USB? XOR? Crypto?
What is the ddr clock for? Does bad things happen if you turn it off?
Kirkwood has a similar clock, dunit, which i decided not to export,
since when you turn it off, the whole SoC locks up.
Thanks
Andrew
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
2012-11-17 8:26 ` Andrew Lunn
@ 2012-11-17 9:41 ` Gregory CLEMENT
-1 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-17 9:41 UTC (permalink / raw)
To: Andrew Lunn; +Cc: linux-arm-kernel, Sebastian Hesselbarth, linux-kernel
Hi Andrew
On 11/17/2012 09:26 AM, Andrew Lunn wrote:
> Hi Gregory
>
> Nice work
Thanks!
>
> On Fri, Nov 16, 2012 at 07:01:59PM +0100, Gregory CLEMENT wrote:
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>> .../bindings/clock/mvebu-gated-clock.txt | 43 ++++++++++++++
>> arch/arm/mach-mvebu/Kconfig | 1 +
>> drivers/clk/mvebu/clk-gating-ctrl.c | 61 ++++++++++++++++++++
>> 3 files changed, 105 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
>> index 7497cc0..9dbcdd9 100644
>> --- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
>> +++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
>> @@ -6,6 +6,49 @@ the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to
>> the corresponding clock gating control bit in HW to ease manual clock lookup
>> in datasheet.
>>
>> +The following is a list of provided IDs for Armada XP:
>
> Should that the 370, not XP?
Yes indeed, it was a wrong copy and paste.
>
>> +ID Clock Peripheral
>> +-----------------------------------
>> +0 Audio AC97 Cntrl
>> +1 pex0_en PCIe 0 Clock out
>> +2 pex1_en PCIe 1 Clock out
>> +3 ge1 Gigabit Ethernet 1
>> +4 ge0 Gigabit Ethernet 0
>> +5 pex0 PCIe Cntrl 0
>> +9 pex1 PCIe Cntrl 1
>> +15 sata0 SATA Host 0
>> +17 sdio SDHCI Host
>> +25 tdm Time Division Mplx
>> +28 ddr DDR Cntrl
>> +30 sata1 SATA Host 0
>
> Not many clocks there. USB? XOR? Crypto?
Yes I was surprised too, but it was I found on the datasheet.
For USB, for example you can turn the USB in low power mode but
at the PHY level.
>
> What is the ddr clock for? Does bad things happen if you turn it off?
> Kirkwood has a similar clock, dunit, which i decided not to export,
> since when you turn it off, the whole SoC locks up.
Well of course if you code run in DDR then it could be a problem. But
I think it could be useful to turn it off when going to suspend, it
the DDR can do self-refresh. In this case it should be possible to run
the code from SRAM or L2 Cache.
Gregory
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
@ 2012-11-17 9:41 ` Gregory CLEMENT
0 siblings, 0 replies; 56+ messages in thread
From: Gregory CLEMENT @ 2012-11-17 9:41 UTC (permalink / raw)
To: linux-arm-kernel
Hi Andrew
On 11/17/2012 09:26 AM, Andrew Lunn wrote:
> Hi Gregory
>
> Nice work
Thanks!
>
> On Fri, Nov 16, 2012 at 07:01:59PM +0100, Gregory CLEMENT wrote:
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>> .../bindings/clock/mvebu-gated-clock.txt | 43 ++++++++++++++
>> arch/arm/mach-mvebu/Kconfig | 1 +
>> drivers/clk/mvebu/clk-gating-ctrl.c | 61 ++++++++++++++++++++
>> 3 files changed, 105 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
>> index 7497cc0..9dbcdd9 100644
>> --- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
>> +++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
>> @@ -6,6 +6,49 @@ the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to
>> the corresponding clock gating control bit in HW to ease manual clock lookup
>> in datasheet.
>>
>> +The following is a list of provided IDs for Armada XP:
>
> Should that the 370, not XP?
Yes indeed, it was a wrong copy and paste.
>
>> +ID Clock Peripheral
>> +-----------------------------------
>> +0 Audio AC97 Cntrl
>> +1 pex0_en PCIe 0 Clock out
>> +2 pex1_en PCIe 1 Clock out
>> +3 ge1 Gigabit Ethernet 1
>> +4 ge0 Gigabit Ethernet 0
>> +5 pex0 PCIe Cntrl 0
>> +9 pex1 PCIe Cntrl 1
>> +15 sata0 SATA Host 0
>> +17 sdio SDHCI Host
>> +25 tdm Time Division Mplx
>> +28 ddr DDR Cntrl
>> +30 sata1 SATA Host 0
>
> Not many clocks there. USB? XOR? Crypto?
Yes I was surprised too, but it was I found on the datasheet.
For USB, for example you can turn the USB in low power mode but
at the PHY level.
>
> What is the ddr clock for? Does bad things happen if you turn it off?
> Kirkwood has a similar clock, dunit, which i decided not to export,
> since when you turn it off, the whole SoC locks up.
Well of course if you code run in DDR then it could be a problem. But
I think it could be useful to turn it off when going to suspend, it
the DDR can do self-refresh. In this case it should be possible to run
the code from SRAM or L2 Cache.
Gregory
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
2012-11-17 9:41 ` Gregory CLEMENT
@ 2012-11-17 13:54 ` Andrew Lunn
-1 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-17 13:54 UTC (permalink / raw)
To: Gregory CLEMENT
Cc: Andrew Lunn, linux-arm-kernel, Sebastian Hesselbarth, linux-kernel
> > What is the ddr clock for? Does bad things happen if you turn it off?
> > Kirkwood has a similar clock, dunit, which i decided not to export,
> > since when you turn it off, the whole SoC locks up.
>
> Well of course if you code run in DDR then it could be a problem. But
> I think it could be useful to turn it off when going to suspend, it
> the DDR can do self-refresh. In this case it should be possible to run
> the code from SRAM or L2 Cache.
O.K. Just watch out for the lateinit call in the clock framework.
Andrew
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
@ 2012-11-17 13:54 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-17 13:54 UTC (permalink / raw)
To: linux-arm-kernel
> > What is the ddr clock for? Does bad things happen if you turn it off?
> > Kirkwood has a similar clock, dunit, which i decided not to export,
> > since when you turn it off, the whole SoC locks up.
>
> Well of course if you code run in DDR then it could be a problem. But
> I think it could be useful to turn it off when going to suspend, it
> the DDR can do self-refresh. In this case it should be possible to run
> the code from SRAM or L2 Cache.
O.K. Just watch out for the lateinit call in the clock framework.
Andrew
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
2012-11-17 13:54 ` Andrew Lunn
@ 2012-11-19 4:30 ` Mike Turquette
-1 siblings, 0 replies; 56+ messages in thread
From: Mike Turquette @ 2012-11-19 4:30 UTC (permalink / raw)
To: Andrew Lunn, Gregory CLEMENT
Cc: Andrew Lunn, linux-kernel, linux-arm-kernel, Sebastian Hesselbarth
Quoting Andrew Lunn (2012-11-17 05:54:35)
> > > What is the ddr clock for? Does bad things happen if you turn it off?
> > > Kirkwood has a similar clock, dunit, which i decided not to export,
> > > since when you turn it off, the whole SoC locks up.
> >
> > Well of course if you code run in DDR then it could be a problem. But
> > I think it could be useful to turn it off when going to suspend, it
> > the DDR can do self-refresh. In this case it should be possible to run
> > the code from SRAM or L2 Cache.
>
> O.K. Just watch out for the lateinit call in the clock framework.
>
CLK_IGNORE_UNUSED is the flag you want for this situation.
Regards,
Mike
> Andrew
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
@ 2012-11-19 4:30 ` Mike Turquette
0 siblings, 0 replies; 56+ messages in thread
From: Mike Turquette @ 2012-11-19 4:30 UTC (permalink / raw)
To: linux-arm-kernel
Quoting Andrew Lunn (2012-11-17 05:54:35)
> > > What is the ddr clock for? Does bad things happen if you turn it off?
> > > Kirkwood has a similar clock, dunit, which i decided not to export,
> > > since when you turn it off, the whole SoC locks up.
> >
> > Well of course if you code run in DDR then it could be a problem. But
> > I think it could be useful to turn it off when going to suspend, it
> > the DDR can do self-refresh. In this case it should be possible to run
> > the code from SRAM or L2 Cache.
>
> O.K. Just watch out for the lateinit call in the clock framework.
>
CLK_IGNORE_UNUSED is the flag you want for this situation.
Regards,
Mike
> Andrew
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
2012-11-17 13:54 ` Andrew Lunn
@ 2012-11-19 15:46 ` Thomas Petazzoni
-1 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-19 15:46 UTC (permalink / raw)
To: Andrew Lunn
Cc: Gregory CLEMENT, linux-kernel, linux-arm-kernel, Sebastian Hesselbarth
Dear Andrew Lunn,
On Sat, 17 Nov 2012 14:54:35 +0100, Andrew Lunn wrote:
> > > What is the ddr clock for? Does bad things happen if you turn it off?
> > > Kirkwood has a similar clock, dunit, which i decided not to export,
> > > since when you turn it off, the whole SoC locks up.
> >
> > Well of course if you code run in DDR then it could be a problem. But
> > I think it could be useful to turn it off when going to suspend, it
> > the DDR can do self-refresh. In this case it should be possible to run
> > the code from SRAM or L2 Cache.
>
> O.K. Just watch out for the lateinit call in the clock framework.
I don't think there is a problem with the dramclk and the lateinit call
of the clock framework. The dramclk is a fixed factor clock, and the
fixed factor clock driver does not implement the ->disable() operation.
And therefore, the clk_disable_unused() code executed as the lateinit
call will not be able to disable it:
if (__clk_is_enabled(clk) && clk->ops->disable)
clk->ops->disable(clk->hw);
So I think we're quite safe with fixed rate clocks and fixed factor
clocks in that no-one can disable them :-)
Best regards,
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
@ 2012-11-19 15:46 ` Thomas Petazzoni
0 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-19 15:46 UTC (permalink / raw)
To: linux-arm-kernel
Dear Andrew Lunn,
On Sat, 17 Nov 2012 14:54:35 +0100, Andrew Lunn wrote:
> > > What is the ddr clock for? Does bad things happen if you turn it off?
> > > Kirkwood has a similar clock, dunit, which i decided not to export,
> > > since when you turn it off, the whole SoC locks up.
> >
> > Well of course if you code run in DDR then it could be a problem. But
> > I think it could be useful to turn it off when going to suspend, it
> > the DDR can do self-refresh. In this case it should be possible to run
> > the code from SRAM or L2 Cache.
>
> O.K. Just watch out for the lateinit call in the clock framework.
I don't think there is a problem with the dramclk and the lateinit call
of the clock framework. The dramclk is a fixed factor clock, and the
fixed factor clock driver does not implement the ->disable() operation.
And therefore, the clk_disable_unused() code executed as the lateinit
call will not be able to disable it:
if (__clk_is_enabled(clk) && clk->ops->disable)
clk->ops->disable(clk->hw);
So I think we're quite safe with fixed rate clocks and fixed factor
clocks in that no-one can disable them :-)
Best regards,
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
2012-11-19 15:46 ` Thomas Petazzoni
@ 2012-11-19 15:58 ` Andrew Lunn
-1 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-19 15:58 UTC (permalink / raw)
To: Thomas Petazzoni
Cc: Andrew Lunn, Gregory CLEMENT, linux-kernel, linux-arm-kernel,
Sebastian Hesselbarth
On Mon, Nov 19, 2012 at 04:46:11PM +0100, Thomas Petazzoni wrote:
> Dear Andrew Lunn,
>
> On Sat, 17 Nov 2012 14:54:35 +0100, Andrew Lunn wrote:
> > > > What is the ddr clock for? Does bad things happen if you turn it off?
> > > > Kirkwood has a similar clock, dunit, which i decided not to export,
> > > > since when you turn it off, the whole SoC locks up.
> > >
> > > Well of course if you code run in DDR then it could be a problem. But
> > > I think it could be useful to turn it off when going to suspend, it
> > > the DDR can do self-refresh. In this case it should be possible to run
> > > the code from SRAM or L2 Cache.
> >
> > O.K. Just watch out for the lateinit call in the clock framework.
>
> I don't think there is a problem with the dramclk and the lateinit call
> of the clock framework. The dramclk is a fixed factor clock, and the
> fixed factor clock driver does not implement the ->disable() operation.
> And therefore, the clk_disable_unused() code executed as the lateinit
> call will not be able to disable it:
>
> if (__clk_is_enabled(clk) && clk->ops->disable)
> clk->ops->disable(clk->hw);
>
> So I think we're quite safe with fixed rate clocks and fixed factor
> clocks in that no-one can disable them :-)
Hi Thomas
I don't think we are taking about the same clock. I mean the gate
clock:
28 ddr DDR Cntrl
not the core clock.
Andrew
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
@ 2012-11-19 15:58 ` Andrew Lunn
0 siblings, 0 replies; 56+ messages in thread
From: Andrew Lunn @ 2012-11-19 15:58 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 19, 2012 at 04:46:11PM +0100, Thomas Petazzoni wrote:
> Dear Andrew Lunn,
>
> On Sat, 17 Nov 2012 14:54:35 +0100, Andrew Lunn wrote:
> > > > What is the ddr clock for? Does bad things happen if you turn it off?
> > > > Kirkwood has a similar clock, dunit, which i decided not to export,
> > > > since when you turn it off, the whole SoC locks up.
> > >
> > > Well of course if you code run in DDR then it could be a problem. But
> > > I think it could be useful to turn it off when going to suspend, it
> > > the DDR can do self-refresh. In this case it should be possible to run
> > > the code from SRAM or L2 Cache.
> >
> > O.K. Just watch out for the lateinit call in the clock framework.
>
> I don't think there is a problem with the dramclk and the lateinit call
> of the clock framework. The dramclk is a fixed factor clock, and the
> fixed factor clock driver does not implement the ->disable() operation.
> And therefore, the clk_disable_unused() code executed as the lateinit
> call will not be able to disable it:
>
> if (__clk_is_enabled(clk) && clk->ops->disable)
> clk->ops->disable(clk->hw);
>
> So I think we're quite safe with fixed rate clocks and fixed factor
> clocks in that no-one can disable them :-)
Hi Thomas
I don't think we are taking about the same clock. I mean the gate
clock:
28 ddr DDR Cntrl
not the core clock.
Andrew
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
2012-11-19 15:46 ` Thomas Petazzoni
@ 2012-11-19 16:01 ` Sebastian Hesselbarth
-1 siblings, 0 replies; 56+ messages in thread
From: Sebastian Hesselbarth @ 2012-11-19 16:01 UTC (permalink / raw)
To: Thomas Petazzoni
Cc: Andrew Lunn, Gregory CLEMENT, linux-kernel, linux-arm-kernel
On 11/19/2012 04:46 PM, Thomas Petazzoni wrote:
> Dear Andrew Lunn,
>
> On Sat, 17 Nov 2012 14:54:35 +0100, Andrew Lunn wrote:
>>>> What is the ddr clock for? Does bad things happen if you turn it off?
>>>> Kirkwood has a similar clock, dunit, which i decided not to export,
>>>> since when you turn it off, the whole SoC locks up.
>>>
>>> Well of course if you code run in DDR then it could be a problem. But
>>> I think it could be useful to turn it off when going to suspend, it
>>> the DDR can do self-refresh. In this case it should be possible to run
>>> the code from SRAM or L2 Cache.
>>
>> O.K. Just watch out for the lateinit call in the clock framework.
>
> I don't think there is a problem with the dramclk and the lateinit call
> of the clock framework. The dramclk is a fixed factor clock, and the
> fixed factor clock driver does not implement the ->disable() operation.
> And therefore, the clk_disable_unused() code executed as the lateinit
> call will not be able to disable it:
>
> if (__clk_is_enabled(clk)&& clk->ops->disable)
> clk->ops->disable(clk->hw);
>
> So I think we're quite safe with fixed rate clocks and fixed factor
> clocks in that no-one can disable them :-)
Thomas,
I guess Andrew was referring to the clock gating control bit for ddr on
Armada 370 not the fixed factor clock. If there is a clk_gate
installed, it will be disabled if not taken by any driver or init code.
You disable either the ddr controller clock or the external ddr clock
or both, but all will lead to a system lock up.
If unsure, you should remove bit 28 from clk-gating-ctrl.c and it's
devicetree documentation for Armada 370. Well get all the gates
straight as soon as we have more support for e.g. PMU, GEPHY, aso.
Sebastian
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
@ 2012-11-19 16:01 ` Sebastian Hesselbarth
0 siblings, 0 replies; 56+ messages in thread
From: Sebastian Hesselbarth @ 2012-11-19 16:01 UTC (permalink / raw)
To: linux-arm-kernel
On 11/19/2012 04:46 PM, Thomas Petazzoni wrote:
> Dear Andrew Lunn,
>
> On Sat, 17 Nov 2012 14:54:35 +0100, Andrew Lunn wrote:
>>>> What is the ddr clock for? Does bad things happen if you turn it off?
>>>> Kirkwood has a similar clock, dunit, which i decided not to export,
>>>> since when you turn it off, the whole SoC locks up.
>>>
>>> Well of course if you code run in DDR then it could be a problem. But
>>> I think it could be useful to turn it off when going to suspend, it
>>> the DDR can do self-refresh. In this case it should be possible to run
>>> the code from SRAM or L2 Cache.
>>
>> O.K. Just watch out for the lateinit call in the clock framework.
>
> I don't think there is a problem with the dramclk and the lateinit call
> of the clock framework. The dramclk is a fixed factor clock, and the
> fixed factor clock driver does not implement the ->disable() operation.
> And therefore, the clk_disable_unused() code executed as the lateinit
> call will not be able to disable it:
>
> if (__clk_is_enabled(clk)&& clk->ops->disable)
> clk->ops->disable(clk->hw);
>
> So I think we're quite safe with fixed rate clocks and fixed factor
> clocks in that no-one can disable them :-)
Thomas,
I guess Andrew was referring to the clock gating control bit for ddr on
Armada 370 not the fixed factor clock. If there is a clk_gate
installed, it will be disabled if not taken by any driver or init code.
You disable either the ddr controller clock or the external ddr clock
or both, but all will lead to a system lock up.
If unsure, you should remove bit 28 from clk-gating-ctrl.c and it's
devicetree documentation for Armada 370. Well get all the gates
straight as soon as we have more support for e.g. PMU, GEPHY, aso.
Sebastian
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
2012-11-19 15:58 ` Andrew Lunn
@ 2012-11-19 16:43 ` Thomas Petazzoni
-1 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-19 16:43 UTC (permalink / raw)
To: Andrew Lunn
Cc: Gregory CLEMENT, linux-kernel, linux-arm-kernel, Sebastian Hesselbarth
Dear Andrew Lunn,
On Mon, 19 Nov 2012 16:58:56 +0100, Andrew Lunn wrote:
> I don't think we are taking about the same clock. I mean the gate
> clock:
>
> 28 ddr DDR Cntrl
>
> not the core clock.
Right, after discussion with Gregory, I found out my misunderstanding.
I'm looking now as to how this clock affects the system behavior. I
indeed see this clock ->disable() hook being called, but it doesn't
seem to cause any sort of problem on the system. It still works nicely.
So not sure this clock is actually doing something, or at least maybe
not what we think it does.
Best regards,
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT
@ 2012-11-19 16:43 ` Thomas Petazzoni
0 siblings, 0 replies; 56+ messages in thread
From: Thomas Petazzoni @ 2012-11-19 16:43 UTC (permalink / raw)
To: linux-arm-kernel
Dear Andrew Lunn,
On Mon, 19 Nov 2012 16:58:56 +0100, Andrew Lunn wrote:
> I don't think we are taking about the same clock. I mean the gate
> clock:
>
> 28 ddr DDR Cntrl
>
> not the core clock.
Right, after discussion with Gregory, I found out my misunderstanding.
I'm looking now as to how this clock affects the system behavior. I
indeed see this clock ->disable() hook being called, but it doesn't
seem to cause any sort of problem on the system. It still works nicely.
So not sure this clock is actually doing something, or at least maybe
not what we think it does.
Best regards,
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 56+ messages in thread
end of thread, other threads:[~2012-11-19 16:43 UTC | newest]
Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-15 21:28 [PATCH 0/7] core, cpu and gated clocks for mvebu Andrew Lunn
2012-11-15 21:28 ` Andrew Lunn
2012-11-15 21:28 ` [PATCH 1/7] clk: mvebu: add mvebu core clocks Andrew Lunn
2012-11-15 21:28 ` Andrew Lunn
[not found] ` <1353014906-31566-2-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>
2012-11-16 12:52 ` Gregory CLEMENT
2012-11-16 12:52 ` Gregory CLEMENT
2012-11-15 21:28 ` [PATCH 2/7] clk: mvebu: add armada-370-xp CPU specific clocks Andrew Lunn
2012-11-15 21:28 ` Andrew Lunn
[not found] ` <1353014906-31566-3-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>
2012-11-15 21:44 ` Thomas Petazzoni
2012-11-15 21:44 ` Thomas Petazzoni
2012-11-15 21:28 ` [PATCH 3/7] clk: armada-370-xp: add support for clock framework Andrew Lunn
2012-11-15 21:28 ` Andrew Lunn
[not found] ` <1353014906-31566-4-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>
2012-11-15 21:46 ` Thomas Petazzoni
2012-11-15 21:46 ` Thomas Petazzoni
[not found] ` <1353014906-31566-1-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>
2012-11-15 21:28 ` [PATCH 4/7] clocksource: time-armada-370-xp converted to clk framework Andrew Lunn
2012-11-15 21:28 ` Andrew Lunn
[not found] ` <1353014906-31566-5-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>
2012-11-15 21:49 ` Thomas Petazzoni
2012-11-15 21:49 ` Thomas Petazzoni
2012-11-15 21:28 ` [PATCH 5/7] clk: mvebu: add clock gating control provider for DT Andrew Lunn
2012-11-15 21:28 ` Andrew Lunn
2012-11-16 18:01 ` [PATCH 0/2] Add clock gating support for Armada 370/XP Gregory CLEMENT
2012-11-16 18:01 ` Gregory CLEMENT
2012-11-16 18:01 ` [PATCH 1/2] clk: mvebu: armada 370/XP add clock gating control provider for DT Gregory CLEMENT
2012-11-16 18:01 ` Gregory CLEMENT
2012-11-17 8:26 ` Andrew Lunn
2012-11-17 8:26 ` Andrew Lunn
2012-11-17 9:41 ` Gregory CLEMENT
2012-11-17 9:41 ` Gregory CLEMENT
2012-11-17 13:54 ` Andrew Lunn
2012-11-17 13:54 ` Andrew Lunn
2012-11-19 4:30 ` Mike Turquette
2012-11-19 4:30 ` Mike Turquette
2012-11-19 15:46 ` Thomas Petazzoni
2012-11-19 15:46 ` Thomas Petazzoni
2012-11-19 15:58 ` Andrew Lunn
2012-11-19 15:58 ` Andrew Lunn
2012-11-19 16:43 ` Thomas Petazzoni
2012-11-19 16:43 ` Thomas Petazzoni
2012-11-19 16:01 ` Sebastian Hesselbarth
2012-11-19 16:01 ` Sebastian Hesselbarth
2012-11-16 18:02 ` [PATCH 2/2] arm: mvebu: armada 370/XP adding clock gating support: dt binding Gregory CLEMENT
2012-11-16 18:02 ` Gregory CLEMENT
2012-11-15 21:28 ` [PATCH 6/7] ARM: dove: switch to DT clock providers Andrew Lunn
2012-11-15 21:28 ` Andrew Lunn
[not found] ` <1353014906-31566-7-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>
2012-11-15 21:52 ` Thomas Petazzoni
2012-11-15 21:52 ` Thomas Petazzoni
2012-11-15 21:28 ` [PATCH 7/7] ARM: Kirkwood: " Andrew Lunn
2012-11-15 21:28 ` Andrew Lunn
[not found] ` <1353014906-31566-8-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>
2012-11-16 17:33 ` Gregory CLEMENT
2012-11-16 17:33 ` Gregory CLEMENT
2012-11-15 21:54 ` [PATCH 0/7] core, cpu and gated clocks for mvebu Thomas Petazzoni
2012-11-15 21:54 ` Thomas Petazzoni
2012-11-16 7:32 ` Andrew Lunn
2012-11-16 7:32 ` Andrew Lunn
2012-11-16 12:51 ` Gregory CLEMENT
2012-11-16 12:51 ` Gregory CLEMENT
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.