linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/10] Marvell Berlin full clock support
@ 2014-05-19 16:43 Sebastian Hesselbarth
  2014-05-19 16:43 ` [PATCH v2 01/10] dt-binding: ARM: add clock binding docs for Marvell Berlin2 SoCs Sebastian Hesselbarth
                   ` (11 more replies)
  0 siblings, 12 replies; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 16:43 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Mike Turquette, Alexandre Belloni, Jisheng Zhang,
	devicetree, linux-doc, linux-arm-kernel, linux-kernel

Mike,

this is v2 of the Berlin SoC clock driver [1] but with a reworked DT
binding as requested [2]. We decided to not even try to split up the chip
control registers that deal with pinmux, padmux, clock, reset, and evil
stuff we haven't even looked at. Instead we keep a single node that clock
driver will remap early, while proper platform_drivers use a regmap
instead. Although clock and other drivers share the same register range,
they use individual registers exclusively.

There are some functional fixes in the single clock drivers, I noticed
while retesting each individial driver. There will be more to fixup but
without any drivers actually using the clocks, it is hard to tell what
isn't working now.

Anyway, the current binding should match what you requested and having
a clock driver for v3.16 will really be a huge benefit for us to work
on more driver support.

If you are fine with it, please take patches 2-7 and I'll pick up
1,8-10 in berlin branch.

Sebastian

[1] https://lkml.kernel.org/r/1399839881-29895-1-git-send-email-sebastian.hesselbarth@gmail.com
[2] https://lkml.kernel.org/r/20140515044106.19795.57249@quantum

Alexandre Belloni (4):
  clk: berlin: add driver for BG2x simple PLLs
  clk: berlin: add driver for BG2x complex divider cells
  clk: berlin: add core clock driver for BG2Q
  ARM: dts: berlin: convert BG2Q to DT clock nodes

Sebastian Hesselbarth (6):
  dt-binding: ARM: add clock binding docs for Marvell Berlin2 SoCs
  clk: berlin: add binding include for Berlin SoC clock ids
  clk: berlin: add driver for BG2x audio/video PLL
  clk: berlin: add core clock driver for BG2/BG2CD
  ARM: dts: berlin: convert BG2CD to DT clock nodes
  ARM: dts: berlin: convert BG2 to DT clock nodes

 .../devicetree/bindings/arm/marvell,berlin.txt     |  47 ++
 arch/arm/boot/dts/berlin2.dtsi                     |  56 +-
 arch/arm/boot/dts/berlin2cd.dtsi                   |  53 +-
 arch/arm/boot/dts/berlin2q.dtsi                    |  54 +-
 drivers/clk/Makefile                               |   1 +
 drivers/clk/berlin/Makefile                        |   4 +
 drivers/clk/berlin/berlin2-avpll.c                 | 393 ++++++++++++
 drivers/clk/berlin/berlin2-avpll.h                 |  36 ++
 drivers/clk/berlin/berlin2-div.c                   | 265 ++++++++
 drivers/clk/berlin/berlin2-div.h                   |  89 +++
 drivers/clk/berlin/berlin2-pll.c                   | 117 ++++
 drivers/clk/berlin/berlin2-pll.h                   |  37 ++
 drivers/clk/berlin/bg2.c                           | 691 +++++++++++++++++++++
 drivers/clk/berlin/bg2q.c                          | 389 ++++++++++++
 drivers/clk/berlin/common.h                        |  29 +
 include/dt-bindings/clock/berlin2.h                |  45 ++
 include/dt-bindings/clock/berlin2q.h               |  31 +
 17 files changed, 2240 insertions(+), 97 deletions(-)
 create mode 100644 drivers/clk/berlin/Makefile
 create mode 100644 drivers/clk/berlin/berlin2-avpll.c
 create mode 100644 drivers/clk/berlin/berlin2-avpll.h
 create mode 100644 drivers/clk/berlin/berlin2-div.c
 create mode 100644 drivers/clk/berlin/berlin2-div.h
 create mode 100644 drivers/clk/berlin/berlin2-pll.c
 create mode 100644 drivers/clk/berlin/berlin2-pll.h
 create mode 100644 drivers/clk/berlin/bg2.c
 create mode 100644 drivers/clk/berlin/bg2q.c
 create mode 100644 drivers/clk/berlin/common.h
 create mode 100644 include/dt-bindings/clock/berlin2.h
 create mode 100644 include/dt-bindings/clock/berlin2q.h

---
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: devicetree@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
-- 
1.9.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 01/10] dt-binding: ARM: add clock binding docs for Marvell Berlin2 SoCs
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
@ 2014-05-19 16:43 ` Sebastian Hesselbarth
  2014-05-19 21:05   ` Alexandre Belloni
  2014-05-19 16:43 ` [PATCH v2 02/10] clk: berlin: add binding include for Berlin SoC clock ids Sebastian Hesselbarth
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 16:43 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Mike Turquette, Alexandre Belloni, Jisheng Zhang,
	devicetree, linux-doc, linux-arm-kernel, linux-kernel

This adds mandatory device tree binding documentation for the clock related
IP found on Marvell Berlin2 (BG2, BG2CD, and BG2Q) SoCs to the Berlin SoC
binding documentation.

Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- typo fixed (Reported by Alexandre Belloni)
- reworked binding to not represent individual clocks but chip control
  IP/registers instead (Suggested by Mike Turquette)
- dropped clock indices, refer to the include instead (Requested by Mike
  Turquette)
- moved the documentation from bindings/clock to Marvell Berlin SoC
  binding, as there will be more functions (e.g. pinctrl) to describe

Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: devicetree@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 .../devicetree/bindings/arm/marvell,berlin.txt     | 47 ++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/marvell,berlin.txt b/Documentation/devicetree/bindings/arm/marvell,berlin.txt
index 0677003e1476..744a7ea569d4 100644
--- a/Documentation/devicetree/bindings/arm/marvell,berlin.txt
+++ b/Documentation/devicetree/bindings/arm/marvell,berlin.txt
@@ -23,3 +23,50 @@ SoC and board used. Currently known SoC compatibles are:
 
 	...
 }
+
+* Marvell Berlin2 chip control binding
+
+Marvell Berlin SoCs have a chip control register set providing several
+individual registers dealing with pinmux, padmux, clock, reset, and secondary
+CPU boot address. Unfortunately, the individual registers are spread among the
+chip control registers, so there should be a single DT node only providing the
+different functions which are described below.
+
+Required properties:
+- compatible: shall be one of
+	"marvell,berlin2-chip-ctrl" for BG2
+	"marvell,berlin2cd-chip-ctrl" for BG2CD
+	"marvell,berlin2q-chip-ctrl" for BG2Q
+- reg: address and length of following register sets for
+  BG2/BG2CD: chip control register set
+  BG2Q: chip control register set and cpu pll registers
+
+* Clock provider binding
+
+As clock related registers are spread among the chip control registers, the
+chip control node also provides the clocks. Marvell Berlin2 (BG2, BG2CD, BG2Q)
+SoCs share the same IP for PLLs and clocks, with some minor differences in
+features and register layout.
+
+Required properties:
+- #clock-cells: shall be set to 1
+- clocks: clock specifiers referencing the core clock input clocks
+- clock-names: array of strings describing the input clock specifiers above.
+    Allowed clock-names for the reference clocks are
+      "refclk" for the SoCs osciallator input on all SoCs,
+    and SoC-specific input clocks for
+      BG2/BG2CD: "video_ext0" for the external video clock input
+
+Clocks provided by core clocks shall be referenced by a clock specifier
+indexing one of the provided clocks. Refer to dt-bindings/clock/berlin<soc>.h
+for the corresponding index mapping.
+
+Example:
+
+chip: chip-control@ea0000 {
+	compatible = "marvell,berlin2-chip-ctrl";
+	#clock-cells = <1>;
+	reg = <0xea0000 0x400>;
+	clocks = <&refclk>, <&externaldev 0>;
+	clock-names = "refclk", "video_ext0";
+};
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 02/10] clk: berlin: add binding include for Berlin SoC clock ids
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
  2014-05-19 16:43 ` [PATCH v2 01/10] dt-binding: ARM: add clock binding docs for Marvell Berlin2 SoCs Sebastian Hesselbarth
@ 2014-05-19 16:43 ` Sebastian Hesselbarth
  2014-05-19 16:43 ` [PATCH v2 03/10] clk: berlin: add driver for BG2x audio/video PLL Sebastian Hesselbarth
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 16:43 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Alexandre Belloni, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Mike Turquette, Jisheng Zhang,
	devicetree, linux-arm-kernel, linux-kernel

This adds a dt-binding include for Marvell Berlin BG2/BG2CD and BG2Q
core clock IDs.

Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
Changelog:
v1->v2:
- separate patch to allow to use it in the driver (Suggested by Alexandre
  Belloni)

Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 include/dt-bindings/clock/berlin2.h  | 45 ++++++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/berlin2q.h | 31 +++++++++++++++++++++++++
 2 files changed, 76 insertions(+)
 create mode 100644 include/dt-bindings/clock/berlin2.h
 create mode 100644 include/dt-bindings/clock/berlin2q.h

diff --git a/include/dt-bindings/clock/berlin2.h b/include/dt-bindings/clock/berlin2.h
new file mode 100644
index 000000000000..0c30800175df
--- /dev/null
+++ b/include/dt-bindings/clock/berlin2.h
@@ -0,0 +1,45 @@
+/*
+ * Berlin2 BG2/BG2CD clock tree IDs
+ */
+
+#define CLKID_SYS		0
+#define CLKID_CPU		1
+#define CLKID_DRMFIGO		2
+#define CLKID_CFG		3
+#define CLKID_GFX		4
+#define CLKID_ZSP		5
+#define CLKID_PERIF		6
+#define CLKID_PCUBE		7
+#define CLKID_VSCOPE		8
+#define CLKID_NFC_ECC		9
+#define CLKID_VPP		10
+#define CLKID_APP		11
+#define CLKID_AUDIO0		12
+#define CLKID_AUDIO2		13
+#define CLKID_AUDIO3		14
+#define CLKID_AUDIO1		15
+#define CLKID_GFX3D_CORE	16
+#define CLKID_GFX3D_SYS		17
+#define CLKID_ARC		18
+#define CLKID_VIP		19
+#define CLKID_SDIO0XIN		20
+#define CLKID_SDIO1XIN		21
+#define CLKID_GFX3D_EXTRA	22
+#define CLKID_GC360		23
+#define CLKID_SDIO_DLLMST	24
+#define CLKID_GETH0		25
+#define CLKID_GETH1		26
+#define CLKID_SATA		27
+#define CLKID_AHBAPB		28
+#define CLKID_USB0		29
+#define CLKID_USB1		30
+#define CLKID_PBRIDGE		31
+#define CLKID_SDIO0		32
+#define CLKID_SDIO1		33
+#define CLKID_NFC		34
+#define CLKID_SMEMC		35
+#define CLKID_AUDIOHD		36
+#define CLKID_VIDEO0		37
+#define CLKID_VIDEO1		38
+#define CLKID_VIDEO2		39
+#define CLKID_TWD		40
diff --git a/include/dt-bindings/clock/berlin2q.h b/include/dt-bindings/clock/berlin2q.h
new file mode 100644
index 000000000000..287fc3b4afb2
--- /dev/null
+++ b/include/dt-bindings/clock/berlin2q.h
@@ -0,0 +1,31 @@
+/*
+ * Berlin2 BG2Q clock tree IDs
+ */
+
+#define CLKID_SYS		0
+#define CLKID_DRMFIGO		1
+#define CLKID_CFG		2
+#define CLKID_GFX2D		3
+#define CLKID_ZSP		4
+#define CLKID_PERIF		5
+#define CLKID_PCUBE		6
+#define CLKID_VSCOPE		7
+#define CLKID_NFC_ECC		8
+#define CLKID_VPP		9
+#define CLKID_APP		10
+#define CLKID_SDIO0XIN		11
+#define CLKID_SDIO1XIN		12
+#define CLKID_GFX2DAXI		13
+#define CLKID_GETH0		14
+#define CLKID_SATA		15
+#define CLKID_AHBAPB		16
+#define CLKID_USB0		17
+#define CLKID_USB1		18
+#define CLKID_USB2		19
+#define CLKID_USB3		20
+#define CLKID_PBRIDGE		21
+#define CLKID_SDIO		22
+#define CLKID_NFC		23
+#define CLKID_SMEMC		24
+#define CLKID_PCIE		25
+#define CLKID_TWD		26
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 03/10] clk: berlin: add driver for BG2x audio/video PLL
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
  2014-05-19 16:43 ` [PATCH v2 01/10] dt-binding: ARM: add clock binding docs for Marvell Berlin2 SoCs Sebastian Hesselbarth
  2014-05-19 16:43 ` [PATCH v2 02/10] clk: berlin: add binding include for Berlin SoC clock ids Sebastian Hesselbarth
@ 2014-05-19 16:43 ` Sebastian Hesselbarth
  2014-05-19 16:43 ` [PATCH v2 04/10] clk: berlin: add driver for BG2x simple PLLs Sebastian Hesselbarth
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 16:43 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Alexandre Belloni, Mike Turquette, Jisheng Zhang,
	linux-arm-kernel, linux-kernel

This is a driver for the AVPLLs built upon a VCO with 8 channels each
found on Marvell Berlin2 SoCs. While both VCOs found on BG2/BG2CD share
the same register set, sometimes registers shifts for one of the VCOs
are a bit off. Nothing serious that should require a separate driver,
so deal with both VCOs in a single driver instead.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- separate include for AVPLL driver
- split single clock driver for both VCO and 8 channels into separate
  drivers for VCO and each channel. BG2Q will be different to BG2/BG2CD
  and it allows us to shove in CCF flags for each of the channels.
  (Suggested by Alexandre Belloni, Mike Turquette)

Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/clk/Makefile               |   1 +
 drivers/clk/berlin/Makefile        |   1 +
 drivers/clk/berlin/berlin2-avpll.c | 393 +++++++++++++++++++++++++++++++++++++
 drivers/clk/berlin/berlin2-avpll.h |  36 ++++
 4 files changed, 431 insertions(+)
 create mode 100644 drivers/clk/berlin/Makefile
 create mode 100644 drivers/clk/berlin/berlin2-avpll.c
 create mode 100644 drivers/clk/berlin/berlin2-avpll.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 5f8a28735c96..f651b2ace915 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_COMMON_CLK_WM831X)		+= clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_XGENE)		+= clk-xgene.o
 obj-$(CONFIG_COMMON_CLK_AT91)		+= at91/
 obj-$(CONFIG_ARCH_BCM_MOBILE)		+= bcm/
+obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
 obj-$(CONFIG_ARCH_HI3xxx)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIP04)		+= hisilicon/
 obj-$(CONFIG_COMMON_CLK_KEYSTONE)	+= keystone/
diff --git a/drivers/clk/berlin/Makefile b/drivers/clk/berlin/Makefile
new file mode 100644
index 000000000000..5905733fc7c7
--- /dev/null
+++ b/drivers/clk/berlin/Makefile
@@ -0,0 +1 @@
+obj-y += berlin2-avpll.o
diff --git a/drivers/clk/berlin/berlin2-avpll.c b/drivers/clk/berlin/berlin2-avpll.c
new file mode 100644
index 000000000000..fd0f26c38465
--- /dev/null
+++ b/drivers/clk/berlin/berlin2-avpll.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2014 Marvell Technology Group Ltd.
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "berlin2-avpll.h"
+
+/*
+ * Berlin2 SoCs comprise up to two PLLs called AVPLL built upon a
+ * VCO with 8 channels each, channel 8 is the odd-one-out and does
+ * not provide mul/div.
+ *
+ * Unfortunately, its registers are not named but just numbered. To
+ * get in at least some kind of structure, we split each AVPLL into
+ * the VCOs and each channel into separate clock drivers.
+ *
+ * Also, here and there the VCO registers are a bit different with
+ * respect to bit shifts. Make sure to add a comment for those.
+ */
+#define NUM_CHANNELS	8
+
+#define AVPLL_CTRL(x)		((x) * 0x4)
+
+#define VCO_CTRL0		AVPLL_CTRL(0)
+/* BG2/BG2CDs VCO_B has an additional shift of 4 for its VCO_CTRL0 reg */
+#define  VCO_RESET		BIT(0)
+#define  VCO_POWERUP		BIT(1)
+#define  VCO_INTERPOL_SHIFT	2
+#define  VCO_INTERPOL_MASK	(0xf << VCO_INTERPOL_SHIFT)
+#define  VCO_REG1V45_SEL_SHIFT	6
+#define  VCO_REG1V45_SEL(x)	((x) << VCO_REG1V45_SEL_SHIFT)
+#define  VCO_REG1V45_SEL_1V40	VCO_REG1V45_SEL(0)
+#define  VCO_REG1V45_SEL_1V45	VCO_REG1V45_SEL(1)
+#define  VCO_REG1V45_SEL_1V50	VCO_REG1V45_SEL(2)
+#define  VCO_REG1V45_SEL_1V55	VCO_REG1V45_SEL(3)
+#define  VCO_REG1V45_SEL_MASK	VCO_REG1V45_SEL(3)
+#define  VCO_REG0V9_SEL_SHIFT	8
+#define  VCO_REG0V9_SEL_MASK	(0xf << VCO_REG0V9_SEL_SHIFT)
+#define  VCO_VTHCAL_SHIFT	12
+#define  VCO_VTHCAL(x)		((x) << VCO_VTHCAL_SHIFT)
+#define  VCO_VTHCAL_0V90	VCO_VTHCAL(0)
+#define  VCO_VTHCAL_0V95	VCO_VTHCAL(1)
+#define  VCO_VTHCAL_1V00	VCO_VTHCAL(2)
+#define  VCO_VTHCAL_1V05	VCO_VTHCAL(3)
+#define  VCO_VTHCAL_MASK	VCO_VTHCAL(3)
+#define  VCO_KVCOEXT_SHIFT	14
+#define  VCO_KVCOEXT_MASK	(0x3 << VCO_KVCOEXT_SHIFT)
+#define  VCO_KVCOEXT_ENABLE	BIT(17)
+#define  VCO_V2IEXT_SHIFT	18
+#define  VCO_V2IEXT_MASK	(0xf << VCO_V2IEXT_SHIFT)
+#define  VCO_V2IEXT_ENABLE	BIT(22)
+#define  VCO_SPEED_SHIFT	23
+#define  VCO_SPEED(x)		((x) << VCO_SPEED_SHIFT)
+#define  VCO_SPEED_1G08_1G21	VCO_SPEED(0)
+#define  VCO_SPEED_1G21_1G40	VCO_SPEED(1)
+#define  VCO_SPEED_1G40_1G61	VCO_SPEED(2)
+#define  VCO_SPEED_1G61_1G86	VCO_SPEED(3)
+#define  VCO_SPEED_1G86_2G00	VCO_SPEED(4)
+#define  VCO_SPEED_2G00_2G22	VCO_SPEED(5)
+#define  VCO_SPEED_2G22		VCO_SPEED(6)
+#define  VCO_SPEED_MASK		VCO_SPEED(0x7)
+#define  VCO_CLKDET_ENABLE	BIT(26)
+#define VCO_CTRL1		AVPLL_CTRL(1)
+#define  VCO_REFDIV_SHIFT	0
+#define  VCO_REFDIV(x)		((x) << VCO_REFDIV_SHIFT)
+#define  VCO_REFDIV_1		VCO_REFDIV(0)
+#define  VCO_REFDIV_2		VCO_REFDIV(1)
+#define  VCO_REFDIV_4		VCO_REFDIV(2)
+#define  VCO_REFDIV_3		VCO_REFDIV(3)
+#define  VCO_REFDIV_MASK	VCO_REFDIV(0x3f)
+#define  VCO_FBDIV_SHIFT	6
+#define  VCO_FBDIV(x)		((x) << VCO_FBDIV_SHIFT)
+#define  VCO_FBDIV_MASK		VCO_FBDIV(0xff)
+#define  VCO_ICP_SHIFT		14
+/* PLL Charge Pump Current = 10uA * (x + 1) */
+#define  VCO_ICP(x)		((x) << VCO_ICP_SHIFT)
+#define  VCO_ICP_MASK		VCO_ICP(0xf)
+#define  VCO_LOAD_CAP		BIT(18)
+#define  VCO_CALIBRATION_START	BIT(19)
+#define VCO_FREQOFFSETn(x)	AVPLL_CTRL(3 + (x))
+#define  VCO_FREQOFFSET_MASK	0x7ffff
+#define VCO_CTRL10		AVPLL_CTRL(10)
+#define  VCO_POWERUP_CH1	BIT(20)
+#define VCO_CTRL11		AVPLL_CTRL(11)
+#define VCO_CTRL12		AVPLL_CTRL(12)
+#define VCO_CTRL13		AVPLL_CTRL(13)
+#define VCO_CTRL14		AVPLL_CTRL(14)
+#define VCO_CTRL15		AVPLL_CTRL(15)
+#define VCO_SYNC1n(x)		AVPLL_CTRL(15 + (x))
+#define  VCO_SYNC1_MASK		0x1ffff
+#define VCO_SYNC2n(x)		AVPLL_CTRL(23 + (x))
+#define  VCO_SYNC2_MASK		0x1ffff
+#define VCO_CTRL30		AVPLL_CTRL(30)
+#define  VCO_DPLL_CH1_ENABLE	BIT(17)
+
+struct berlin2_avpll_vco {
+	struct clk_hw hw;
+	void __iomem *base;
+	u8 flags;
+};
+
+#define to_avpll_vco(hw) container_of(hw, struct berlin2_avpll_vco, hw)
+
+static int berlin2_avpll_vco_is_enabled(struct clk_hw *hw)
+{
+	struct berlin2_avpll_vco *vco = to_avpll_vco(hw);
+	u32 reg;
+
+	reg = readl_relaxed(vco->base + VCO_CTRL0);
+	if (vco->flags & BERLIN2_AVPLL_BIT_QUIRK)
+		reg >>= 4;
+
+	return !!(reg & VCO_POWERUP);
+}
+
+static int berlin2_avpll_vco_enable(struct clk_hw *hw)
+{
+	struct berlin2_avpll_vco *vco = to_avpll_vco(hw);
+	u32 reg;
+
+	reg = readl_relaxed(vco->base + VCO_CTRL0);
+	if (vco->flags & BERLIN2_AVPLL_BIT_QUIRK)
+		reg |= VCO_POWERUP << 4;
+	else
+		reg |= VCO_POWERUP;
+	writel_relaxed(reg, vco->base + VCO_CTRL0);
+
+	return 0;
+}
+
+static void berlin2_avpll_vco_disable(struct clk_hw *hw)
+{
+	struct berlin2_avpll_vco *vco = to_avpll_vco(hw);
+	u32 reg;
+
+	reg = readl_relaxed(vco->base + VCO_CTRL0);
+	if (vco->flags & BERLIN2_AVPLL_BIT_QUIRK)
+		reg &= ~(VCO_POWERUP << 4);
+	else
+		reg &= ~VCO_POWERUP;
+	writel_relaxed(reg, vco->base + VCO_CTRL0);
+}
+
+static u8 vco_refdiv[] = { 1, 2, 4, 3 };
+
+static unsigned long
+berlin2_avpll_vco_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	struct berlin2_avpll_vco *vco = to_avpll_vco(hw);
+	u32 reg, refdiv, fbdiv;
+	u64 freq = parent_rate;
+
+	/* AVPLL VCO frequency: Fvco = (Fref / refdiv) * fbdiv */
+	reg = readl_relaxed(vco->base + VCO_CTRL1);
+	refdiv = (reg & VCO_REFDIV_MASK) >> VCO_REFDIV_SHIFT;
+	refdiv = vco_refdiv[refdiv];
+	fbdiv = (reg & VCO_FBDIV_MASK) >> VCO_FBDIV_SHIFT;
+	freq *= fbdiv;
+	do_div(freq, refdiv);
+
+	return (unsigned long)freq;
+}
+
+static const struct clk_ops berlin2_avpll_vco_ops = {
+	.is_enabled	= berlin2_avpll_vco_is_enabled,
+	.enable		= berlin2_avpll_vco_enable,
+	.disable	= berlin2_avpll_vco_disable,
+	.recalc_rate	= berlin2_avpll_vco_recalc_rate,
+};
+
+struct clk * __init berlin2_avpll_vco_register(void __iomem *base,
+			       const char *name, const char *parent_name,
+			       u8 vco_flags, unsigned long flags)
+{
+	struct berlin2_avpll_vco *vco;
+	struct clk_init_data init;
+
+	vco = kzalloc(sizeof(*vco), GFP_KERNEL);
+	if (!vco)
+		return ERR_PTR(-ENOMEM);
+
+	vco->base = base;
+	vco->flags = vco_flags;
+	vco->hw.init = &init;
+	init.name = name;
+	init.ops = &berlin2_avpll_vco_ops;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	init.flags = flags;
+
+	return clk_register(NULL, &vco->hw);
+}
+
+struct berlin2_avpll_channel {
+	struct clk_hw hw;
+	void __iomem *base;
+	u8 flags;
+	u8 index;
+};
+
+#define to_avpll_channel(hw) container_of(hw, struct berlin2_avpll_channel, hw)
+
+static int berlin2_avpll_channel_is_enabled(struct clk_hw *hw)
+{
+	struct berlin2_avpll_channel *ch = to_avpll_channel(hw);
+	u32 reg;
+
+	if (ch->index == 7)
+		return 1;
+
+	reg = readl_relaxed(ch->base + VCO_CTRL10);
+	reg &= VCO_POWERUP_CH1 << ch->index;
+
+	return !!reg;
+}
+
+static int berlin2_avpll_channel_enable(struct clk_hw *hw)
+{
+	struct berlin2_avpll_channel *ch = to_avpll_channel(hw);
+	u32 reg;
+
+	reg = readl_relaxed(ch->base + VCO_CTRL10);
+	reg |= VCO_POWERUP_CH1 << ch->index;
+	writel_relaxed(reg, ch->base + VCO_CTRL10);
+
+	return 0;
+}
+
+static void berlin2_avpll_channel_disable(struct clk_hw *hw)
+{
+	struct berlin2_avpll_channel *ch = to_avpll_channel(hw);
+	u32 reg;
+
+	reg = readl_relaxed(ch->base + VCO_CTRL10);
+	reg &= ~(VCO_POWERUP_CH1 << ch->index);
+	writel_relaxed(reg, ch->base + VCO_CTRL10);
+}
+
+static const u8 div_hdmi[] = { 1, 2, 4, 6 };
+static const u8 div_av1[] = { 1, 2, 5, 5 };
+
+static unsigned long
+berlin2_avpll_channel_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	struct berlin2_avpll_channel *ch = to_avpll_channel(hw);
+	u32 reg, div_av2, div_av3, divider = 1;
+	u64 freq = parent_rate;
+
+	reg = readl_relaxed(ch->base + VCO_CTRL30);
+	if ((reg & (VCO_DPLL_CH1_ENABLE << ch->index)) == 0)
+		goto skip_div;
+
+	/*
+	 * Fch = (Fref * sync2) /
+	 *    (sync1 * div_hdmi * div_av1 * div_av2 * div_av3)
+	 */
+
+	reg = readl_relaxed(ch->base + VCO_SYNC1n(ch->index));
+	/* BG2/BG2CDs SYNC1 reg on AVPLL_B channel 1 is shifted by 4 */
+	if (ch->flags & BERLIN2_AVPLL_BIT_QUIRK && ch->index == 0)
+		reg >>= 4;
+	divider = reg & VCO_SYNC1_MASK;
+
+	reg = readl_relaxed(ch->base + VCO_SYNC2n(ch->index));
+	freq *= reg & VCO_SYNC2_MASK;
+
+	/* Channel 8 has no dividers */
+	if (ch->index == 7)
+		goto skip_div;
+
+	/*
+	 * HDMI divider start at VCO_CTRL11, bit 7; MSB is enable, lower 2 bit
+	 * determine divider.
+	 */
+	reg = readl_relaxed(ch->base + VCO_CTRL11) >> 7;
+	reg = (reg >> (ch->index * 3));
+	if (reg & BIT(2))
+		divider *= div_hdmi[reg & 0x3];
+
+	/*
+	 * AV1 divider start at VCO_CTRL11, bit 28; MSB is enable, lower 2 bit
+	 * determine divider.
+	 */
+	if (ch->index == 0) {
+		reg = readl_relaxed(ch->base + VCO_CTRL11);
+		reg >>= 28;
+	} else {
+		reg = readl_relaxed(ch->base + VCO_CTRL12);
+		reg >>= (ch->index-1) * 3;
+	}
+	if (reg & BIT(2))
+		divider *= div_av1[reg & 0x3];
+
+	/*
+	 * AV2 divider start at VCO_CTRL12, bit 18; each 7 bits wide,
+	 * zero is not a valid value.
+	 */
+	if (ch->index < 2) {
+		reg = readl_relaxed(ch->base + VCO_CTRL12);
+		reg >>= 18 + (ch->index * 7);
+	} else if (ch->index < 7) {
+		reg = readl_relaxed(ch->base + VCO_CTRL13);
+		reg >>= (ch->index - 2) * 7;
+	} else {
+		reg = readl_relaxed(ch->base + VCO_CTRL14);
+	}
+	div_av2 = reg & 0x7f;
+	if (div_av2)
+		divider *= div_av2;
+
+	/*
+	 * AV3 divider start at VCO_CTRL14, bit 7; each 4 bits wide.
+	 * AV2/AV3 form a fractional divider, where only specfic values for AV3
+	 * are allowed. AV3 != 0 divides by AV2/2, AV3=0 is bypass.
+	 */
+	if (ch->index < 6) {
+		reg = readl_relaxed(ch->base + VCO_CTRL14);
+		reg >>= 7 + (ch->index * 4);
+	} else {
+		reg = readl_relaxed(ch->base + VCO_CTRL15);
+	}
+	div_av3 = reg & 0xf;
+	if (div_av2 && div_av3)
+		freq *= 2;
+
+skip_div:
+	do_div(freq, divider);
+	return (unsigned long)freq;
+}
+
+static const struct clk_ops berlin2_avpll_channel_ops = {
+	.is_enabled	= berlin2_avpll_channel_is_enabled,
+	.enable		= berlin2_avpll_channel_enable,
+	.disable	= berlin2_avpll_channel_disable,
+	.recalc_rate	= berlin2_avpll_channel_recalc_rate,
+};
+
+/*
+ * Another nice quirk:
+ * On some production SoCs, AVPLL channels are scrambled with respect
+ * to the channel numbering in the registers but still referenced by
+ * their original channel numbers. We deal with it by having a flag
+ * and a translation table for the index.
+ */
+static const u8 quirk_index[] __initconst = { 0, 6, 5, 4, 3, 2, 1, 7 };
+
+struct clk * __init berlin2_avpll_channel_register(void __iomem *base,
+			   const char *name, u8 index, const char *parent_name,
+			   u8 ch_flags, unsigned long flags)
+{
+	struct berlin2_avpll_channel *ch;
+	struct clk_init_data init;
+
+	ch = kzalloc(sizeof(*ch), GFP_KERNEL);
+	if (!ch)
+		return ERR_PTR(-ENOMEM);
+
+	ch->base = base;
+	if (ch_flags & BERLIN2_AVPLL_SCRAMBLE_QUIRK)
+		ch->index = quirk_index[index];
+	else
+		ch->index = index;
+
+	ch->flags = ch_flags;
+	ch->hw.init = &init;
+	init.name = name;
+	init.ops = &berlin2_avpll_channel_ops;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	init.flags = flags;
+
+	return clk_register(NULL, &ch->hw);
+}
diff --git a/drivers/clk/berlin/berlin2-avpll.h b/drivers/clk/berlin/berlin2-avpll.h
new file mode 100644
index 000000000000..a37f5068d299
--- /dev/null
+++ b/drivers/clk/berlin/berlin2-avpll.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 Marvell Technology Group Ltd.
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __BERLIN2_AVPLL_H
+#define __BERLIN2_AVPLL_H
+
+struct clk;
+
+#define BERLIN2_AVPLL_BIT_QUIRK		BIT(0)
+#define BERLIN2_AVPLL_SCRAMBLE_QUIRK	BIT(1)
+
+struct clk * __init
+berlin2_avpll_vco_register(void __iomem *base, const char *name,
+	   const char *parent_name, u8 vco_flags, unsigned long flags);
+
+struct clk * __init
+berlin2_avpll_channel_register(void __iomem *base, const char *name,
+		       u8 index, const char *parent_name, u8 ch_flags,
+		       unsigned long flags);
+
+#endif /* __BERLIN2_AVPLL_H */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 04/10] clk: berlin: add driver for BG2x simple PLLs
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
                   ` (2 preceding siblings ...)
  2014-05-19 16:43 ` [PATCH v2 03/10] clk: berlin: add driver for BG2x audio/video PLL Sebastian Hesselbarth
@ 2014-05-19 16:43 ` Sebastian Hesselbarth
  2014-05-19 16:43 ` [PATCH v2 05/10] clk: berlin: add driver for BG2x complex divider cells Sebastian Hesselbarth
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 16:43 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Alexandre Belloni, Mike Turquette, Jisheng Zhang,
	linux-arm-kernel, linux-kernel

From: Alexandre Belloni <alexandre.belloni@free-electrons.com>

This is a clock driver for the simple PLLs found on Berlin SoCs.
With repect to PLL registers and features, BG2/BG2CD and BG2Q are
slightly different, e.g. different allowed VCO dividers and bit
shifts.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- separate include for the PLL driver

Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/clk/berlin/Makefile      |   2 +-
 drivers/clk/berlin/berlin2-pll.c | 117 +++++++++++++++++++++++++++++++++++++++
 drivers/clk/berlin/berlin2-pll.h |  37 +++++++++++++
 3 files changed, 155 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/berlin/berlin2-pll.c
 create mode 100644 drivers/clk/berlin/berlin2-pll.h

diff --git a/drivers/clk/berlin/Makefile b/drivers/clk/berlin/Makefile
index 5905733fc7c7..9d3490e9782f 100644
--- a/drivers/clk/berlin/Makefile
+++ b/drivers/clk/berlin/Makefile
@@ -1 +1 @@
-obj-y += berlin2-avpll.o
+obj-y += berlin2-avpll.o berlin2-pll.o
diff --git a/drivers/clk/berlin/berlin2-pll.c b/drivers/clk/berlin/berlin2-pll.c
new file mode 100644
index 000000000000..bdc506b03824
--- /dev/null
+++ b/drivers/clk/berlin/berlin2-pll.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 Marvell Technology Group Ltd.
+ *
+ * Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <asm/div64.h>
+
+#include "berlin2-div.h"
+
+struct berlin2_pll_map {
+	const u8 vcodiv[16];
+	u8 mult;
+	u8 fbdiv_shift;
+	u8 rfdiv_shift;
+	u8 divsel_shift;
+};
+
+struct berlin2_pll {
+	struct clk_hw hw;
+	void __iomem *base;
+	struct berlin2_pll_map map;
+};
+
+#define to_berlin2_pll(hw) container_of(hw, struct berlin2_pll, hw)
+
+#define SPLL_CTRL0	0x00
+#define SPLL_CTRL1	0x04
+#define SPLL_CTRL2	0x08
+#define SPLL_CTRL3	0x0c
+#define SPLL_CTRL4	0x10
+
+#define FBDIV_MASK	0x1ff
+#define RFDIV_MASK	0x1f
+#define DIVSEL_MASK	0xf
+
+/*
+ * The output frequency formula for the pll is:
+ * clkout = fbdiv / refdiv * parent / vcodiv
+ */
+static unsigned long
+berlin2_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	struct berlin2_pll *pll = to_berlin2_pll(hw);
+	struct berlin2_pll_map *map = &pll->map;
+	u32 val, fbdiv, rfdiv, vcodivsel, vcodiv;
+	u64 rate = parent_rate;
+
+	val = readl_relaxed(pll->base + SPLL_CTRL0);
+	fbdiv = (val >> map->fbdiv_shift) & FBDIV_MASK;
+	rfdiv = (val >> map->rfdiv_shift) & RFDIV_MASK;
+	if (rfdiv == 0) {
+		pr_warn("%s has zero rfdiv\n", __clk_get_name(hw->clk));
+		rfdiv = 1;
+	}
+
+	val = readl_relaxed(pll->base + SPLL_CTRL1);
+	vcodivsel = (val >> map->divsel_shift) & DIVSEL_MASK;
+	vcodiv = map->vcodiv[vcodivsel];
+	if (vcodiv == 0) {
+		pr_warn("%s has zero vcodiv (index %d)\n",
+			__clk_get_name(hw->clk), vcodivsel);
+		vcodiv = 1;
+	}
+
+	rate *= fbdiv * map->mult;
+	do_div(rate, rfdiv * vcodiv);
+
+	return (unsigned long)rate;
+}
+
+static const struct clk_ops berlin2_pll_ops = {
+	.recalc_rate	= berlin2_pll_recalc_rate,
+};
+
+struct clk * __init
+berlin2_pll_register(const struct berlin2_pll_map *map,
+		     void __iomem *base, const char *name,
+		     const char *parent_name, unsigned long flags)
+{
+	struct clk_init_data init;
+	struct berlin2_pll *pll;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	/* copy pll_map to allow __initconst */
+	memcpy(&pll->map, map, sizeof(*map));
+	pll->base = base;
+	pll->hw.init = &init;
+	init.name = name;
+	init.ops = &berlin2_pll_ops;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	init.flags = flags;
+
+	return clk_register(NULL, &pll->hw);
+}
diff --git a/drivers/clk/berlin/berlin2-pll.h b/drivers/clk/berlin/berlin2-pll.h
new file mode 100644
index 000000000000..8831ce27ac1e
--- /dev/null
+++ b/drivers/clk/berlin/berlin2-pll.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Marvell Technology Group Ltd.
+ *
+ * Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __BERLIN2_PLL_H
+#define __BERLIN2_PLL_H
+
+struct clk;
+
+struct berlin2_pll_map {
+	const u8 vcodiv[16];
+	u8 mult;
+	u8 fbdiv_shift;
+	u8 rfdiv_shift;
+	u8 divsel_shift;
+};
+
+struct clk * __init
+berlin2_pll_register(const struct berlin2_pll_map *map,
+		     void __iomem *base, const char *name,
+		     const char *parent_name, unsigned long flags);
+
+#endif /* __BERLIN2_PLL_H */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 05/10] clk: berlin: add driver for BG2x complex divider cells
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
                   ` (3 preceding siblings ...)
  2014-05-19 16:43 ` [PATCH v2 04/10] clk: berlin: add driver for BG2x simple PLLs Sebastian Hesselbarth
@ 2014-05-19 16:43 ` Sebastian Hesselbarth
  2014-05-19 16:43 ` [PATCH v2 06/10] clk: berlin: add core clock driver for BG2/BG2CD Sebastian Hesselbarth
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 16:43 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Alexandre Belloni, Mike Turquette, Jisheng Zhang,
	linux-arm-kernel, linux-kernel

From: Alexandre Belloni <alexandre.belloni@free-electrons.com>

This is a driver for the complex divider cells found on Marvell Berlin2
SoCs. The cells come in two flavors: single register cells and shared
register cells.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- separate include for the DIV cell driver

Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/clk/berlin/Makefile      |   2 +-
 drivers/clk/berlin/berlin2-div.c | 265 +++++++++++++++++++++++++++++++++++++++
 drivers/clk/berlin/berlin2-div.h |  89 +++++++++++++
 3 files changed, 355 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/berlin/berlin2-div.c
 create mode 100644 drivers/clk/berlin/berlin2-div.h

diff --git a/drivers/clk/berlin/Makefile b/drivers/clk/berlin/Makefile
index 9d3490e9782f..f0a7dc8b5e30 100644
--- a/drivers/clk/berlin/Makefile
+++ b/drivers/clk/berlin/Makefile
@@ -1 +1 @@
-obj-y += berlin2-avpll.o berlin2-pll.o
+obj-y += berlin2-avpll.o berlin2-pll.o berlin2-div.o
diff --git a/drivers/clk/berlin/berlin2-div.c b/drivers/clk/berlin/berlin2-div.c
new file mode 100644
index 000000000000..81ff97f8aa0b
--- /dev/null
+++ b/drivers/clk/berlin/berlin2-div.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2014 Marvell Technology Group Ltd.
+ *
+ * Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "berlin2-div.h"
+
+/*
+ * Clock dividers in Berlin2 SoCs comprise a complex cell to select
+ * input pll and divider. The virtual structure as it is used in Marvell
+ * BSP code can be seen as:
+ *
+ *                      +---+
+ * pll0 --------------->| 0 |                   +---+
+ *           +---+      |(B)|--+--------------->| 0 |      +---+
+ * pll1.0 -->| 0 |  +-->| 1 |  |   +--------+   |(E)|----->| 0 |   +---+
+ * pll1.1 -->| 1 |  |   +---+  +-->|(C) 1:M |-->| 1 |      |(F)|-->|(G)|->
+ * ...    -->|(A)|--+          |   +--------+   +---+  +-->| 1 |   +---+
+ * ...    -->|   |             +-->|(D) 1:3 |----------+   +---+
+ * pll1.N -->| N |                 +---------
+ *           +---+
+ *
+ * (A) input pll clock mux controlled by               <PllSelect[1:n]>
+ * (B) input pll bypass mux controlled by              <PllSwitch>
+ * (C) programmable clock divider controlled by        <Select[1:n]>
+ * (D) constant div-by-3 clock divider
+ * (E) programmable clock divider bypass controlled by <Switch>
+ * (F) constant div-by-3 clock mux controlled by       <D3Switch>
+ * (G) clock gate controlled by                        <Enable>
+ *
+ * For whatever reason, above control signals come in two flavors:
+ * - single register dividers with all bits in one register
+ * - shared register dividers with bits spread over multiple registers
+ *   (including signals for the same cell spread over consecutive registers)
+ *
+ * Also, clock gate and pll mux is not available on every div cell, so
+ * we have to deal with those, too. We reuse common clock composite driver
+ * for it.
+ */
+
+#define PLL_SELECT_MASK	0x7
+#define DIV_SELECT_MASK	0x7
+
+struct berlin2_div {
+	struct clk_hw hw;
+	void __iomem *base;
+	struct berlin2_div_map map;
+	spinlock_t *lock;
+};
+
+#define to_berlin2_div(hw) container_of(hw, struct berlin2_div, hw)
+
+static u8 clk_div[] = { 1, 2, 4, 6, 8, 12, 1, 1 };
+
+static int berlin2_div_is_enabled(struct clk_hw *hw)
+{
+	struct berlin2_div *div = to_berlin2_div(hw);
+	struct berlin2_div_map *map = &div->map;
+	u32 reg;
+
+	if (div->lock)
+		spin_lock(div->lock);
+
+	reg = readl_relaxed(div->base + map->gate_offs);
+	reg >>= map->gate_shift;
+
+	if (div->lock)
+		spin_unlock(div->lock);
+
+	return (reg & 0x1);
+}
+
+static int berlin2_div_enable(struct clk_hw *hw)
+{
+	struct berlin2_div *div = to_berlin2_div(hw);
+	struct berlin2_div_map *map = &div->map;
+	u32 reg;
+
+	if (div->lock)
+		spin_lock(div->lock);
+
+	reg = readl_relaxed(div->base + map->gate_offs);
+	reg |= BIT(map->gate_shift);
+	writel_relaxed(reg, div->base + map->gate_offs);
+
+	if (div->lock)
+		spin_unlock(div->lock);
+
+	return 0;
+}
+
+static void berlin2_div_disable(struct clk_hw *hw)
+{
+	struct berlin2_div *div = to_berlin2_div(hw);
+	struct berlin2_div_map *map = &div->map;
+	u32 reg;
+
+	if (div->lock)
+		spin_lock(div->lock);
+
+	reg = readl_relaxed(div->base + map->gate_offs);
+	reg &= ~BIT(map->gate_shift);
+	writel_relaxed(reg, div->base + map->gate_offs);
+
+	if (div->lock)
+		spin_unlock(div->lock);
+}
+
+static int berlin2_div_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct berlin2_div *div = to_berlin2_div(hw);
+	struct berlin2_div_map *map = &div->map;
+	u32 reg;
+
+	if (div->lock)
+		spin_lock(div->lock);
+
+	/* index == 0 is PLL_SWITCH */
+	reg = readl_relaxed(div->base + map->pll_switch_offs);
+	if (index == 0)
+		reg &= ~BIT(map->pll_switch_shift);
+	else
+		reg |= BIT(map->pll_switch_shift);
+	writel_relaxed(reg, div->base + map->pll_switch_offs);
+
+	/* index > 0 is PLL_SELECT */
+	if (index > 0) {
+		reg = readl_relaxed(div->base + map->pll_select_offs);
+		reg &= ~(PLL_SELECT_MASK << map->pll_select_shift);
+		reg |= (index - 1) << map->pll_select_shift;
+		writel_relaxed(reg, div->base + map->pll_select_offs);
+	}
+
+	if (div->lock)
+		spin_unlock(div->lock);
+
+	return 0;
+}
+
+static u8 berlin2_div_get_parent(struct clk_hw *hw)
+{
+	struct berlin2_div *div = to_berlin2_div(hw);
+	struct berlin2_div_map *map = &div->map;
+	u32 reg;
+	u8 index = 0;
+
+	if (div->lock)
+		spin_lock(div->lock);
+
+	/* PLL_SWITCH == 0 is index 0 */
+	reg = readl_relaxed(div->base + map->pll_switch_offs);
+	reg &= BIT(map->pll_switch_shift);
+	if (reg) {
+		reg = readl_relaxed(div->base + map->pll_select_offs);
+		reg >>= map->pll_select_shift;
+		reg &= PLL_SELECT_MASK;
+		index = 1 + reg;
+	}
+
+	if (div->lock)
+		spin_unlock(div->lock);
+
+	return index;
+}
+
+static unsigned long berlin2_div_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	struct berlin2_div *div = to_berlin2_div(hw);
+	struct berlin2_div_map *map = &div->map;
+	u32 divsw, div3sw, divider = 1;
+
+	if (div->lock)
+		spin_lock(div->lock);
+
+	divsw = readl_relaxed(div->base + map->div_switch_offs) &
+		(1 << map->div_switch_shift);
+	div3sw = readl_relaxed(div->base + map->div3_switch_offs) &
+		(1 << map->div3_switch_shift);
+
+	/* constant divide-by-3 (dominant) */
+	if (div3sw != 0) {
+		divider = 3;
+	/* divider can be bypassed with DIV_SWITCH == 0 */
+	} else if (divsw == 0) {
+		divider = 1;
+	/* clock divider determined by DIV_SELECT */
+	} else {
+		u32 reg;
+		reg = readl_relaxed(div->base + map->div_select_offs);
+		reg >>= map->div_select_shift;
+		reg &= DIV_SELECT_MASK;
+		divider = clk_div[reg];
+	}
+
+	if (div->lock)
+		spin_unlock(div->lock);
+
+	return parent_rate / divider;
+}
+
+static const struct clk_ops berlin2_div_rate_ops = {
+	.recalc_rate	= berlin2_div_recalc_rate,
+};
+
+static const struct clk_ops berlin2_div_gate_ops = {
+	.is_enabled	= berlin2_div_is_enabled,
+	.enable		= berlin2_div_enable,
+	.disable	= berlin2_div_disable,
+};
+
+static const struct clk_ops berlin2_div_mux_ops = {
+	.set_parent	= berlin2_div_set_parent,
+	.get_parent	= berlin2_div_get_parent,
+};
+
+struct clk * __init
+berlin2_div_register(const struct berlin2_div_map *map,
+		     void __iomem *base, const char *name, u8 div_flags,
+		     const char **parent_names, int num_parents,
+		     unsigned long flags, spinlock_t *lock)
+{
+	const struct clk_ops *mux_ops = &berlin2_div_mux_ops;
+	const struct clk_ops *rate_ops = &berlin2_div_rate_ops;
+	const struct clk_ops *gate_ops = &berlin2_div_gate_ops;
+	struct berlin2_div *div;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	/* copy div_map to allow __initconst */
+	memcpy(&div->map, map, sizeof(*map));
+	div->base = base;
+	div->lock = lock;
+
+	if ((div_flags & BERLIN2_DIV_HAS_GATE) == 0)
+		gate_ops = NULL;
+	if ((div_flags & BERLIN2_DIV_HAS_MUX) == 0)
+		mux_ops = NULL;
+
+	return clk_register_composite(NULL, name, parent_names, num_parents,
+				      &div->hw, mux_ops, &div->hw, rate_ops,
+				      &div->hw, gate_ops, flags);
+}
diff --git a/drivers/clk/berlin/berlin2-div.h b/drivers/clk/berlin/berlin2-div.h
new file mode 100644
index 000000000000..15e3384f3116
--- /dev/null
+++ b/drivers/clk/berlin/berlin2-div.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 Marvell Technology Group Ltd.
+ *
+ * Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __BERLIN2_DIV_H
+#define __BERLIN2_DIV_H
+
+struct clk;
+
+#define BERLIN2_DIV_HAS_GATE		BIT(0)
+#define BERLIN2_DIV_HAS_MUX		BIT(1)
+
+#define BERLIN2_PLL_SELECT(_off, _sh)	\
+	.pll_select_offs = _off,	\
+	.pll_select_shift = _sh
+
+#define BERLIN2_PLL_SWITCH(_off, _sh)	\
+	.pll_switch_offs = _off,	\
+	.pll_switch_shift = _sh
+
+#define BERLIN2_DIV_SELECT(_off, _sh)	\
+	.div_select_offs = _off,	\
+	.div_select_shift = _sh
+
+#define BERLIN2_DIV_SWITCH(_off, _sh)	\
+	.div_switch_offs = _off,	\
+	.div_switch_shift = _sh
+
+#define BERLIN2_DIV_D3SWITCH(_off, _sh)	\
+	.div3_switch_offs = _off,	\
+	.div3_switch_shift = _sh
+
+#define BERLIN2_DIV_GATE(_off, _sh)	\
+	.gate_offs = _off,		\
+	.gate_shift = _sh
+
+#define BERLIN2_SINGLE_DIV(_off)	\
+	BERLIN2_DIV_GATE(_off, 0),	\
+	BERLIN2_PLL_SELECT(_off, 1),	\
+	BERLIN2_PLL_SWITCH(_off, 4),	\
+	BERLIN2_DIV_SWITCH(_off, 5),	\
+	BERLIN2_DIV_D3SWITCH(_off, 6),	\
+	BERLIN2_DIV_SELECT(_off, 7)
+
+struct berlin2_div_map {
+	u16 pll_select_offs;
+	u16 pll_switch_offs;
+	u16 div_select_offs;
+	u16 div_switch_offs;
+	u16 div3_switch_offs;
+	u16 gate_offs;
+	u8 pll_select_shift;
+	u8 pll_switch_shift;
+	u8 div_select_shift;
+	u8 div_switch_shift;
+	u8 div3_switch_shift;
+	u8 gate_shift;
+};
+
+struct berlin2_div_data {
+	const char *name;
+	const u8 *parent_ids;
+	int num_parents;
+	unsigned long flags;
+	struct berlin2_div_map map;
+	u8 div_flags;
+};
+
+struct clk * __init
+berlin2_div_register(const struct berlin2_div_map *map,
+	     void __iomem *base,  const char *name, u8 div_flags,
+	     const char **parent_names, int num_parents,
+	     unsigned long flags,  spinlock_t *lock);
+
+#endif /* __BERLIN2_DIV_H */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 06/10] clk: berlin: add core clock driver for BG2/BG2CD
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
                   ` (4 preceding siblings ...)
  2014-05-19 16:43 ` [PATCH v2 05/10] clk: berlin: add driver for BG2x complex divider cells Sebastian Hesselbarth
@ 2014-05-19 16:43 ` Sebastian Hesselbarth
  2014-05-19 21:06   ` Alexandre Belloni
  2014-05-19 16:43 ` [PATCH v2 07/10] clk: berlin: add core clock driver for BG2Q Sebastian Hesselbarth
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 16:43 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Mike Turquette, Alexandre Belloni, Jisheng Zhang,
	linux-arm-kernel, linux-kernel

This driver deals with the core clocks found on Marvell Berlin
BG2 and BG2CD. For the shared register dividers, make use of the
corresponding driver and add some single clock muxes and gates for
the rest.

Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- adapt to new single chip control node and compatible
- swallow twd clock node

Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/clk/berlin/Makefile |   2 +
 drivers/clk/berlin/bg2.c    | 691 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/berlin/common.h |  29 ++
 3 files changed, 722 insertions(+)
 create mode 100644 drivers/clk/berlin/bg2.c
 create mode 100644 drivers/clk/berlin/common.h

diff --git a/drivers/clk/berlin/Makefile b/drivers/clk/berlin/Makefile
index f0a7dc8b5e30..2b33e1e74503 100644
--- a/drivers/clk/berlin/Makefile
+++ b/drivers/clk/berlin/Makefile
@@ -1 +1,3 @@
 obj-y += berlin2-avpll.o berlin2-pll.o berlin2-div.o
+obj-$(CONFIG_MACH_BERLIN_BG2)	+= bg2.o
+obj-$(CONFIG_MACH_BERLIN_BG2CD)	+= bg2.o
diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c
new file mode 100644
index 000000000000..515fb133495c
--- /dev/null
+++ b/drivers/clk/berlin/bg2.c
@@ -0,0 +1,691 @@
+/*
+ * Copyright (c) 2014 Marvell Technology Group Ltd.
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/berlin2.h>
+
+#include "berlin2-avpll.h"
+#include "berlin2-div.h"
+#include "berlin2-pll.h"
+#include "common.h"
+
+#define REG_PINMUX0		0x0000
+#define REG_PINMUX1		0x0004
+#define REG_SYSPLLCTL0		0x0014
+#define REG_SYSPLLCTL4		0x0024
+#define REG_MEMPLLCTL0		0x0028
+#define REG_MEMPLLCTL4		0x0038
+#define REG_CPUPLLCTL0		0x003c
+#define REG_CPUPLLCTL4		0x004c
+#define REG_AVPLLCTL0		0x0050
+#define REG_AVPLLCTL31		0x00cc
+#define REG_AVPLLCTL62		0x0148
+#define REG_PLLSTATUS		0x014c
+#define REG_CLKENABLE		0x0150
+#define REG_CLKSELECT0		0x0154
+#define REG_CLKSELECT1		0x0158
+#define REG_CLKSELECT2		0x015c
+#define REG_CLKSELECT3		0x0160
+#define REG_CLKSWITCH0		0x0164
+#define REG_CLKSWITCH1		0x0168
+#define REG_RESET_TRIGGER	0x0178
+#define REG_RESET_STATUS0	0x017c
+#define REG_RESET_STATUS1	0x0180
+#define REG_SW_GENERIC0		0x0184
+#define REG_SW_GENERIC3		0x0190
+#define REG_PRODUCTID		0x01cc
+#define REG_PRODUCTID_EXT	0x01d0
+#define REG_GFX3DCORE_CLKCTL	0x022c
+#define REG_GFX3DSYS_CLKCTL	0x0230
+#define REG_ARC_CLKCTL		0x0234
+#define REG_VIP_CLKCTL		0x0238
+#define REG_SDIO0XIN_CLKCTL	0x023c
+#define REG_SDIO1XIN_CLKCTL	0x0240
+#define REG_GFX3DEXTRA_CLKCTL	0x0244
+#define REG_GFX3D_RESET		0x0248
+#define REG_GC360_CLKCTL	0x024c
+#define REG_SDIO_DLLMST_CLKCTL	0x0250
+
+/*
+ * BG2/BG2CD SoCs have the following audio/video I/O units:
+ *
+ * audiohd: HDMI TX audio
+ * audio0:  7.1ch TX
+ * audio1:  2ch TX
+ * audio2:  2ch RX
+ * audio3:  SPDIF TX
+ * video0:  HDMI video
+ * video1:  Secondary video
+ * video2:  SD auxiliary video
+ *
+ * There are no external audio clocks (ACLKI0, ACLKI1) and
+ * only one external video clock (VCLKI0).
+ *
+ * Currently missing bits and pieces:
+ * - audio_fast_pll is unknown
+ * - audiohd_pll is unknown
+ * - video0_pll is unknown
+ * - audio[023], audiohd parent pll is assumed to be audio_fast_pll
+ *
+ */
+
+#define	MAX_CLKS 41
+static struct clk *clks[MAX_CLKS];
+static struct clk_onecell_data clk_data;
+static DEFINE_SPINLOCK(lock);
+static void __iomem *gbase;
+
+enum {
+	REFCLK, VIDEO_EXT0,
+	SYSPLL, MEMPLL, CPUPLL,
+	AVPLL_A1, AVPLL_A2, AVPLL_A3, AVPLL_A4,
+	AVPLL_A5, AVPLL_A6, AVPLL_A7, AVPLL_A8,
+	AVPLL_B1, AVPLL_B2, AVPLL_B3, AVPLL_B4,
+	AVPLL_B5, AVPLL_B6, AVPLL_B7, AVPLL_B8,
+	AUDIO1_PLL, AUDIO_FAST_PLL,
+	VIDEO0_PLL, VIDEO0_IN,
+	VIDEO1_PLL, VIDEO1_IN,
+	VIDEO2_PLL, VIDEO2_IN,
+};
+
+static const char *clk_names[] = {
+	[REFCLK]		= "refclk",
+	[VIDEO_EXT0]		= "video_ext0",
+	[SYSPLL]		= "syspll",
+	[MEMPLL]		= "mempll",
+	[CPUPLL]		= "cpupll",
+	[AVPLL_A1]		= "avpll_a1",
+	[AVPLL_A2]		= "avpll_a2",
+	[AVPLL_A3]		= "avpll_a3",
+	[AVPLL_A4]		= "avpll_a4",
+	[AVPLL_A5]		= "avpll_a5",
+	[AVPLL_A6]		= "avpll_a6",
+	[AVPLL_A7]		= "avpll_a7",
+	[AVPLL_A8]		= "avpll_a8",
+	[AVPLL_B1]		= "avpll_b1",
+	[AVPLL_B2]		= "avpll_b2",
+	[AVPLL_B3]		= "avpll_b3",
+	[AVPLL_B4]		= "avpll_b4",
+	[AVPLL_B5]		= "avpll_b5",
+	[AVPLL_B6]		= "avpll_b6",
+	[AVPLL_B7]		= "avpll_b7",
+	[AVPLL_B8]		= "avpll_b8",
+	[AUDIO1_PLL]		= "audio1_pll",
+	[AUDIO_FAST_PLL]	= "audio_fast_pll",
+	[VIDEO0_PLL]		= "video0_pll",
+	[VIDEO0_IN]		= "video0_in",
+	[VIDEO1_PLL]		= "video1_pll",
+	[VIDEO1_IN]		= "video1_in",
+	[VIDEO2_PLL]		= "video2_pll",
+	[VIDEO2_IN]		= "video2_in",
+};
+
+static const struct berlin2_pll_map bg2_pll_map __initconst = {
+	.vcodiv		= {10, 15, 20, 25, 30, 40, 50, 60, 80},
+	.mult		= 10,
+	.fbdiv_shift	= 6,
+	.rfdiv_shift	= 1,
+	.divsel_shift	= 7,
+};
+
+static const u8 default_parent_ids[] = {
+	SYSPLL, AVPLL_B4, AVPLL_A5, AVPLL_B6, AVPLL_B7, SYSPLL
+};
+
+static const struct berlin2_div_data bg2_divs[] __initconst = {
+	{
+		.name = "sys",
+		.parent_ids = (const u8 []){
+			SYSPLL, AVPLL_B4, AVPLL_B5, AVPLL_B6, AVPLL_B7, SYSPLL
+		},
+		.num_parents = 6,
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 0),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 0),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 3),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 3),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 4),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 5),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = CLK_IGNORE_UNUSED,
+	},
+	{
+		.name = "cpu",
+		.parent_ids = (const u8 []){
+			CPUPLL, MEMPLL, MEMPLL, MEMPLL, MEMPLL
+		},
+		.num_parents = 5,
+		.map = {
+			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 6),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 9),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 6),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 7),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 8),
+		},
+		.div_flags = BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "drmfigo",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 16),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 17),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 20),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 12),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 13),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 14),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "cfg",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 1),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 23),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 26),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 15),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 16),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 17),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "gfx",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 4),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 29),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 0),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 18),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 19),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 20),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "zsp",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 5),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 3),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 6),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 21),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 22),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 23),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "perif",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 6),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 9),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 12),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 24),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 25),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 26),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = CLK_IGNORE_UNUSED,
+	},
+	{
+		.name = "pcube",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 2),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 15),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 18),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 27),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 28),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 29),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "vscope",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 3),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 21),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 24),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 30),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 31),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 0),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "nfc_ecc",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 18),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 27),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 0),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 1),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 2),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 3),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "vpp",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 21),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT2, 3),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 6),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 4),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 5),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 6),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "app",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 20),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT2, 9),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 12),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 7),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 8),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 9),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "audio0",
+		.parent_ids = (const u8 []){ AUDIO_FAST_PLL },
+		.num_parents = 1,
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 22),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 17),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 10),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 11),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE,
+		.flags = 0,
+	},
+	{
+		.name = "audio2",
+		.parent_ids = (const u8 []){ AUDIO_FAST_PLL },
+		.num_parents = 1,
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 24),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 20),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 14),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 15),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE,
+		.flags = 0,
+	},
+	{
+		.name = "audio3",
+		.parent_ids = (const u8 []){ AUDIO_FAST_PLL },
+		.num_parents = 1,
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 25),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 23),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 16),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 17),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE,
+		.flags = 0,
+	},
+	{
+		.name = "audio1",
+		.parent_ids = (const u8 []){ AUDIO1_PLL },
+		.num_parents = 1,
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 23),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT3, 0),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 12),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 13),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE,
+		.flags = 0,
+	},
+	{
+		.name = "gfx3d_core",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_SINGLE_DIV(REG_GFX3DCORE_CLKCTL),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "gfx3d_sys",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_SINGLE_DIV(REG_GFX3DSYS_CLKCTL),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "arc",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_SINGLE_DIV(REG_ARC_CLKCTL),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "vip",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_SINGLE_DIV(REG_VIP_CLKCTL),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "sdio0xin",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_SINGLE_DIV(REG_SDIO0XIN_CLKCTL),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "sdio1xin",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_SINGLE_DIV(REG_SDIO1XIN_CLKCTL),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "gfx3d_extra",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_SINGLE_DIV(REG_GFX3DEXTRA_CLKCTL),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "gc360",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_SINGLE_DIV(REG_GC360_CLKCTL),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "sdio_dllmst",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_SINGLE_DIV(REG_SDIO_DLLMST_CLKCTL),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+};
+
+static const struct berlin2_gate_data bg2_gates[] __initconst = {
+	{ "geth0",	"perif",	7 },
+	{ "geth1",	"perif",	8 },
+	{ "sata",	"perif",	9 },
+	{ "ahbapb",	"perif",	10, CLK_IGNORE_UNUSED },
+	{ "usb0",	"perif",	11 },
+	{ "usb1",	"perif",	12 },
+	{ "pbridge",	"perif",	13, CLK_IGNORE_UNUSED },
+	{ "sdio0",	"perif",	14, CLK_IGNORE_UNUSED },
+	{ "sdio1",	"perif",	15, CLK_IGNORE_UNUSED },
+	{ "nfc",	"perif",	17 },
+	{ "smemc",	"perif",	19 },
+	{ "audiohd",	"audiohd_pll",	26 },
+	{ "video0",	"video0_in",	27 },
+	{ "video1",	"video1_in",	28 },
+	{ "video2",	"video2_in",	29 },
+};
+
+static void __init berlin2_clock_setup(struct device_node *np)
+{
+	const char *parent_names[9];
+	struct clk *clk;
+	u8 avpll_flags = 0;
+	int n;
+
+	gbase = of_iomap(np, 0);
+	if (!gbase)
+		return;
+
+	/* overwrite default clock names with DT provided ones */
+	clk = of_clk_get_by_name(np, clk_names[REFCLK]);
+	if (!IS_ERR(clk)) {
+		clk_names[REFCLK] = __clk_get_name(clk);
+		clk_put(clk);
+	}
+
+	clk = of_clk_get_by_name(np, clk_names[VIDEO_EXT0]);
+	if (!IS_ERR(clk)) {
+		clk_names[VIDEO_EXT0] = __clk_get_name(clk);
+		clk_put(clk);
+	}
+
+	/* simple register PLLs */
+	clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0,
+				   clk_names[SYSPLL], clk_names[REFCLK], 0);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+
+	clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0,
+				   clk_names[MEMPLL], clk_names[REFCLK], 0);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+
+	clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0,
+				   clk_names[CPUPLL], clk_names[REFCLK], 0);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+
+	if (of_device_is_compatible(np, "marvell,berlin2-global-register"))
+		avpll_flags |= BERLIN2_AVPLL_SCRAMBLE_QUIRK;
+
+	/* audio/video VCOs */
+	clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA",
+			 clk_names[REFCLK], avpll_flags, 0);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+
+	for (n = 0; n < 8; n++) {
+		clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0,
+			     clk_names[AVPLL_A1 + n], n, "avpll_vcoA",
+			     avpll_flags, 0);
+		if (IS_ERR(clk))
+			goto bg2_fail;
+	}
+
+	clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB",
+				 clk_names[REFCLK], BERLIN2_AVPLL_BIT_QUIRK |
+				 avpll_flags, 0);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+
+	for (n = 0; n < 8; n++) {
+		clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31,
+			     clk_names[AVPLL_B1 + n], n, "avpll_vcoB",
+			     BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0);
+		if (IS_ERR(clk))
+			goto bg2_fail;
+	}
+
+	/* reference clock bypass switches */
+	parent_names[0] = clk_names[SYSPLL];
+	parent_names[1] = clk_names[REFCLK];
+	clk = clk_register_mux(NULL, "syspll_byp", parent_names, 2,
+			       0, gbase + REG_CLKSWITCH0, 0, 1, 0, &lock);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+	clk_names[SYSPLL] = __clk_get_name(clk);
+
+	parent_names[0] = clk_names[MEMPLL];
+	parent_names[1] = clk_names[REFCLK];
+	clk = clk_register_mux(NULL, "mempll_byp", parent_names, 2,
+			       0, gbase + REG_CLKSWITCH0, 1, 1, 0, &lock);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+	clk_names[MEMPLL] = __clk_get_name(clk);
+
+	parent_names[0] = clk_names[CPUPLL];
+	parent_names[1] = clk_names[REFCLK];
+	clk = clk_register_mux(NULL, "cpupll_byp", parent_names, 2,
+			       0, gbase + REG_CLKSWITCH0, 2, 1, 0, &lock);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+	clk_names[CPUPLL] = __clk_get_name(clk);
+
+	/* clock muxes */
+	parent_names[0] = clk_names[AVPLL_B3];
+	parent_names[1] = clk_names[AVPLL_A3];
+	clk = clk_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2,
+			       0, gbase + REG_CLKSELECT2, 29, 1, 0, &lock);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+
+	parent_names[0] = clk_names[VIDEO0_PLL];
+	parent_names[1] = clk_names[VIDEO_EXT0];
+	clk = clk_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2,
+			       0, gbase + REG_CLKSELECT3, 4, 1, 0, &lock);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+
+	parent_names[0] = clk_names[VIDEO1_PLL];
+	parent_names[1] = clk_names[VIDEO_EXT0];
+	clk = clk_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2,
+			       0, gbase + REG_CLKSELECT3, 6, 1, 0, &lock);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+
+	parent_names[0] = clk_names[AVPLL_A2];
+	parent_names[1] = clk_names[AVPLL_B2];
+	clk = clk_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2,
+			       0, gbase + REG_CLKSELECT3, 7, 1, 0, &lock);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+
+	parent_names[0] = clk_names[VIDEO2_PLL];
+	parent_names[1] = clk_names[VIDEO_EXT0];
+	clk = clk_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2,
+			       0, gbase + REG_CLKSELECT3, 9, 1, 0, &lock);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+
+	parent_names[0] = clk_names[AVPLL_B1];
+	parent_names[1] = clk_names[AVPLL_A5];
+	clk = clk_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2,
+			       0, gbase + REG_CLKSELECT3, 10, 1, 0, &lock);
+	if (IS_ERR(clk))
+		goto bg2_fail;
+
+	/* clock divider cells */
+	for (n = 0; n < ARRAY_SIZE(bg2_divs); n++) {
+		const struct berlin2_div_data *dd = &bg2_divs[n];
+		int k;
+
+		for (k = 0; k < dd->num_parents; k++)
+			parent_names[k] = clk_names[dd->parent_ids[k]];
+
+		clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
+				dd->name, dd->div_flags, parent_names,
+				dd->num_parents, dd->flags, &lock);
+	}
+
+	/* clock gate cells */
+	for (n = 0; n < ARRAY_SIZE(bg2_gates); n++) {
+		const struct berlin2_gate_data *gd = &bg2_gates[n];
+
+		clks[CLKID_GETH0 + n] = clk_register_gate(NULL, gd->name,
+			    gd->parent_name, gd->flags, gbase + REG_CLKENABLE,
+			    gd->bit_idx, 0, &lock);
+	}
+
+	/* twdclk is derived from cpu/3 */
+	clks[CLKID_TWD] =
+		clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
+
+	/* check for errors on leaf clocks */
+	for (n = 0; n < MAX_CLKS; n++) {
+		if (!IS_ERR(clks[n]))
+			continue;
+
+		pr_err("%s: Unable to register leaf clock %d\n",
+		       np->full_name, n);
+		goto bg2_fail;
+	}
+
+	/* register clk-provider */
+	clk_data.clks = clks;
+	clk_data.clk_num = MAX_CLKS;
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+	return;
+
+bg2_fail:
+	iounmap(gbase);
+}
+CLK_OF_DECLARE(berlin2_clock, "marvell,berlin2-chip-ctrl",
+	       berlin2_clock_setup);
+CLK_OF_DECLARE(berlin2cd_clock, "marvell,berlin2cd-chip-ctrl",
+	       berlin2_clock_setup);
diff --git a/drivers/clk/berlin/common.h b/drivers/clk/berlin/common.h
new file mode 100644
index 000000000000..bc68a14c4550
--- /dev/null
+++ b/drivers/clk/berlin/common.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 Marvell Technology Group Ltd.
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __BERLIN2_COMMON_H
+#define __BERLIN2_COMMON_H
+
+struct berlin2_gate_data {
+	const char *name;
+	const char *parent_name;
+	u8 bit_idx;
+	unsigned long flags;
+};
+
+#endif /* BERLIN2_COMMON_H */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 07/10] clk: berlin: add core clock driver for BG2Q
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
                   ` (5 preceding siblings ...)
  2014-05-19 16:43 ` [PATCH v2 06/10] clk: berlin: add core clock driver for BG2/BG2CD Sebastian Hesselbarth
@ 2014-05-19 16:43 ` Sebastian Hesselbarth
  2014-05-19 16:43 ` [PATCH v2 08/10] ARM: dts: berlin: convert BG2CD to DT clock nodes Sebastian Hesselbarth
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 16:43 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Alexandre Belloni, Mike Turquette, Jisheng Zhang,
	linux-arm-kernel, linux-kernel

From: Alexandre Belloni <alexandre.belloni@free-electrons.com>

This driver deals with the core clocks found on Marvell Berlin BG2Q. For the
shared register dividers, make use of the corresponding driver and add some
single clock muxes and gates for the rest.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
Changelog:
v1->v2:
- adapt to new single chip control node and compatible
- swallow twd clock node

Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/clk/berlin/Makefile |   1 +
 drivers/clk/berlin/bg2q.c   | 389 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 390 insertions(+)
 create mode 100644 drivers/clk/berlin/bg2q.c

diff --git a/drivers/clk/berlin/Makefile b/drivers/clk/berlin/Makefile
index 2b33e1e74503..2a36ab710a07 100644
--- a/drivers/clk/berlin/Makefile
+++ b/drivers/clk/berlin/Makefile
@@ -1,3 +1,4 @@
 obj-y += berlin2-avpll.o berlin2-pll.o berlin2-div.o
 obj-$(CONFIG_MACH_BERLIN_BG2)	+= bg2.o
 obj-$(CONFIG_MACH_BERLIN_BG2CD)	+= bg2.o
+obj-$(CONFIG_MACH_BERLIN_BG2Q)	+= bg2q.o
diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
new file mode 100644
index 000000000000..21784e4eb3f0
--- /dev/null
+++ b/drivers/clk/berlin/bg2q.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2014 Marvell Technology Group Ltd.
+ *
+ * Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/berlin2q.h>
+
+#include "berlin2-div.h"
+#include "berlin2-pll.h"
+#include "common.h"
+
+#define REG_PINMUX0		0x0018
+#define REG_PINMUX5		0x002c
+#define REG_SYSPLLCTL0		0x0030
+#define REG_SYSPLLCTL4		0x0040
+#define REG_CLKENABLE		0x00e8
+#define REG_CLKSELECT0		0x00ec
+#define REG_CLKSELECT1		0x00f0
+#define REG_CLKSELECT2		0x00f4
+#define REG_CLKSWITCH0		0x00f8
+#define REG_CLKSWITCH1		0x00fc
+#define REG_SW_GENERIC0		0x0110
+#define REG_SW_GENERIC3		0x011c
+#define REG_SDIO0XIN_CLKCTL	0x0158
+#define REG_SDIO1XIN_CLKCTL	0x015c
+
+#define	MAX_CLKS 27
+static struct clk *clks[MAX_CLKS];
+static struct clk_onecell_data clk_data;
+static DEFINE_SPINLOCK(lock);
+static void __iomem *gbase;
+static void __iomem *cpupll_base;
+
+enum {
+	REFCLK,
+	SYSPLL, CPUPLL,
+	AVPLL_B1, AVPLL_B2, AVPLL_B3, AVPLL_B4,
+	AVPLL_B5, AVPLL_B6, AVPLL_B7, AVPLL_B8,
+};
+
+static const char *clk_names[] = {
+	[REFCLK]		= "refclk",
+	[SYSPLL]		= "syspll",
+	[CPUPLL]		= "cpupll",
+	[AVPLL_B1]		= "avpll_b1",
+	[AVPLL_B2]		= "avpll_b2",
+	[AVPLL_B3]		= "avpll_b3",
+	[AVPLL_B4]		= "avpll_b4",
+	[AVPLL_B5]		= "avpll_b5",
+	[AVPLL_B6]		= "avpll_b6",
+	[AVPLL_B7]		= "avpll_b7",
+	[AVPLL_B8]		= "avpll_b8",
+};
+
+static const struct berlin2_pll_map bg2q_pll_map __initconst = {
+	.vcodiv		= {1, 0, 2, 0, 3, 4, 0, 6, 8},
+	.mult		= 1,
+	.fbdiv_shift	= 7,
+	.rfdiv_shift	= 2,
+	.divsel_shift	= 9,
+};
+
+static const u8 default_parent_ids[] = {
+	SYSPLL, AVPLL_B4, AVPLL_B5, AVPLL_B6, AVPLL_B7, SYSPLL
+};
+
+static const struct berlin2_div_data bg2q_divs[] __initconst = {
+	{
+		.name = "sys",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 0),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 0),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 3),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 3),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 4),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 5),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = CLK_IGNORE_UNUSED,
+	},
+	{
+		.name = "drmfigo",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 17),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 6),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 9),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 6),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 7),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 8),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "cfg",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 1),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 12),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 15),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 9),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 10),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 11),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "gfx2d",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 4),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 18),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 21),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 12),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 13),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 14),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "zsp",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 6),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 24),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 27),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 15),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 16),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 17),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "perif",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 7),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 0),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 3),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 18),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 19),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 20),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = CLK_IGNORE_UNUSED,
+	},
+	{
+		.name = "pcube",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 2),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 6),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 9),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 21),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 22),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 23),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "vscope",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 3),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 12),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 15),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 24),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 25),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 26),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "nfc_ecc",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 19),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 18),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 21),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 27),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 28),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 29),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "vpp",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 21),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 24),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 27),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 30),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 31),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 0),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "app",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_DIV_GATE(REG_CLKENABLE, 20),
+			BERLIN2_PLL_SELECT(REG_CLKSELECT2, 0),
+			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 3),
+			BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 1),
+			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 2),
+			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 3),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "sdio0xin",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_SINGLE_DIV(REG_SDIO0XIN_CLKCTL),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+	{
+		.name = "sdio1xin",
+		.parent_ids = default_parent_ids,
+		.num_parents = ARRAY_SIZE(default_parent_ids),
+		.map = {
+			BERLIN2_SINGLE_DIV(REG_SDIO1XIN_CLKCTL),
+		},
+		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
+		.flags = 0,
+	},
+};
+
+static const struct berlin2_gate_data bg2q_gates[] __initconst = {
+	{ "gfx2daxi",	"perif",	5 },
+	{ "geth0",	"perif",	8 },
+	{ "sata",	"perif",	9 },
+	{ "ahbapb",	"perif",	10, CLK_IGNORE_UNUSED },
+	{ "usb0",	"perif",	11 },
+	{ "usb1",	"perif",	12 },
+	{ "usb2",	"perif",	13 },
+	{ "usb3",	"perif",	14 },
+	{ "pbridge",	"perif",	15, CLK_IGNORE_UNUSED },
+	{ "sdio",	"perif",	16, CLK_IGNORE_UNUSED },
+	{ "nfc",	"perif",	18 },
+	{ "smemc",	"perif",	19 },
+	{ "pcie",	"perif",	22 },
+};
+
+static void __init berlin2q_clock_setup(struct device_node *np)
+{
+	const char *parent_names[9];
+	struct clk *clk;
+	int n;
+
+	gbase = of_iomap(np, 0);
+	if (!gbase) {
+		pr_err("%s: Unable to map global base\n", np->full_name);
+		return;
+	}
+
+	/* BG2Q CPU PLL is not part of global registers */
+	cpupll_base = of_iomap(np, 1);
+	if (!cpupll_base) {
+		pr_err("%s: Unable to map cpupll base\n", np->full_name);
+		iounmap(gbase);
+		return;
+	}
+
+	/* overwrite default clock names with DT provided ones */
+	clk = of_clk_get_by_name(np, clk_names[REFCLK]);
+	if (!IS_ERR(clk)) {
+		clk_names[REFCLK] = __clk_get_name(clk);
+		clk_put(clk);
+	}
+
+	/* simple register PLLs */
+	clk = berlin2_pll_register(&bg2q_pll_map, gbase + REG_SYSPLLCTL0,
+				   clk_names[SYSPLL], clk_names[REFCLK], 0);
+	if (IS_ERR(clk))
+		goto bg2q_fail;
+
+	clk = berlin2_pll_register(&bg2q_pll_map, cpupll_base,
+				   clk_names[CPUPLL], clk_names[REFCLK], 0);
+	if (IS_ERR(clk))
+		goto bg2q_fail;
+
+	/* TODO: add BG2Q AVPLL */
+
+	/*
+	 * TODO: add reference clock bypass switches:
+	 * memPLLSWBypass, cpuPLLSWBypass, and sysPLLSWBypass
+	 */
+
+	/* clock divider cells */
+	for (n = 0; n < ARRAY_SIZE(bg2q_divs); n++) {
+		const struct berlin2_div_data *dd = &bg2q_divs[n];
+		int k;
+
+		for (k = 0; k < dd->num_parents; k++)
+			parent_names[k] = clk_names[dd->parent_ids[k]];
+
+		clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
+				dd->name, dd->div_flags, parent_names,
+				dd->num_parents, dd->flags, &lock);
+	}
+
+	/* clock gate cells */
+	for (n = 0; n < ARRAY_SIZE(bg2q_gates); n++) {
+		const struct berlin2_gate_data *gd = &bg2q_gates[n];
+
+		clks[CLKID_GFX2DAXI + n] = clk_register_gate(NULL, gd->name,
+			    gd->parent_name, gd->flags, gbase + REG_CLKENABLE,
+			    gd->bit_idx, 0, &lock);
+	}
+
+	/*
+	 * twdclk is derived from cpu/3
+	 * TODO: use cpupll until cpuclk is not available
+	 */
+	clks[CLKID_TWD] =
+		clk_register_fixed_factor(NULL, "twd", clk_names[CPUPLL],
+					  0, 1, 3);
+
+	/* check for errors on leaf clocks */
+	for (n = 0; n < MAX_CLKS; n++) {
+		if (!IS_ERR(clks[n]))
+			continue;
+
+		pr_err("%s: Unable to register leaf clock %d\n",
+		       np->full_name, n);
+		goto bg2q_fail;
+	}
+
+	/* register clk-provider */
+	clk_data.clks = clks;
+	clk_data.clk_num = MAX_CLKS;
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+	return;
+
+bg2q_fail:
+	iounmap(cpupll_base);
+	iounmap(gbase);
+}
+CLK_OF_DECLARE(berlin2q_clock, "marvell,berlin2q-chip-ctrl",
+	       berlin2q_clock_setup);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 08/10] ARM: dts: berlin: convert BG2CD to DT clock nodes
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
                   ` (6 preceding siblings ...)
  2014-05-19 16:43 ` [PATCH v2 07/10] clk: berlin: add core clock driver for BG2Q Sebastian Hesselbarth
@ 2014-05-19 16:43 ` Sebastian Hesselbarth
  2014-05-19 21:07   ` Alexandre Belloni
  2014-05-19 16:43 ` [PATCH v2 09/10] ARM: dts: berlin: convert BG2 " Sebastian Hesselbarth
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 16:43 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Mike Turquette, Alexandre Belloni, Jisheng Zhang,
	linux-arm-kernel, linux-kernel

This converts Berlin BG2CD SoC dtsi to make use of the new DT clock
nodes for Berlin SoCs. Also add a binding include to ease core clock
references.

Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- adapt to new single chip control node and compatible

Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 arch/arm/boot/dts/berlin2cd.dtsi | 53 ++++++++++++++++++----------------------
 1 file changed, 24 insertions(+), 29 deletions(-)

diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
index 6eb1bdae23ac..1385caa6d029 100644
--- a/arch/arm/boot/dts/berlin2cd.dtsi
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -12,6 +12,7 @@
  */
 
 #include "skeleton.dtsi"
+#include <dt-bindings/clock/berlin2.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
 / {
@@ -30,24 +31,10 @@
 		};
 	};
 
-	clocks {
-		smclk: sysmgr-clock {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <25000000>;
-		};
-
-		cfgclk: cfg-clock {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <75000000>;
-		};
-
-		sysclk: system-clock {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <300000000>;
-		};
+	refclk: oscillator {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
 	};
 
 	soc {
@@ -76,7 +63,7 @@
 			compatible = "arm,cortex-a9-twd-timer";
 			reg = <0xad0600 0x20>;
 			interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&sysclk>;
+			clocks = <&chip CLKID_TWD>;
 		};
 
 		apb@e80000 {
@@ -163,7 +150,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c00 0x14>;
 				interrupts = <8>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "okay";
 			};
@@ -172,7 +159,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c14 0x14>;
 				interrupts = <9>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "okay";
 			};
@@ -181,7 +168,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c28 0x14>;
 				interrupts = <10>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -190,7 +177,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c3c 0x14>;
 				interrupts = <11>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -199,7 +186,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c50 0x14>;
 				interrupts = <12>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -208,7 +195,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c64 0x14>;
 				interrupts = <13>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -217,7 +204,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c78 0x14>;
 				interrupts = <14>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -226,7 +213,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c8c 0x14>;
 				interrupts = <15>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -241,6 +228,14 @@
 			};
 		};
 
+		chip: chip-control@ea0000 {
+			compatible = "marvell,berlin2cd-chip-ctrl";
+			#clock-cells = <1>;
+			reg = <0xea0000 0x400>;
+			clocks = <&refclk>;
+			clock-names = "refclk";
+		};
+
 		apb@fc0000 {
 			compatible = "simple-bus";
 			#address-cells = <1>;
@@ -285,7 +280,7 @@
 				reg-shift = <2>;
 				reg-io-width = <1>;
 				interrupts = <8>;
-				clocks = <&smclk>;
+				clocks = <&refclk>;
 				status = "disabled";
 			};
 
@@ -295,7 +290,7 @@
 				reg-shift = <2>;
 				reg-io-width = <1>;
 				interrupts = <9>;
-				clocks = <&smclk>;
+				clocks = <&refclk>;
 				status = "disabled";
 			};
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 09/10] ARM: dts: berlin: convert BG2 to DT clock nodes
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
                   ` (7 preceding siblings ...)
  2014-05-19 16:43 ` [PATCH v2 08/10] ARM: dts: berlin: convert BG2CD to DT clock nodes Sebastian Hesselbarth
@ 2014-05-19 16:43 ` Sebastian Hesselbarth
  2014-05-19 21:13   ` Alexandre Belloni
  2014-05-19 16:43 ` [PATCH v2 10/10] ARM: dts: berlin: convert BG2Q " Sebastian Hesselbarth
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 16:43 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Mike Turquette, Alexandre Belloni, Jisheng Zhang,
	linux-arm-kernel, linux-kernel

This converts Berlin BG2 SoC dtsi to make use of the new DT clock
nodes for Berlin SoCs. While at it, also fix up twdclk which is
running at cpuclk/3 instead of sysclk.

Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- adapt to new single chip control node and compatible

Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 arch/arm/boot/dts/berlin2.dtsi | 56 +++++++++++++++++-------------------------
 1 file changed, 23 insertions(+), 33 deletions(-)

diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
index 57cadd31f4e1..591d4b8c1c2b 100644
--- a/arch/arm/boot/dts/berlin2.dtsi
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -12,6 +12,7 @@
  */
 
 #include "skeleton.dtsi"
+#include <dt-bindings/clock/berlin2.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
 / {
@@ -37,24 +38,10 @@
 		};
 	};
 
-	clocks {
-		smclk: sysmgr-clock {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <25000000>;
-		};
-
-		cfgclk: cfg-clock {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <100000000>;
-		};
-
-		sysclk: system-clock {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <400000000>;
-		};
+	refclk: oscillator {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
 	};
 
 	soc {
@@ -88,7 +75,7 @@
 			compatible = "arm,cortex-a9-twd-timer";
 			reg = <0xad0600 0x20>;
 			interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&sysclk>;
+			clocks = <&chip CLKID_TWD>;
 		};
 
 		apb@e80000 {
@@ -175,7 +162,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c00 0x14>;
 				interrupts = <8>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "okay";
 			};
@@ -184,7 +171,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c14 0x14>;
 				interrupts = <9>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "okay";
 			};
@@ -193,7 +180,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c28 0x14>;
 				interrupts = <10>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -202,7 +189,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c3c 0x14>;
 				interrupts = <11>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -211,7 +198,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c50 0x14>;
 				interrupts = <12>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -220,7 +207,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c64 0x14>;
 				interrupts = <13>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -229,7 +216,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c78 0x14>;
 				interrupts = <14>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -238,7 +225,7 @@
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c8c 0x14>;
 				interrupts = <15>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -253,9 +240,12 @@
 			};
 		};
 
-		generic-regs@ea0184 {
-			compatible = "marvell,berlin-generic-regs", "syscon";
-			reg = <0xea0184 0x10>;
+		chip: chip-control@ea0000 {
+			compatible = "marvell,berlin2-chip-ctrl";
+			#clock-cells = <1>;
+			reg = <0xea0000 0x400>;
+			clocks = <&refclk>;
+			clock-names = "refclk";
 		};
 
 		apb@fc0000 {
@@ -305,7 +295,7 @@
 				reg-shift = <2>;
 				reg-io-width = <1>;
 				interrupts = <8>;
-				clocks = <&smclk>;
+				clocks = <&refclk>;
 				status = "disabled";
 			};
 
@@ -315,7 +305,7 @@
 				reg-shift = <2>;
 				reg-io-width = <1>;
 				interrupts = <9>;
-				clocks = <&smclk>;
+				clocks = <&refclk>;
 				status = "disabled";
 			};
 
@@ -325,7 +315,7 @@
 				reg-shift = <2>;
 				reg-io-width = <1>;
 				interrupts = <10>;
-				clocks = <&smclk>;
+				clocks = <&refclk>;
 				status = "disabled";
 			};
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 10/10] ARM: dts: berlin: convert BG2Q to DT clock nodes
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
                   ` (8 preceding siblings ...)
  2014-05-19 16:43 ` [PATCH v2 09/10] ARM: dts: berlin: convert BG2 " Sebastian Hesselbarth
@ 2014-05-19 16:43 ` Sebastian Hesselbarth
  2014-05-19 19:46 ` [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
  2014-05-29  0:07 ` Mike Turquette
  11 siblings, 0 replies; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 16:43 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Alexandre Belloni, Mike Turquette, Jisheng Zhang,
	linux-arm-kernel, linux-kernel

From: Alexandre Belloni <alexandre.belloni@free-electrons.com>

This converts Berlin BG2Q SoC dtsi to make use of the new DT clock
nodes for Berlin SoCs.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Changelog:
v1->v2:
- adapt to new single chip control node and compatible

Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 arch/arm/boot/dts/berlin2q.dtsi | 54 +++++++++++++++--------------------------
 1 file changed, 19 insertions(+), 35 deletions(-)

diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index 52c7d644e492..cd3287c95f1a 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -6,6 +6,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <dt-bindings/clock/berlin2q.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
 #include "skeleton.dtsi"
@@ -47,32 +48,12 @@
 		};
 	};
 
-	smclk: sysmgr-clock {
+	refclk: oscillator {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <25000000>;
 	};
 
-	cfgclk: config-clock {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <100000000>;
-	};
-
-	cpuclk: cpu-clock {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <1200000000>;
-	};
-
-	twdclk: twdclk {
-		compatible = "fixed-factor-clock";
-		#clock-cells = <0>;
-		clocks = <&cpuclk>;
-		clock-mult = <1>;
-		clock-div = <3>;
-	};
-
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -95,7 +76,7 @@
 		local-timer@ad0600 {
 			compatible = "arm,cortex-a9-twd-timer";
 			reg = <0xad0600 0x20>;
-			clocks = <&twdclk>;
+			clocks = <&chip CLKID_TWD>;
 			interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
@@ -189,7 +170,7 @@
 			timer0: timer@2c00 {
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c00 0x14>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				interrupts = <8>;
 			};
@@ -197,7 +178,7 @@
 			timer1: timer@2c14 {
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c14 0x14>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -205,7 +186,7 @@
 			timer2: timer@2c28 {
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c28 0x14>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -213,7 +194,7 @@
 			timer3: timer@2c3c {
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c3c 0x14>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -221,7 +202,7 @@
 			timer4: timer@2c50 {
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c50 0x14>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -229,7 +210,7 @@
 			timer5: timer@2c64 {
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c64 0x14>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -237,7 +218,7 @@
 			timer6: timer@2c78 {
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c78 0x14>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -245,7 +226,7 @@
 			timer7: timer@2c8c {
 				compatible = "snps,dw-apb-timer";
 				reg = <0x2c8c 0x14>;
-				clocks = <&cfgclk>;
+				clocks = <&chip CLKID_CFG>;
 				clock-names = "timer";
 				status = "disabled";
 			};
@@ -290,9 +271,12 @@
 			};
 		};
 
-		generic-regs@ea0110 {
-			compatible = "marvell,berlin-generic-regs", "syscon";
-			reg = <0xea0110 0x10>;
+		chip: chip-control@ea0000 {
+			compatible = "marvell,berlin2q-chip-ctrl";
+			#clock-cells = <1>;
+			reg = <0xea0000 0x400>, <0xdd0170 0x10>;
+			clocks = <&refclk>;
+			clock-names = "refclk";
 		};
 
 		apb@fc0000 {
@@ -308,7 +292,7 @@
 				reg = <0x9000 0x100>;
 				interrupt-parent = <&sic>;
 				interrupts = <8>;
-				clocks = <&smclk>;
+				clocks = <&refclk>;
 				reg-shift = <2>;
 				status = "disabled";
 			};
@@ -318,7 +302,7 @@
 				reg = <0xa000 0x100>;
 				interrupt-parent = <&sic>;
 				interrupts = <9>;
-				clocks = <&smclk>;
+				clocks = <&refclk>;
 				reg-shift = <2>;
 				status = "disabled";
 			};
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 00/10] Marvell Berlin full clock support
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
                   ` (9 preceding siblings ...)
  2014-05-19 16:43 ` [PATCH v2 10/10] ARM: dts: berlin: convert BG2Q " Sebastian Hesselbarth
@ 2014-05-19 19:46 ` Sebastian Hesselbarth
  2014-05-29  0:07 ` Mike Turquette
  11 siblings, 0 replies; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-19 19:46 UTC (permalink / raw)
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Mike Turquette, Alexandre Belloni, Jisheng Zhang,
	devicetree, linux-doc, linux-arm-kernel, linux-kernel

On 05/19/2014 06:43 PM, Sebastian Hesselbarth wrote:
> Mike,
> 
> this is v2 of the Berlin SoC clock driver [1] but with a reworked DT
> binding as requested [2]. We decided to not even try to split up the chip
> control registers that deal with pinmux, padmux, clock, reset, and evil
> stuff we haven't even looked at. Instead we keep a single node that clock
> driver will remap early, while proper platform_drivers use a regmap
> instead. Although clock and other drivers share the same register range,
> they use individual registers exclusively.
> 
> There are some functional fixes in the single clock drivers, I noticed
> while retesting each individial driver. There will be more to fixup but
> without any drivers actually using the clocks, it is hard to tell what
> isn't working now.
> 
> Anyway, the current binding should match what you requested and having
> a clock driver for v3.16 will really be a huge benefit for us to work
> on more driver support.
> 
> If you are fine with it, please take patches 2-7 and I'll pick up
> 1,8-10 in berlin branch.

nit: I also take patch 2 as it is the required DT include. Makes 3-7
to pick up for you.

Sebastian

> [1] https://lkml.kernel.org/r/1399839881-29895-1-git-send-email-sebastian.hesselbarth@gmail.com
> [2] https://lkml.kernel.org/r/20140515044106.19795.57249@quantum
> 
> Alexandre Belloni (4):
>   clk: berlin: add driver for BG2x simple PLLs
>   clk: berlin: add driver for BG2x complex divider cells
>   clk: berlin: add core clock driver for BG2Q
>   ARM: dts: berlin: convert BG2Q to DT clock nodes
> 
> Sebastian Hesselbarth (6):
>   dt-binding: ARM: add clock binding docs for Marvell Berlin2 SoCs
>   clk: berlin: add binding include for Berlin SoC clock ids
>   clk: berlin: add driver for BG2x audio/video PLL
>   clk: berlin: add core clock driver for BG2/BG2CD
>   ARM: dts: berlin: convert BG2CD to DT clock nodes
>   ARM: dts: berlin: convert BG2 to DT clock nodes
> 
>  .../devicetree/bindings/arm/marvell,berlin.txt     |  47 ++
>  arch/arm/boot/dts/berlin2.dtsi                     |  56 +-
>  arch/arm/boot/dts/berlin2cd.dtsi                   |  53 +-
>  arch/arm/boot/dts/berlin2q.dtsi                    |  54 +-
>  drivers/clk/Makefile                               |   1 +
>  drivers/clk/berlin/Makefile                        |   4 +
>  drivers/clk/berlin/berlin2-avpll.c                 | 393 ++++++++++++
>  drivers/clk/berlin/berlin2-avpll.h                 |  36 ++
>  drivers/clk/berlin/berlin2-div.c                   | 265 ++++++++
>  drivers/clk/berlin/berlin2-div.h                   |  89 +++
>  drivers/clk/berlin/berlin2-pll.c                   | 117 ++++
>  drivers/clk/berlin/berlin2-pll.h                   |  37 ++
>  drivers/clk/berlin/bg2.c                           | 691 +++++++++++++++++++++
>  drivers/clk/berlin/bg2q.c                          | 389 ++++++++++++
>  drivers/clk/berlin/common.h                        |  29 +
>  include/dt-bindings/clock/berlin2.h                |  45 ++
>  include/dt-bindings/clock/berlin2q.h               |  31 +
>  17 files changed, 2240 insertions(+), 97 deletions(-)
>  create mode 100644 drivers/clk/berlin/Makefile
>  create mode 100644 drivers/clk/berlin/berlin2-avpll.c
>  create mode 100644 drivers/clk/berlin/berlin2-avpll.h
>  create mode 100644 drivers/clk/berlin/berlin2-div.c
>  create mode 100644 drivers/clk/berlin/berlin2-div.h
>  create mode 100644 drivers/clk/berlin/berlin2-pll.c
>  create mode 100644 drivers/clk/berlin/berlin2-pll.h
>  create mode 100644 drivers/clk/berlin/bg2.c
>  create mode 100644 drivers/clk/berlin/bg2q.c
>  create mode 100644 drivers/clk/berlin/common.h
>  create mode 100644 include/dt-bindings/clock/berlin2.h
>  create mode 100644 include/dt-bindings/clock/berlin2q.h
> 
> ---
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
> Cc: Kumar Gala <galak@codeaurora.org>
> Cc: Randy Dunlap <rdunlap@infradead.org>
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> Cc: Jisheng Zhang <jszhang@marvell.com>
> Cc: devicetree@vger.kernel.org
> Cc: linux-doc@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 01/10] dt-binding: ARM: add clock binding docs for Marvell Berlin2 SoCs
  2014-05-19 16:43 ` [PATCH v2 01/10] dt-binding: ARM: add clock binding docs for Marvell Berlin2 SoCs Sebastian Hesselbarth
@ 2014-05-19 21:05   ` Alexandre Belloni
  0 siblings, 0 replies; 19+ messages in thread
From: Alexandre Belloni @ 2014-05-19 21:05 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Mike Turquette, Jisheng Zhang, devicetree,
	linux-doc, linux-arm-kernel, linux-kernel

On 19/05/2014 at 18:43:22 +0200, Sebastian Hesselbarth wrote :
> This adds mandatory device tree binding documentation for the clock related
> IP found on Marvell Berlin2 (BG2, BG2CD, and BG2Q) SoCs to the Berlin SoC
> binding documentation.
> 
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>

Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> ---
> Changelog:
> v1->v2:
> - typo fixed (Reported by Alexandre Belloni)
> - reworked binding to not represent individual clocks but chip control
>   IP/registers instead (Suggested by Mike Turquette)
> - dropped clock indices, refer to the include instead (Requested by Mike
>   Turquette)
> - moved the documentation from bindings/clock to Marvell Berlin SoC
>   binding, as there will be more functions (e.g. pinctrl) to describe
> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
> Cc: Kumar Gala <galak@codeaurora.org>
> Cc: Randy Dunlap <rdunlap@infradead.org>
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> Cc: Jisheng Zhang <jszhang@marvell.com>
> Cc: devicetree@vger.kernel.org
> Cc: linux-doc@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> ---
>  .../devicetree/bindings/arm/marvell,berlin.txt     | 47 ++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/marvell,berlin.txt b/Documentation/devicetree/bindings/arm/marvell,berlin.txt
> index 0677003e1476..744a7ea569d4 100644
> --- a/Documentation/devicetree/bindings/arm/marvell,berlin.txt
> +++ b/Documentation/devicetree/bindings/arm/marvell,berlin.txt
> @@ -23,3 +23,50 @@ SoC and board used. Currently known SoC compatibles are:
>  
>  	...
>  }
> +
> +* Marvell Berlin2 chip control binding
> +
> +Marvell Berlin SoCs have a chip control register set providing several
> +individual registers dealing with pinmux, padmux, clock, reset, and secondary
> +CPU boot address. Unfortunately, the individual registers are spread among the
> +chip control registers, so there should be a single DT node only providing the
> +different functions which are described below.
> +
> +Required properties:
> +- compatible: shall be one of
> +	"marvell,berlin2-chip-ctrl" for BG2
> +	"marvell,berlin2cd-chip-ctrl" for BG2CD
> +	"marvell,berlin2q-chip-ctrl" for BG2Q
> +- reg: address and length of following register sets for
> +  BG2/BG2CD: chip control register set
> +  BG2Q: chip control register set and cpu pll registers
> +
> +* Clock provider binding
> +
> +As clock related registers are spread among the chip control registers, the
> +chip control node also provides the clocks. Marvell Berlin2 (BG2, BG2CD, BG2Q)
> +SoCs share the same IP for PLLs and clocks, with some minor differences in
> +features and register layout.
> +
> +Required properties:
> +- #clock-cells: shall be set to 1
> +- clocks: clock specifiers referencing the core clock input clocks
> +- clock-names: array of strings describing the input clock specifiers above.
> +    Allowed clock-names for the reference clocks are
> +      "refclk" for the SoCs osciallator input on all SoCs,
> +    and SoC-specific input clocks for
> +      BG2/BG2CD: "video_ext0" for the external video clock input
> +
> +Clocks provided by core clocks shall be referenced by a clock specifier
> +indexing one of the provided clocks. Refer to dt-bindings/clock/berlin<soc>.h
> +for the corresponding index mapping.
> +
> +Example:
> +
> +chip: chip-control@ea0000 {
> +	compatible = "marvell,berlin2-chip-ctrl";
> +	#clock-cells = <1>;
> +	reg = <0xea0000 0x400>;
> +	clocks = <&refclk>, <&externaldev 0>;
> +	clock-names = "refclk", "video_ext0";
> +};
> -- 
> 1.9.1
> 

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 06/10] clk: berlin: add core clock driver for BG2/BG2CD
  2014-05-19 16:43 ` [PATCH v2 06/10] clk: berlin: add core clock driver for BG2/BG2CD Sebastian Hesselbarth
@ 2014-05-19 21:06   ` Alexandre Belloni
  0 siblings, 0 replies; 19+ messages in thread
From: Alexandre Belloni @ 2014-05-19 21:06 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Mike Turquette, Jisheng Zhang, linux-arm-kernel, linux-kernel

On 19/05/2014 at 18:43:27 +0200, Sebastian Hesselbarth wrote :
> This driver deals with the core clocks found on Marvell Berlin
> BG2 and BG2CD. For the shared register dividers, make use of the
> corresponding driver and add some single clock muxes and gates for
> the rest.
> 
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> ---
> Changelog:
> v1->v2:
> - adapt to new single chip control node and compatible
> - swallow twd clock node
> 
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> Cc: Jisheng Zhang <jszhang@marvell.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> ---
>  drivers/clk/berlin/Makefile |   2 +
>  drivers/clk/berlin/bg2.c    | 691 ++++++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/berlin/common.h |  29 ++
>  3 files changed, 722 insertions(+)
>  create mode 100644 drivers/clk/berlin/bg2.c
>  create mode 100644 drivers/clk/berlin/common.h
> 
> diff --git a/drivers/clk/berlin/Makefile b/drivers/clk/berlin/Makefile
> index f0a7dc8b5e30..2b33e1e74503 100644
> --- a/drivers/clk/berlin/Makefile
> +++ b/drivers/clk/berlin/Makefile
> @@ -1 +1,3 @@
>  obj-y += berlin2-avpll.o berlin2-pll.o berlin2-div.o
> +obj-$(CONFIG_MACH_BERLIN_BG2)	+= bg2.o
> +obj-$(CONFIG_MACH_BERLIN_BG2CD)	+= bg2.o
> diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c
> new file mode 100644
> index 000000000000..515fb133495c
> --- /dev/null
> +++ b/drivers/clk/berlin/bg2.c
> @@ -0,0 +1,691 @@
> +/*
> + * Copyright (c) 2014 Marvell Technology Group Ltd.
> + *
> + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
> + * Alexandre Belloni <alexandre.belloni@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/kernel.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/slab.h>
> +
> +#include <dt-bindings/clock/berlin2.h>
> +
> +#include "berlin2-avpll.h"
> +#include "berlin2-div.h"
> +#include "berlin2-pll.h"
> +#include "common.h"
> +
> +#define REG_PINMUX0		0x0000
> +#define REG_PINMUX1		0x0004
> +#define REG_SYSPLLCTL0		0x0014
> +#define REG_SYSPLLCTL4		0x0024
> +#define REG_MEMPLLCTL0		0x0028
> +#define REG_MEMPLLCTL4		0x0038
> +#define REG_CPUPLLCTL0		0x003c
> +#define REG_CPUPLLCTL4		0x004c
> +#define REG_AVPLLCTL0		0x0050
> +#define REG_AVPLLCTL31		0x00cc
> +#define REG_AVPLLCTL62		0x0148
> +#define REG_PLLSTATUS		0x014c
> +#define REG_CLKENABLE		0x0150
> +#define REG_CLKSELECT0		0x0154
> +#define REG_CLKSELECT1		0x0158
> +#define REG_CLKSELECT2		0x015c
> +#define REG_CLKSELECT3		0x0160
> +#define REG_CLKSWITCH0		0x0164
> +#define REG_CLKSWITCH1		0x0168
> +#define REG_RESET_TRIGGER	0x0178
> +#define REG_RESET_STATUS0	0x017c
> +#define REG_RESET_STATUS1	0x0180
> +#define REG_SW_GENERIC0		0x0184
> +#define REG_SW_GENERIC3		0x0190
> +#define REG_PRODUCTID		0x01cc
> +#define REG_PRODUCTID_EXT	0x01d0
> +#define REG_GFX3DCORE_CLKCTL	0x022c
> +#define REG_GFX3DSYS_CLKCTL	0x0230
> +#define REG_ARC_CLKCTL		0x0234
> +#define REG_VIP_CLKCTL		0x0238
> +#define REG_SDIO0XIN_CLKCTL	0x023c
> +#define REG_SDIO1XIN_CLKCTL	0x0240
> +#define REG_GFX3DEXTRA_CLKCTL	0x0244
> +#define REG_GFX3D_RESET		0x0248
> +#define REG_GC360_CLKCTL	0x024c
> +#define REG_SDIO_DLLMST_CLKCTL	0x0250
> +
> +/*
> + * BG2/BG2CD SoCs have the following audio/video I/O units:
> + *
> + * audiohd: HDMI TX audio
> + * audio0:  7.1ch TX
> + * audio1:  2ch TX
> + * audio2:  2ch RX
> + * audio3:  SPDIF TX
> + * video0:  HDMI video
> + * video1:  Secondary video
> + * video2:  SD auxiliary video
> + *
> + * There are no external audio clocks (ACLKI0, ACLKI1) and
> + * only one external video clock (VCLKI0).
> + *
> + * Currently missing bits and pieces:
> + * - audio_fast_pll is unknown
> + * - audiohd_pll is unknown
> + * - video0_pll is unknown
> + * - audio[023], audiohd parent pll is assumed to be audio_fast_pll
> + *
> + */
> +
> +#define	MAX_CLKS 41
> +static struct clk *clks[MAX_CLKS];
> +static struct clk_onecell_data clk_data;
> +static DEFINE_SPINLOCK(lock);
> +static void __iomem *gbase;
> +
> +enum {
> +	REFCLK, VIDEO_EXT0,
> +	SYSPLL, MEMPLL, CPUPLL,
> +	AVPLL_A1, AVPLL_A2, AVPLL_A3, AVPLL_A4,
> +	AVPLL_A5, AVPLL_A6, AVPLL_A7, AVPLL_A8,
> +	AVPLL_B1, AVPLL_B2, AVPLL_B3, AVPLL_B4,
> +	AVPLL_B5, AVPLL_B6, AVPLL_B7, AVPLL_B8,
> +	AUDIO1_PLL, AUDIO_FAST_PLL,
> +	VIDEO0_PLL, VIDEO0_IN,
> +	VIDEO1_PLL, VIDEO1_IN,
> +	VIDEO2_PLL, VIDEO2_IN,
> +};
> +
> +static const char *clk_names[] = {
> +	[REFCLK]		= "refclk",
> +	[VIDEO_EXT0]		= "video_ext0",
> +	[SYSPLL]		= "syspll",
> +	[MEMPLL]		= "mempll",
> +	[CPUPLL]		= "cpupll",
> +	[AVPLL_A1]		= "avpll_a1",
> +	[AVPLL_A2]		= "avpll_a2",
> +	[AVPLL_A3]		= "avpll_a3",
> +	[AVPLL_A4]		= "avpll_a4",
> +	[AVPLL_A5]		= "avpll_a5",
> +	[AVPLL_A6]		= "avpll_a6",
> +	[AVPLL_A7]		= "avpll_a7",
> +	[AVPLL_A8]		= "avpll_a8",
> +	[AVPLL_B1]		= "avpll_b1",
> +	[AVPLL_B2]		= "avpll_b2",
> +	[AVPLL_B3]		= "avpll_b3",
> +	[AVPLL_B4]		= "avpll_b4",
> +	[AVPLL_B5]		= "avpll_b5",
> +	[AVPLL_B6]		= "avpll_b6",
> +	[AVPLL_B7]		= "avpll_b7",
> +	[AVPLL_B8]		= "avpll_b8",
> +	[AUDIO1_PLL]		= "audio1_pll",
> +	[AUDIO_FAST_PLL]	= "audio_fast_pll",
> +	[VIDEO0_PLL]		= "video0_pll",
> +	[VIDEO0_IN]		= "video0_in",
> +	[VIDEO1_PLL]		= "video1_pll",
> +	[VIDEO1_IN]		= "video1_in",
> +	[VIDEO2_PLL]		= "video2_pll",
> +	[VIDEO2_IN]		= "video2_in",
> +};
> +
> +static const struct berlin2_pll_map bg2_pll_map __initconst = {
> +	.vcodiv		= {10, 15, 20, 25, 30, 40, 50, 60, 80},
> +	.mult		= 10,
> +	.fbdiv_shift	= 6,
> +	.rfdiv_shift	= 1,
> +	.divsel_shift	= 7,
> +};
> +
> +static const u8 default_parent_ids[] = {
> +	SYSPLL, AVPLL_B4, AVPLL_A5, AVPLL_B6, AVPLL_B7, SYSPLL
> +};
> +
> +static const struct berlin2_div_data bg2_divs[] __initconst = {
> +	{
> +		.name = "sys",
> +		.parent_ids = (const u8 []){
> +			SYSPLL, AVPLL_B4, AVPLL_B5, AVPLL_B6, AVPLL_B7, SYSPLL
> +		},
> +		.num_parents = 6,
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 0),
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 0),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 3),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 3),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 4),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 5),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = CLK_IGNORE_UNUSED,
> +	},
> +	{
> +		.name = "cpu",
> +		.parent_ids = (const u8 []){
> +			CPUPLL, MEMPLL, MEMPLL, MEMPLL, MEMPLL
> +		},
> +		.num_parents = 5,
> +		.map = {
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 6),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 9),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 6),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 7),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 8),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "drmfigo",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 16),
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 17),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 20),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 12),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 13),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 14),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "cfg",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 1),
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 23),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT0, 26),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 15),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 16),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 17),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "gfx",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 4),
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT0, 29),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 0),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 18),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 19),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 20),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "zsp",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 5),
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 3),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 6),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 21),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 22),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 23),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "perif",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 6),
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 9),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 12),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 24),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 25),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 26),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = CLK_IGNORE_UNUSED,
> +	},
> +	{
> +		.name = "pcube",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 2),
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 15),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 18),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 27),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 28),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH0, 29),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "vscope",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 3),
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 21),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT1, 24),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH0, 30),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH0, 31),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 0),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "nfc_ecc",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 18),
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT1, 27),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 0),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 1),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 2),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 3),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "vpp",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 21),
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT2, 3),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 6),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 4),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 5),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 6),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "app",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 20),
> +			BERLIN2_PLL_SELECT(REG_CLKSELECT2, 9),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 12),
> +			BERLIN2_PLL_SWITCH(REG_CLKSWITCH1, 7),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 8),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 9),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "audio0",
> +		.parent_ids = (const u8 []){ AUDIO_FAST_PLL },
> +		.num_parents = 1,
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 22),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 17),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 10),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 11),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "audio2",
> +		.parent_ids = (const u8 []){ AUDIO_FAST_PLL },
> +		.num_parents = 1,
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 24),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 20),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 14),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 15),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "audio3",
> +		.parent_ids = (const u8 []){ AUDIO_FAST_PLL },
> +		.num_parents = 1,
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 25),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT2, 23),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 16),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 17),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "audio1",
> +		.parent_ids = (const u8 []){ AUDIO1_PLL },
> +		.num_parents = 1,
> +		.map = {
> +			BERLIN2_DIV_GATE(REG_CLKENABLE, 23),
> +			BERLIN2_DIV_SELECT(REG_CLKSELECT3, 0),
> +			BERLIN2_DIV_SWITCH(REG_CLKSWITCH1, 12),
> +			BERLIN2_DIV_D3SWITCH(REG_CLKSWITCH1, 13),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "gfx3d_core",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_SINGLE_DIV(REG_GFX3DCORE_CLKCTL),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "gfx3d_sys",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_SINGLE_DIV(REG_GFX3DSYS_CLKCTL),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "arc",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_SINGLE_DIV(REG_ARC_CLKCTL),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "vip",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_SINGLE_DIV(REG_VIP_CLKCTL),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "sdio0xin",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_SINGLE_DIV(REG_SDIO0XIN_CLKCTL),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "sdio1xin",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_SINGLE_DIV(REG_SDIO1XIN_CLKCTL),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "gfx3d_extra",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_SINGLE_DIV(REG_GFX3DEXTRA_CLKCTL),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "gc360",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_SINGLE_DIV(REG_GC360_CLKCTL),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +	{
> +		.name = "sdio_dllmst",
> +		.parent_ids = default_parent_ids,
> +		.num_parents = ARRAY_SIZE(default_parent_ids),
> +		.map = {
> +			BERLIN2_SINGLE_DIV(REG_SDIO_DLLMST_CLKCTL),
> +		},
> +		.div_flags = BERLIN2_DIV_HAS_GATE | BERLIN2_DIV_HAS_MUX,
> +		.flags = 0,
> +	},
> +};
> +
> +static const struct berlin2_gate_data bg2_gates[] __initconst = {
> +	{ "geth0",	"perif",	7 },
> +	{ "geth1",	"perif",	8 },
> +	{ "sata",	"perif",	9 },
> +	{ "ahbapb",	"perif",	10, CLK_IGNORE_UNUSED },
> +	{ "usb0",	"perif",	11 },
> +	{ "usb1",	"perif",	12 },
> +	{ "pbridge",	"perif",	13, CLK_IGNORE_UNUSED },
> +	{ "sdio0",	"perif",	14, CLK_IGNORE_UNUSED },
> +	{ "sdio1",	"perif",	15, CLK_IGNORE_UNUSED },
> +	{ "nfc",	"perif",	17 },
> +	{ "smemc",	"perif",	19 },
> +	{ "audiohd",	"audiohd_pll",	26 },
> +	{ "video0",	"video0_in",	27 },
> +	{ "video1",	"video1_in",	28 },
> +	{ "video2",	"video2_in",	29 },
> +};
> +
> +static void __init berlin2_clock_setup(struct device_node *np)
> +{
> +	const char *parent_names[9];
> +	struct clk *clk;
> +	u8 avpll_flags = 0;
> +	int n;
> +
> +	gbase = of_iomap(np, 0);
> +	if (!gbase)
> +		return;
> +
> +	/* overwrite default clock names with DT provided ones */
> +	clk = of_clk_get_by_name(np, clk_names[REFCLK]);
> +	if (!IS_ERR(clk)) {
> +		clk_names[REFCLK] = __clk_get_name(clk);
> +		clk_put(clk);
> +	}
> +
> +	clk = of_clk_get_by_name(np, clk_names[VIDEO_EXT0]);
> +	if (!IS_ERR(clk)) {
> +		clk_names[VIDEO_EXT0] = __clk_get_name(clk);
> +		clk_put(clk);
> +	}
> +
> +	/* simple register PLLs */
> +	clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0,
> +				   clk_names[SYSPLL], clk_names[REFCLK], 0);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +
> +	clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0,
> +				   clk_names[MEMPLL], clk_names[REFCLK], 0);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +
> +	clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0,
> +				   clk_names[CPUPLL], clk_names[REFCLK], 0);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +
> +	if (of_device_is_compatible(np, "marvell,berlin2-global-register"))
> +		avpll_flags |= BERLIN2_AVPLL_SCRAMBLE_QUIRK;
> +
> +	/* audio/video VCOs */
> +	clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA",
> +			 clk_names[REFCLK], avpll_flags, 0);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +
> +	for (n = 0; n < 8; n++) {
> +		clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0,
> +			     clk_names[AVPLL_A1 + n], n, "avpll_vcoA",
> +			     avpll_flags, 0);
> +		if (IS_ERR(clk))
> +			goto bg2_fail;
> +	}
> +
> +	clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB",
> +				 clk_names[REFCLK], BERLIN2_AVPLL_BIT_QUIRK |
> +				 avpll_flags, 0);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +
> +	for (n = 0; n < 8; n++) {
> +		clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31,
> +			     clk_names[AVPLL_B1 + n], n, "avpll_vcoB",
> +			     BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0);
> +		if (IS_ERR(clk))
> +			goto bg2_fail;
> +	}
> +
> +	/* reference clock bypass switches */
> +	parent_names[0] = clk_names[SYSPLL];
> +	parent_names[1] = clk_names[REFCLK];
> +	clk = clk_register_mux(NULL, "syspll_byp", parent_names, 2,
> +			       0, gbase + REG_CLKSWITCH0, 0, 1, 0, &lock);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +	clk_names[SYSPLL] = __clk_get_name(clk);
> +
> +	parent_names[0] = clk_names[MEMPLL];
> +	parent_names[1] = clk_names[REFCLK];
> +	clk = clk_register_mux(NULL, "mempll_byp", parent_names, 2,
> +			       0, gbase + REG_CLKSWITCH0, 1, 1, 0, &lock);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +	clk_names[MEMPLL] = __clk_get_name(clk);
> +
> +	parent_names[0] = clk_names[CPUPLL];
> +	parent_names[1] = clk_names[REFCLK];
> +	clk = clk_register_mux(NULL, "cpupll_byp", parent_names, 2,
> +			       0, gbase + REG_CLKSWITCH0, 2, 1, 0, &lock);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +	clk_names[CPUPLL] = __clk_get_name(clk);
> +
> +	/* clock muxes */
> +	parent_names[0] = clk_names[AVPLL_B3];
> +	parent_names[1] = clk_names[AVPLL_A3];
> +	clk = clk_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2,
> +			       0, gbase + REG_CLKSELECT2, 29, 1, 0, &lock);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +
> +	parent_names[0] = clk_names[VIDEO0_PLL];
> +	parent_names[1] = clk_names[VIDEO_EXT0];
> +	clk = clk_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2,
> +			       0, gbase + REG_CLKSELECT3, 4, 1, 0, &lock);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +
> +	parent_names[0] = clk_names[VIDEO1_PLL];
> +	parent_names[1] = clk_names[VIDEO_EXT0];
> +	clk = clk_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2,
> +			       0, gbase + REG_CLKSELECT3, 6, 1, 0, &lock);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +
> +	parent_names[0] = clk_names[AVPLL_A2];
> +	parent_names[1] = clk_names[AVPLL_B2];
> +	clk = clk_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2,
> +			       0, gbase + REG_CLKSELECT3, 7, 1, 0, &lock);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +
> +	parent_names[0] = clk_names[VIDEO2_PLL];
> +	parent_names[1] = clk_names[VIDEO_EXT0];
> +	clk = clk_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2,
> +			       0, gbase + REG_CLKSELECT3, 9, 1, 0, &lock);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +
> +	parent_names[0] = clk_names[AVPLL_B1];
> +	parent_names[1] = clk_names[AVPLL_A5];
> +	clk = clk_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2,
> +			       0, gbase + REG_CLKSELECT3, 10, 1, 0, &lock);
> +	if (IS_ERR(clk))
> +		goto bg2_fail;
> +
> +	/* clock divider cells */
> +	for (n = 0; n < ARRAY_SIZE(bg2_divs); n++) {
> +		const struct berlin2_div_data *dd = &bg2_divs[n];
> +		int k;
> +
> +		for (k = 0; k < dd->num_parents; k++)
> +			parent_names[k] = clk_names[dd->parent_ids[k]];
> +
> +		clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
> +				dd->name, dd->div_flags, parent_names,
> +				dd->num_parents, dd->flags, &lock);
> +	}
> +
> +	/* clock gate cells */
> +	for (n = 0; n < ARRAY_SIZE(bg2_gates); n++) {
> +		const struct berlin2_gate_data *gd = &bg2_gates[n];
> +
> +		clks[CLKID_GETH0 + n] = clk_register_gate(NULL, gd->name,
> +			    gd->parent_name, gd->flags, gbase + REG_CLKENABLE,
> +			    gd->bit_idx, 0, &lock);
> +	}
> +
> +	/* twdclk is derived from cpu/3 */
> +	clks[CLKID_TWD] =
> +		clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
> +
> +	/* check for errors on leaf clocks */
> +	for (n = 0; n < MAX_CLKS; n++) {
> +		if (!IS_ERR(clks[n]))
> +			continue;
> +
> +		pr_err("%s: Unable to register leaf clock %d\n",
> +		       np->full_name, n);
> +		goto bg2_fail;
> +	}
> +
> +	/* register clk-provider */
> +	clk_data.clks = clks;
> +	clk_data.clk_num = MAX_CLKS;
> +	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> +
> +	return;
> +
> +bg2_fail:
> +	iounmap(gbase);
> +}
> +CLK_OF_DECLARE(berlin2_clock, "marvell,berlin2-chip-ctrl",
> +	       berlin2_clock_setup);
> +CLK_OF_DECLARE(berlin2cd_clock, "marvell,berlin2cd-chip-ctrl",
> +	       berlin2_clock_setup);
> diff --git a/drivers/clk/berlin/common.h b/drivers/clk/berlin/common.h
> new file mode 100644
> index 000000000000..bc68a14c4550
> --- /dev/null
> +++ b/drivers/clk/berlin/common.h
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright (c) 2014 Marvell Technology Group Ltd.
> + *
> + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
> + * Alexandre Belloni <alexandre.belloni@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
> + */
> +#ifndef __BERLIN2_COMMON_H
> +#define __BERLIN2_COMMON_H
> +
> +struct berlin2_gate_data {
> +	const char *name;
> +	const char *parent_name;
> +	u8 bit_idx;
> +	unsigned long flags;
> +};
> +
> +#endif /* BERLIN2_COMMON_H */
> -- 
> 1.9.1
> 

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 08/10] ARM: dts: berlin: convert BG2CD to DT clock nodes
  2014-05-19 16:43 ` [PATCH v2 08/10] ARM: dts: berlin: convert BG2CD to DT clock nodes Sebastian Hesselbarth
@ 2014-05-19 21:07   ` Alexandre Belloni
  0 siblings, 0 replies; 19+ messages in thread
From: Alexandre Belloni @ 2014-05-19 21:07 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Mike Turquette, Jisheng Zhang, linux-arm-kernel, linux-kernel

On 19/05/2014 at 18:43:29 +0200, Sebastian Hesselbarth wrote :
> This converts Berlin BG2CD SoC dtsi to make use of the new DT clock
> nodes for Berlin SoCs. Also add a binding include to ease core clock
> references.
> 
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>

Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

> ---
> Changelog:
> v1->v2:
> - adapt to new single chip control node and compatible
> 
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> Cc: Jisheng Zhang <jszhang@marvell.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> ---
>  arch/arm/boot/dts/berlin2cd.dtsi | 53 ++++++++++++++++++----------------------
>  1 file changed, 24 insertions(+), 29 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
> index 6eb1bdae23ac..1385caa6d029 100644
> --- a/arch/arm/boot/dts/berlin2cd.dtsi
> +++ b/arch/arm/boot/dts/berlin2cd.dtsi
> @@ -12,6 +12,7 @@
>   */
>  
>  #include "skeleton.dtsi"
> +#include <dt-bindings/clock/berlin2.h>
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>  
>  / {
> @@ -30,24 +31,10 @@
>  		};
>  	};
>  
> -	clocks {
> -		smclk: sysmgr-clock {
> -			compatible = "fixed-clock";
> -			#clock-cells = <0>;
> -			clock-frequency = <25000000>;
> -		};
> -
> -		cfgclk: cfg-clock {
> -			compatible = "fixed-clock";
> -			#clock-cells = <0>;
> -			clock-frequency = <75000000>;
> -		};
> -
> -		sysclk: system-clock {
> -			compatible = "fixed-clock";
> -			#clock-cells = <0>;
> -			clock-frequency = <300000000>;
> -		};
> +	refclk: oscillator {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <25000000>;
>  	};
>  
>  	soc {
> @@ -76,7 +63,7 @@
>  			compatible = "arm,cortex-a9-twd-timer";
>  			reg = <0xad0600 0x20>;
>  			interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
> -			clocks = <&sysclk>;
> +			clocks = <&chip CLKID_TWD>;
>  		};
>  
>  		apb@e80000 {
> @@ -163,7 +150,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c00 0x14>;
>  				interrupts = <8>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "okay";
>  			};
> @@ -172,7 +159,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c14 0x14>;
>  				interrupts = <9>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "okay";
>  			};
> @@ -181,7 +168,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c28 0x14>;
>  				interrupts = <10>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -190,7 +177,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c3c 0x14>;
>  				interrupts = <11>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -199,7 +186,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c50 0x14>;
>  				interrupts = <12>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -208,7 +195,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c64 0x14>;
>  				interrupts = <13>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -217,7 +204,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c78 0x14>;
>  				interrupts = <14>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -226,7 +213,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c8c 0x14>;
>  				interrupts = <15>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -241,6 +228,14 @@
>  			};
>  		};
>  
> +		chip: chip-control@ea0000 {
> +			compatible = "marvell,berlin2cd-chip-ctrl";
> +			#clock-cells = <1>;
> +			reg = <0xea0000 0x400>;
> +			clocks = <&refclk>;
> +			clock-names = "refclk";
> +		};
> +
>  		apb@fc0000 {
>  			compatible = "simple-bus";
>  			#address-cells = <1>;
> @@ -285,7 +280,7 @@
>  				reg-shift = <2>;
>  				reg-io-width = <1>;
>  				interrupts = <8>;
> -				clocks = <&smclk>;
> +				clocks = <&refclk>;
>  				status = "disabled";
>  			};
>  
> @@ -295,7 +290,7 @@
>  				reg-shift = <2>;
>  				reg-io-width = <1>;
>  				interrupts = <9>;
> -				clocks = <&smclk>;
> +				clocks = <&refclk>;
>  				status = "disabled";
>  			};
>  
> -- 
> 1.9.1
> 

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 09/10] ARM: dts: berlin: convert BG2 to DT clock nodes
  2014-05-19 16:43 ` [PATCH v2 09/10] ARM: dts: berlin: convert BG2 " Sebastian Hesselbarth
@ 2014-05-19 21:13   ` Alexandre Belloni
  0 siblings, 0 replies; 19+ messages in thread
From: Alexandre Belloni @ 2014-05-19 21:13 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Mike Turquette, Jisheng Zhang, linux-arm-kernel, linux-kernel

On 19/05/2014 at 18:43:30 +0200, Sebastian Hesselbarth wrote :
> This converts Berlin BG2 SoC dtsi to make use of the new DT clock
> nodes for Berlin SoCs. While at it, also fix up twdclk which is
> running at cpuclk/3 instead of sysclk.
> 
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> ---
> Changelog:
> v1->v2:
> - adapt to new single chip control node and compatible
> 
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> Cc: Jisheng Zhang <jszhang@marvell.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> ---
>  arch/arm/boot/dts/berlin2.dtsi | 56 +++++++++++++++++-------------------------
>  1 file changed, 23 insertions(+), 33 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
> index 57cadd31f4e1..591d4b8c1c2b 100644
> --- a/arch/arm/boot/dts/berlin2.dtsi
> +++ b/arch/arm/boot/dts/berlin2.dtsi
> @@ -12,6 +12,7 @@
>   */
>  
>  #include "skeleton.dtsi"
> +#include <dt-bindings/clock/berlin2.h>
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>  
>  / {
> @@ -37,24 +38,10 @@
>  		};
>  	};
>  
> -	clocks {
> -		smclk: sysmgr-clock {
> -			compatible = "fixed-clock";
> -			#clock-cells = <0>;
> -			clock-frequency = <25000000>;
> -		};
> -
> -		cfgclk: cfg-clock {
> -			compatible = "fixed-clock";
> -			#clock-cells = <0>;
> -			clock-frequency = <100000000>;
> -		};
> -
> -		sysclk: system-clock {
> -			compatible = "fixed-clock";
> -			#clock-cells = <0>;
> -			clock-frequency = <400000000>;
> -		};
> +	refclk: oscillator {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <25000000>;
>  	};
>  
>  	soc {
> @@ -88,7 +75,7 @@
>  			compatible = "arm,cortex-a9-twd-timer";
>  			reg = <0xad0600 0x20>;
>  			interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
> -			clocks = <&sysclk>;
> +			clocks = <&chip CLKID_TWD>;
>  		};
>  
>  		apb@e80000 {
> @@ -175,7 +162,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c00 0x14>;
>  				interrupts = <8>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "okay";
>  			};
> @@ -184,7 +171,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c14 0x14>;
>  				interrupts = <9>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "okay";
>  			};
> @@ -193,7 +180,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c28 0x14>;
>  				interrupts = <10>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -202,7 +189,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c3c 0x14>;
>  				interrupts = <11>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -211,7 +198,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c50 0x14>;
>  				interrupts = <12>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -220,7 +207,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c64 0x14>;
>  				interrupts = <13>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -229,7 +216,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c78 0x14>;
>  				interrupts = <14>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -238,7 +225,7 @@
>  				compatible = "snps,dw-apb-timer";
>  				reg = <0x2c8c 0x14>;
>  				interrupts = <15>;
> -				clocks = <&cfgclk>;
> +				clocks = <&chip CLKID_CFG>;
>  				clock-names = "timer";
>  				status = "disabled";
>  			};
> @@ -253,9 +240,12 @@
>  			};
>  		};
>  
> -		generic-regs@ea0184 {
> -			compatible = "marvell,berlin-generic-regs", "syscon";
> -			reg = <0xea0184 0x10>;
> +		chip: chip-control@ea0000 {
> +			compatible = "marvell,berlin2-chip-ctrl";
> +			#clock-cells = <1>;
> +			reg = <0xea0000 0x400>;
> +			clocks = <&refclk>;
> +			clock-names = "refclk";
>  		};
>  
>  		apb@fc0000 {
> @@ -305,7 +295,7 @@
>  				reg-shift = <2>;
>  				reg-io-width = <1>;
>  				interrupts = <8>;
> -				clocks = <&smclk>;
> +				clocks = <&refclk>;
>  				status = "disabled";
>  			};
>  
> @@ -315,7 +305,7 @@
>  				reg-shift = <2>;
>  				reg-io-width = <1>;
>  				interrupts = <9>;
> -				clocks = <&smclk>;
> +				clocks = <&refclk>;
>  				status = "disabled";
>  			};
>  
> @@ -325,7 +315,7 @@
>  				reg-shift = <2>;
>  				reg-io-width = <1>;
>  				interrupts = <10>;
> -				clocks = <&smclk>;
> +				clocks = <&refclk>;
>  				status = "disabled";
>  			};
>  
> -- 
> 1.9.1
> 

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 00/10] Marvell Berlin full clock support
  2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
                   ` (10 preceding siblings ...)
  2014-05-19 19:46 ` [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
@ 2014-05-29  0:07 ` Mike Turquette
  2014-05-29  9:20   ` Sebastian Hesselbarth
  11 siblings, 1 reply; 19+ messages in thread
From: Mike Turquette @ 2014-05-29  0:07 UTC (permalink / raw)
  To: Sebastian Hesselbarth, Sebastian Hesselbarth
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Alexandre Belloni, Jisheng Zhang, devicetree,
	linux-doc, linux-arm-kernel, linux-kernel

Quoting Sebastian Hesselbarth (2014-05-19 09:43:21)
> Mike,
> 
> this is v2 of the Berlin SoC clock driver [1] but with a reworked DT
> binding as requested [2]. We decided to not even try to split up the chip
> control registers that deal with pinmux, padmux, clock, reset, and evil
> stuff we haven't even looked at. Instead we keep a single node that clock
> driver will remap early, while proper platform_drivers use a regmap
> instead. Although clock and other drivers share the same register range,
> they use individual registers exclusively.
> 
> There are some functional fixes in the single clock drivers, I noticed
> while retesting each individial driver. There will be more to fixup but
> without any drivers actually using the clocks, it is hard to tell what
> isn't working now.
> 
> Anyway, the current binding should match what you requested and having
> a clock driver for v3.16 will really be a huge benefit for us to work
> on more driver support.
> 
> If you are fine with it, please take patches 2-7 and I'll pick up
> 1,8-10 in berlin branch.

Patches #2-7 applied to clk-next.

Thanks!
Mike

> 
> Sebastian
> 
> [1] https://lkml.kernel.org/r/1399839881-29895-1-git-send-email-sebastian.hesselbarth@gmail.com
> [2] https://lkml.kernel.org/r/20140515044106.19795.57249@quantum
> 
> Alexandre Belloni (4):
>   clk: berlin: add driver for BG2x simple PLLs
>   clk: berlin: add driver for BG2x complex divider cells
>   clk: berlin: add core clock driver for BG2Q
>   ARM: dts: berlin: convert BG2Q to DT clock nodes
> 
> Sebastian Hesselbarth (6):
>   dt-binding: ARM: add clock binding docs for Marvell Berlin2 SoCs
>   clk: berlin: add binding include for Berlin SoC clock ids
>   clk: berlin: add driver for BG2x audio/video PLL
>   clk: berlin: add core clock driver for BG2/BG2CD
>   ARM: dts: berlin: convert BG2CD to DT clock nodes
>   ARM: dts: berlin: convert BG2 to DT clock nodes
> 
>  .../devicetree/bindings/arm/marvell,berlin.txt     |  47 ++
>  arch/arm/boot/dts/berlin2.dtsi                     |  56 +-
>  arch/arm/boot/dts/berlin2cd.dtsi                   |  53 +-
>  arch/arm/boot/dts/berlin2q.dtsi                    |  54 +-
>  drivers/clk/Makefile                               |   1 +
>  drivers/clk/berlin/Makefile                        |   4 +
>  drivers/clk/berlin/berlin2-avpll.c                 | 393 ++++++++++++
>  drivers/clk/berlin/berlin2-avpll.h                 |  36 ++
>  drivers/clk/berlin/berlin2-div.c                   | 265 ++++++++
>  drivers/clk/berlin/berlin2-div.h                   |  89 +++
>  drivers/clk/berlin/berlin2-pll.c                   | 117 ++++
>  drivers/clk/berlin/berlin2-pll.h                   |  37 ++
>  drivers/clk/berlin/bg2.c                           | 691 +++++++++++++++++++++
>  drivers/clk/berlin/bg2q.c                          | 389 ++++++++++++
>  drivers/clk/berlin/common.h                        |  29 +
>  include/dt-bindings/clock/berlin2.h                |  45 ++
>  include/dt-bindings/clock/berlin2q.h               |  31 +
>  17 files changed, 2240 insertions(+), 97 deletions(-)
>  create mode 100644 drivers/clk/berlin/Makefile
>  create mode 100644 drivers/clk/berlin/berlin2-avpll.c
>  create mode 100644 drivers/clk/berlin/berlin2-avpll.h
>  create mode 100644 drivers/clk/berlin/berlin2-div.c
>  create mode 100644 drivers/clk/berlin/berlin2-div.h
>  create mode 100644 drivers/clk/berlin/berlin2-pll.c
>  create mode 100644 drivers/clk/berlin/berlin2-pll.h
>  create mode 100644 drivers/clk/berlin/bg2.c
>  create mode 100644 drivers/clk/berlin/bg2q.c
>  create mode 100644 drivers/clk/berlin/common.h
>  create mode 100644 include/dt-bindings/clock/berlin2.h
>  create mode 100644 include/dt-bindings/clock/berlin2q.h
> 
> ---
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
> Cc: Kumar Gala <galak@codeaurora.org>
> Cc: Randy Dunlap <rdunlap@infradead.org>
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> Cc: Jisheng Zhang <jszhang@marvell.com>
> Cc: devicetree@vger.kernel.org
> Cc: linux-doc@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> -- 
> 1.9.1
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 00/10] Marvell Berlin full clock support
  2014-05-29  0:07 ` Mike Turquette
@ 2014-05-29  9:20   ` Sebastian Hesselbarth
  0 siblings, 0 replies; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-29  9:20 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Alexandre Belloni, Jisheng Zhang, devicetree,
	linux-doc, linux-arm-kernel, linux-kernel

On 05/29/2014 02:07 AM, Mike Turquette wrote:
> Quoting Sebastian Hesselbarth (2014-05-19 09:43:21)
>> Mike,
>>
>> this is v2 of the Berlin SoC clock driver [1] but with a reworked DT
>> binding as requested [2]. We decided to not even try to split up the chip
>> control registers that deal with pinmux, padmux, clock, reset, and evil
>> stuff we haven't even looked at. Instead we keep a single node that clock
>> driver will remap early, while proper platform_drivers use a regmap
>> instead. Although clock and other drivers share the same register range,
>> they use individual registers exclusively.
>>
>> There are some functional fixes in the single clock drivers, I noticed
>> while retesting each individial driver. There will be more to fixup but
>> without any drivers actually using the clocks, it is hard to tell what
>> isn't working now.
>>
>> Anyway, the current binding should match what you requested and having
>> a clock driver for v3.16 will really be a huge benefit for us to work
>> on more driver support.
>>
>> If you are fine with it, please take patches 2-7 and I'll pick up
>> 1,8-10 in berlin branch.
> 
> Patches #2-7 applied to clk-next.

Thanks Mike, but please drop patch #2
  ("clk: berlin: add binding include for Berlin SoC clock ids")
before you push your clk-next branch, it already went through arm-soc.

Sorry,
  Sebastian

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 00/10] Marvell Berlin full clock support
  2014-05-11 20:24 [PATCH 0/8] " Sebastian Hesselbarth
@ 2014-05-14 20:15 ` Sebastian Hesselbarth
  0 siblings, 0 replies; 19+ messages in thread
From: Sebastian Hesselbarth @ 2014-05-14 20:15 UTC (permalink / raw)
  To: Sebastian Hesselbarth
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Mike Turquette, Alexandre Belloni, Jisheng Zhang,
	devicetree, linux-doc, linux-arm-kernel, linux-kernel

This is version 2 of a patch set to bring proper DT based clocks to
Marvell Berlin SoCs.

The overall changes are:

* Dropped of_clk_create_name() helper
Booting into an initramfs rootfs revealed that the unique clock names
created with that helper clash with the way of_clk_get_parent_name()
resolves the clock specifier to get the correct clock name. Anyway,
I still consider the helper a good idea and postpone it to the next
cycle when I have more time to look at the details.

* Added BG2Q core clock driver and dtsi changes
Alexandre just provided them, so I added them to this patch set.

The single patch overview now is:

Patch 1 adds the whole binding documentation for all clock related IP
found on BG2, BG2CD, and BG2Q.

Patch 2 adds corresponding dt-binding includes for the core clock
indices to be used in both DT and the driver.

Patches 3, 4, and 5 add clock drivers for the Audio/Video PLL, simple
PLLs, and complex clock divider cells found on Berlin SoCs. Where
required, currently known differences between BG2/BG2CD and BG2Q are
taken care of.

Patches 6 and 7 add core clock drivers for the remaining clocks of
BG2/BG2CD and BG2Q. The register set dealing with it, is shared among
input and bypass muxes, clock dividers and clock gates.

Patches 8, 9, and 10 finally convert the DT SoC includes for BG2,
BG2CD, and BG2Q to make use of the new clock related DT nodes.

Alexandre Belloni (4):
  clk: berlin: add driver for BG2x simple PLLs
  clk: berlin: add driver for BG2x complex divider cells
  clk: berlin: add core clock driver for BG2Q
  ARM: dts: berlin: convert BG2Q to DT clock nodes

Sebastian Hesselbarth (6):
  dt-binding: clk: add clock binding docs for Marvell Berlin2 SoCs
  clk: berlin: add binding include for BG2/BG2CD clock ids
  clk: berlin: add driver for BG2x audio/video PLL
  clk: berlin: add core clock driver for BG2/BG2CD
  ARM: dts: berlin: convert BG2CD to DT clock nodes
  ARM: dts: berlin: convert BG2 to DT clock nodes

 .../devicetree/bindings/clock/berlin2-clock.txt    | 195 ++++++++
 arch/arm/boot/dts/berlin2.dtsi                     | 207 +++++++--
 arch/arm/boot/dts/berlin2cd.dtsi                   | 205 +++++++--
 arch/arm/boot/dts/berlin2q.dtsi                    |  80 +++-
 drivers/clk/Makefile                               |   1 +
 drivers/clk/berlin/Makefile                        |   4 +
 drivers/clk/berlin/berlin2-avpll.c                 | 368 +++++++++++++++
 drivers/clk/berlin/berlin2-div.c                   | 324 +++++++++++++
 drivers/clk/berlin/berlin2-div.h                   |  80 ++++
 drivers/clk/berlin/berlin2-pll.c                   | 168 +++++++
 drivers/clk/berlin/bg2.c                           | 502 +++++++++++++++++++++
 drivers/clk/berlin/bg2q.c                          | 269 +++++++++++
 include/dt-bindings/clock/berlin2.h                |  35 ++
 include/dt-bindings/clock/berlin2q.h               |  28 ++
 14 files changed, 2385 insertions(+), 81 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/berlin2-clock.txt
 create mode 100644 drivers/clk/berlin/Makefile
 create mode 100644 drivers/clk/berlin/berlin2-avpll.c
 create mode 100644 drivers/clk/berlin/berlin2-div.c
 create mode 100644 drivers/clk/berlin/berlin2-div.h
 create mode 100644 drivers/clk/berlin/berlin2-pll.c
 create mode 100644 drivers/clk/berlin/bg2.c
 create mode 100644 drivers/clk/berlin/bg2q.c
 create mode 100644 include/dt-bindings/clock/berlin2.h
 create mode 100644 include/dt-bindings/clock/berlin2q.h

---
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Jisheng Zhang <jszhang@marvell.com>
Cc: devicetree@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
-- 
1.9.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2014-05-29  9:20 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-19 16:43 [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
2014-05-19 16:43 ` [PATCH v2 01/10] dt-binding: ARM: add clock binding docs for Marvell Berlin2 SoCs Sebastian Hesselbarth
2014-05-19 21:05   ` Alexandre Belloni
2014-05-19 16:43 ` [PATCH v2 02/10] clk: berlin: add binding include for Berlin SoC clock ids Sebastian Hesselbarth
2014-05-19 16:43 ` [PATCH v2 03/10] clk: berlin: add driver for BG2x audio/video PLL Sebastian Hesselbarth
2014-05-19 16:43 ` [PATCH v2 04/10] clk: berlin: add driver for BG2x simple PLLs Sebastian Hesselbarth
2014-05-19 16:43 ` [PATCH v2 05/10] clk: berlin: add driver for BG2x complex divider cells Sebastian Hesselbarth
2014-05-19 16:43 ` [PATCH v2 06/10] clk: berlin: add core clock driver for BG2/BG2CD Sebastian Hesselbarth
2014-05-19 21:06   ` Alexandre Belloni
2014-05-19 16:43 ` [PATCH v2 07/10] clk: berlin: add core clock driver for BG2Q Sebastian Hesselbarth
2014-05-19 16:43 ` [PATCH v2 08/10] ARM: dts: berlin: convert BG2CD to DT clock nodes Sebastian Hesselbarth
2014-05-19 21:07   ` Alexandre Belloni
2014-05-19 16:43 ` [PATCH v2 09/10] ARM: dts: berlin: convert BG2 " Sebastian Hesselbarth
2014-05-19 21:13   ` Alexandre Belloni
2014-05-19 16:43 ` [PATCH v2 10/10] ARM: dts: berlin: convert BG2Q " Sebastian Hesselbarth
2014-05-19 19:46 ` [PATCH v2 00/10] Marvell Berlin full clock support Sebastian Hesselbarth
2014-05-29  0:07 ` Mike Turquette
2014-05-29  9:20   ` Sebastian Hesselbarth
  -- strict thread matches above, loose matches on Subject: below --
2014-05-11 20:24 [PATCH 0/8] " Sebastian Hesselbarth
2014-05-14 20:15 ` [PATCH v2 00/10] " Sebastian Hesselbarth

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).