diff mbox

[v2,7/7] clk: ns2: add clock support for Broadcom Northstar 2 SoC

Message ID 1444770485-11210-8-git-send-email-jonmason@broadcom.com
State Superseded
Headers show

Commit Message

Jon Mason Oct. 13, 2015, 9:08 p.m. UTC
The Broadcom Northstar 2 SoC is architected under the iProc
architecture. It has the following PLLs: GENPLL SCR, GENPLL SW,
LCPLL DDR, LCPLL Ports, all derived from an onboard crystal.

Signed-off-by: Jon Mason <jonmason@broadcom.com>
---
 drivers/clk/Makefile                |   2 +-
 drivers/clk/bcm/Makefile            |   1 +
 drivers/clk/bcm/clk-ns2.c           | 288 ++++++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/bcm-ns2.h |  72 +++++++++
 4 files changed, 362 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/bcm/clk-ns2.c
 create mode 100644 include/dt-bindings/clock/bcm-ns2.h

Comments

Arnd Bergmann Oct. 13, 2015, 9:18 p.m. UTC | #1
On Tuesday 13 October 2015 17:08:05 Jon Mason wrote:
> @@ -3,6 +3,7 @@ obj-$(CONFIG_CLK_BCM_KONA)      += clk-kona-setup.o
>  obj-$(CONFIG_CLK_BCM_KONA)     += clk-bcm281xx.o
>  obj-$(CONFIG_CLK_BCM_KONA)     += clk-bcm21664.o
>  obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o
> +obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o
>  obj-$(CONFIG_ARCH_BCM_CYGNUS)  += clk-cygnus.o
>  obj-$(CONFIG_ARCH_BCM_NSP)     += clk-nsp.o
>  obj-$(CONFIG_ARCH_BCM_5301X)   += clk-nsp.o

If I understand this right, both CYGNUS and NS2 are IPROC based, but it
looks like you now require building the clk-ns2 file for both?

On a related note, I'm seeing problems when CONFIG_CYGNUS is set but
CONFIG_COMMON_CLK_IPROC is disabled, as that currently leads to a link
failure.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jon Mason Oct. 13, 2015, 10:04 p.m. UTC | #2
On Tue, Oct 13, 2015 at 11:18:53PM +0200, Arnd Bergmann wrote:
> On Tuesday 13 October 2015 17:08:05 Jon Mason wrote:
> > @@ -3,6 +3,7 @@ obj-$(CONFIG_CLK_BCM_KONA)      += clk-kona-setup.o
> >  obj-$(CONFIG_CLK_BCM_KONA)     += clk-bcm281xx.o
> >  obj-$(CONFIG_CLK_BCM_KONA)     += clk-bcm21664.o
> >  obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o
> > +obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o
> >  obj-$(CONFIG_ARCH_BCM_CYGNUS)  += clk-cygnus.o
> >  obj-$(CONFIG_ARCH_BCM_NSP)     += clk-nsp.o
> >  obj-$(CONFIG_ARCH_BCM_5301X)   += clk-nsp.o
> 
> If I understand this right, both CYGNUS and NS2 are IPROC based, but it
> looks like you now require building the clk-ns2 file for both?

There is no need for the NS2 clk code to be used by anything other
than NS2.  There is no unique CONFIG_ identifier for NS2 in the code
that was accepted upstream.  If I can add one for NS2, then I can
split this off similar to Cygnus or NSP.  If not, then it has to be
lumped in with all of iProc.  :(

> On a related note, I'm seeing problems when CONFIG_CYGNUS is set but
> CONFIG_COMMON_CLK_IPROC is disabled, as that currently leads to a link
> failure.

I can double check, but it should be on by default when Cygnus is
enabled.  If you send me the error, I'll be happy to fix it.

Thanks,
Jon

> 
> 	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Scott Branden Oct. 14, 2015, 7:46 p.m. UTC | #3
On 15-10-13 03:23 PM, Arnd Bergmann wrote:
> On Tuesday 13 October 2015 18:04:50 Jon Mason wrote:
>>
>>> On a related note, I'm seeing problems when CONFIG_CYGNUS is set but
>>> CONFIG_COMMON_CLK_IPROC is disabled, as that currently leads to a link
>>> failure.
>>
>> I can double check, but it should be on by default when Cygnus is
>> enabled.  If you send me the error, I'll be happy to fix it.
>
>
> The problem is not that it's off by default but that it can be
> disabled, so it breaks some 'make randconfig' builds with this
> message:
>
> drivers/built-in.o: In function `cygnus_armpll_init':
> :(.init.text+0x1d290): undefined reference to `iproc_armpll_setup'
> drivers/built-in.o: In function `cygnus_genpll_clk_init':
> :(.init.text+0x1d2c4): undefined reference to `iproc_pll_clk_setup'
> drivers/built-in.o: In function `cygnus_lcpll0_clk_init':
> :(.init.text+0x1d304): undefined reference to `iproc_pll_clk_setup'
> drivers/built-in.o: In function `cygnus_mipipll_clk_init':
> :(.init.text+0x1d344): undefined reference to `iproc_pll_clk_setup'
> drivers/built-in.o: In function `cygnus_asiu_init':
> :(.init.text+0x1d370): undefined reference to `iproc_asiu_setup'
>
> My patch fixes it by always selecting COMMON_CLK_IPROC from
> ARCH_BCM_CYGNUS. I wasn't sure whether you want COMMON_CLK_IPROC
> to still be user-selectable, so I left that in place. Normally
> I'd expect it to be a silent option though, that just gets
> implicitly enabled whenever a platform that needs it is built
> into the kernel.
COMMON_CLK_IPROC can be a silent option and selected as Arnd has done below.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Scott Branden <sbranden@broadcom.com>

>
> diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
> index 1319c3c14327..35234e563cd8 100644
> --- a/arch/arm/mach-bcm/Kconfig
> +++ b/arch/arm/mach-bcm/Kconfig
> @@ -29,6 +29,7 @@ config ARCH_BCM_IPROC
>   config ARCH_BCM_CYGNUS
>   	bool "Broadcom Cygnus Support" if ARCH_MULTI_V7
>   	select ARCH_BCM_IPROC
> +	select COMMON_CLK_IPROC
>   	help
>   	  Enable support for the Cygnus family,
>   	  which includes the following variants:
>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann Oct. 14, 2015, 8:16 p.m. UTC | #4
On Wednesday 14 October 2015 12:46:19 Scott Branden wrote:
> >
> > My patch fixes it by always selecting COMMON_CLK_IPROC from
> > ARCH_BCM_CYGNUS. I wasn't sure whether you want COMMON_CLK_IPROC
> > to still be user-selectable, so I left that in place. Normally
> > I'd expect it to be a silent option though, that just gets
> > implicitly enabled whenever a platform that needs it is built
> > into the kernel.
> COMMON_CLK_IPROC can be a silent option and selected as Arnd has done below.

Ok, please do that then. If you want to apply my patch directly,
you can remove that last paragraph from the description.

> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Acked-by: Scott Branden <sbranden@broadcom.com>

Thanks for taking a look!

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Scott Branden Oct. 15, 2015, 6:36 p.m. UTC | #5
Jon,

Can you add this to your patchset and change COMMON_CLK_IPROC to a 
silent option?

On 15-10-14 01:16 PM, Arnd Bergmann wrote:
> On Wednesday 14 October 2015 12:46:19 Scott Branden wrote:
>>>
>>> My patch fixes it by always selecting COMMON_CLK_IPROC from
>>> ARCH_BCM_CYGNUS. I wasn't sure whether you want COMMON_CLK_IPROC
>>> to still be user-selectable, so I left that in place. Normally
>>> I'd expect it to be a silent option though, that just gets
>>> implicitly enabled whenever a platform that needs it is built
>>> into the kernel.
>> COMMON_CLK_IPROC can be a silent option and selected as Arnd has done below.
>
> Ok, please do that then. If you want to apply my patch directly,
> you can remove that last paragraph from the description.
>
>>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> Acked-by: Scott Branden <sbranden@broadcom.com>
>
> Thanks for taking a look!
>
> 	Arnd
>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jon Mason Oct. 15, 2015, 6:43 p.m. UTC | #6
On Thu, Oct 15, 2015 at 11:36:19AM -0700, Scott Branden wrote:
> Jon,
> 
> Can you add this to your patchset and change COMMON_CLK_IPROC to a
> silent option?

Sure, I'll add this (and make it silent), as well as adding the
documentation patches back to this series (per Ray's suggestion), and
will resend.

Thanks,
Jon

> 
> On 15-10-14 01:16 PM, Arnd Bergmann wrote:
> >On Wednesday 14 October 2015 12:46:19 Scott Branden wrote:
> >>>
> >>>My patch fixes it by always selecting COMMON_CLK_IPROC from
> >>>ARCH_BCM_CYGNUS. I wasn't sure whether you want COMMON_CLK_IPROC
> >>>to still be user-selectable, so I left that in place. Normally
> >>>I'd expect it to be a silent option though, that just gets
> >>>implicitly enabled whenever a platform that needs it is built
> >>>into the kernel.
> >>COMMON_CLK_IPROC can be a silent option and selected as Arnd has done below.
> >
> >Ok, please do that then. If you want to apply my patch directly,
> >you can remove that last paragraph from the description.
> >
> >>>Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> >>Acked-by: Scott Branden <sbranden@broadcom.com>
> >
> >Thanks for taking a look!
> >
> >	Arnd
> >
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann Oct. 15, 2015, 6:54 p.m. UTC | #7
On Thursday 15 October 2015 14:43:45 Jon Mason wrote:
> On Thu, Oct 15, 2015 at 11:36:19AM -0700, Scott Branden wrote:
> > Jon,
> > 
> > Can you add this to your patchset and change COMMON_CLK_IPROC to a
> > silent option?
> 
> Sure, I'll add this (and make it silent), as well as adding the
> documentation patches back to this series (per Ray's suggestion), and
> will resend.
> 

Thanks!

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jon Mason Oct. 15, 2015, 7:23 p.m. UTC | #8
On Thu, Oct 15, 2015 at 08:54:34PM +0200, Arnd Bergmann wrote:
> On Thursday 15 October 2015 14:43:45 Jon Mason wrote:
> > On Thu, Oct 15, 2015 at 11:36:19AM -0700, Scott Branden wrote:
> > > Jon,
> > > 
> > > Can you add this to your patchset and change COMMON_CLK_IPROC to a
> > > silent option?
> > 
> > Sure, I'll add this (and make it silent), as well as adding the
> > documentation patches back to this series (per Ray's suggestion), and
> > will resend.
> > 
> 
> Thanks!
> 
> 	Arnd

I'm tweaking the patch slightly.  So, I'll remove Scott's ack and let
him re-ack if he still likes it.

I moved the selection of the COMMON_CLK_IPROC to ARCH_BCM_IPROC, as
all iProc SoCs will soon have clk drivers (and enabling it without a
SoC driver won't hurt anything).  Also, the slient enable option is
added.

Thanks,
Jon
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d08b3e5..6124bd3 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -47,7 +47,7 @@  obj-$(CONFIG_COMMON_CLK_WM831X)		+= clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_XGENE)		+= clk-xgene.o
 obj-$(CONFIG_COMMON_CLK_PWM)		+= clk-pwm.o
 obj-$(CONFIG_COMMON_CLK_AT91)		+= at91/
-obj-$(CONFIG_ARCH_BCM)			+= bcm/
+obj-y					+= bcm/
 obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
 obj-$(CONFIG_ARCH_HISI)			+= hisilicon/
 obj-$(CONFIG_ARCH_MXC)			+= imx/
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile
index e258b28..2d1cbc5 100644
--- a/drivers/clk/bcm/Makefile
+++ b/drivers/clk/bcm/Makefile
@@ -3,6 +3,7 @@  obj-$(CONFIG_CLK_BCM_KONA)	+= clk-kona-setup.o
 obj-$(CONFIG_CLK_BCM_KONA)	+= clk-bcm281xx.o
 obj-$(CONFIG_CLK_BCM_KONA)	+= clk-bcm21664.o
 obj-$(CONFIG_COMMON_CLK_IPROC)	+= clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o
+obj-$(CONFIG_COMMON_CLK_IPROC)	+= clk-ns2.o
 obj-$(CONFIG_ARCH_BCM_CYGNUS)	+= clk-cygnus.o
 obj-$(CONFIG_ARCH_BCM_NSP)	+= clk-nsp.o
 obj-$(CONFIG_ARCH_BCM_5301X)	+= clk-nsp.o
diff --git a/drivers/clk/bcm/clk-ns2.c b/drivers/clk/bcm/clk-ns2.c
new file mode 100644
index 0000000..a564e92
--- /dev/null
+++ b/drivers/clk/bcm/clk-ns2.c
@@ -0,0 +1,288 @@ 
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <dt-bindings/clock/bcm-ns2.h>
+#include "clk-iproc.h"
+
+#define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
+
+#define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
+	.pwr_shift = ps, .iso_shift = is }
+
+#define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
+	.p_reset_shift = prs }
+
+#define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\
+	.ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas,    \
+	.ka_width = kaw }
+
+#define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
+
+#define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
+	.hold_shift = hs, .bypass_shift = bs }
+
+static const struct iproc_pll_ctrl genpll_scr = {
+	.flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
+	.aon = AON_VAL(0x0, 1, 15, 12),
+	.reset = RESET_VAL(0x4, 2, 1),
+	.dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3),
+	.ndiv_int = REG_VAL(0x8, 4, 10),
+	.pdiv = REG_VAL(0x8, 0, 4),
+	.vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
+	.status = REG_VAL(0x0, 27, 1),
+};
+
+
+static const struct iproc_clk_ctrl genpll_scr_clk[] = {
+	/* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
+	 * in NS2.  However, it doesn't appear to be used anywhere, so setting
+	 * it to 0.
+	 */
+	[BCM_NS2_GENPLL_SCR_SCR_CLK] = {
+		.channel = BCM_NS2_GENPLL_SCR_SCR_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 18, 12, 0),
+		.mdiv = REG_VAL(0x18, 0, 8),
+	},
+	[BCM_NS2_GENPLL_SCR_FS_CLK] = {
+		.channel = BCM_NS2_GENPLL_SCR_FS_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 19, 13, 0),
+		.mdiv = REG_VAL(0x18, 8, 8),
+	},
+	[BCM_NS2_GENPLL_SCR_AUDIO_CLK] = {
+		.channel = BCM_NS2_GENPLL_SCR_AUDIO_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 20, 14, 0),
+		.mdiv = REG_VAL(0x14, 0, 8),
+	},
+	[BCM_NS2_GENPLL_SCR_CH3_UNUSED] = {
+		.channel = BCM_NS2_GENPLL_SCR_CH3_UNUSED,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 21, 15, 0),
+		.mdiv = REG_VAL(0x14, 8, 8),
+	},
+	[BCM_NS2_GENPLL_SCR_CH4_UNUSED] = {
+		.channel = BCM_NS2_GENPLL_SCR_CH4_UNUSED,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 22, 16, 0),
+		.mdiv = REG_VAL(0x14, 16, 8),
+	},
+	[BCM_NS2_GENPLL_SCR_CH5_UNUSED] = {
+		.channel = BCM_NS2_GENPLL_SCR_CH5_UNUSED,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 23, 17, 0),
+		.mdiv = REG_VAL(0x14, 24, 8),
+	},
+};
+
+static void __init ns2_genpll_scr_clk_init(struct device_node *node)
+{
+	iproc_pll_clk_setup(node, &genpll_scr, NULL, 0, genpll_scr_clk,
+			    ARRAY_SIZE(genpll_scr_clk));
+}
+CLK_OF_DECLARE(ns2_genpll_src_clk, "brcm,ns2-genpll-scr",
+	       ns2_genpll_scr_clk_init);
+
+static const struct iproc_pll_ctrl genpll_sw = {
+	.flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
+	.aon = AON_VAL(0x0, 2, 9, 8),
+	.reset = RESET_VAL(0x4, 2, 1),
+	.dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3),
+	.ndiv_int = REG_VAL(0x8, 4, 10),
+	.pdiv = REG_VAL(0x8, 0, 4),
+	.vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
+	.status = REG_VAL(0x0, 13, 1),
+};
+
+static const struct iproc_clk_ctrl genpll_sw_clk[] = {
+	/* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
+	 * in NS2.  However, it doesn't appear to be used anywhere, so setting
+	 * it to 0.
+	 */
+	[BCM_NS2_GENPLL_SW_RPE_CLK] = {
+		.channel = BCM_NS2_GENPLL_SW_RPE_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 18, 12, 0),
+		.mdiv = REG_VAL(0x18, 0, 8),
+	},
+	[BCM_NS2_GENPLL_SW_250_CLK] = {
+		.channel = BCM_NS2_GENPLL_SW_250_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 19, 13, 0),
+		.mdiv = REG_VAL(0x18, 8, 8),
+	},
+	[BCM_NS2_GENPLL_SW_NIC_CLK] = {
+		.channel = BCM_NS2_GENPLL_SW_NIC_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 20, 14, 0),
+		.mdiv = REG_VAL(0x14, 0, 8),
+	},
+	[BCM_NS2_GENPLL_SW_CHIMP_CLK] = {
+		.channel = BCM_NS2_GENPLL_SW_CHIMP_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 21, 15, 0),
+		.mdiv = REG_VAL(0x14, 8, 8),
+	},
+	[BCM_NS2_GENPLL_SW_PORT_CLK] = {
+		.channel = BCM_NS2_GENPLL_SW_PORT_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 22, 16, 0),
+		.mdiv = REG_VAL(0x14, 16, 8),
+	},
+	[BCM_NS2_GENPLL_SW_SDIO_CLK] = {
+		.channel = BCM_NS2_GENPLL_SW_SDIO_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 23, 17, 0),
+		.mdiv = REG_VAL(0x14, 24, 8),
+	},
+};
+
+static void __init ns2_genpll_sw_clk_init(struct device_node *node)
+{
+	iproc_pll_clk_setup(node, &genpll_sw, NULL, 0, genpll_sw_clk,
+			    ARRAY_SIZE(genpll_sw_clk));
+}
+CLK_OF_DECLARE(ns2_genpll_sw_clk, "brcm,ns2-genpll-sw",
+	       ns2_genpll_sw_clk_init);
+
+static const struct iproc_pll_ctrl lcpll_ddr = {
+	.flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
+	.aon = AON_VAL(0x0, 2, 1, 0),
+	.reset = RESET_VAL(0x4, 2, 1),
+	.dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 1, 4),
+	.ndiv_int = REG_VAL(0x8, 4, 10),
+	.pdiv = REG_VAL(0x8, 0, 4),
+	.vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
+	.status = REG_VAL(0x0, 0, 1),
+};
+
+static const struct iproc_clk_ctrl lcpll_ddr_clk[] = {
+	/* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
+	 * in NS2.  However, it doesn't appear to be used anywhere, so setting
+	 * it to 0.
+	 */
+	[BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK] = {
+		.channel = BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 18, 12, 0),
+		.mdiv = REG_VAL(0x14, 0, 8),
+	},
+	[BCM_NS2_LCPLL_DDR_DDR_CLK] = {
+		.channel = BCM_NS2_LCPLL_DDR_DDR_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 19, 13, 0),
+		.mdiv = REG_VAL(0x14, 8, 8),
+	},
+	[BCM_NS2_LCPLL_DDR_CH2_UNUSED] = {
+		.channel = BCM_NS2_LCPLL_DDR_CH2_UNUSED,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 20, 14, 0),
+		.mdiv = REG_VAL(0x10, 0, 8),
+	},
+	[BCM_NS2_LCPLL_DDR_CH3_UNUSED] = {
+		.channel = BCM_NS2_LCPLL_DDR_CH3_UNUSED,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 21, 15, 0),
+		.mdiv = REG_VAL(0x10, 8, 8),
+	},
+	[BCM_NS2_LCPLL_DDR_CH4_UNUSED] = {
+		.channel = BCM_NS2_LCPLL_DDR_CH4_UNUSED,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 22, 16, 0),
+		.mdiv = REG_VAL(0x10, 16, 8),
+	},
+	[BCM_NS2_LCPLL_DDR_CH5_UNUSED] = {
+		.channel = BCM_NS2_LCPLL_DDR_CH5_UNUSED,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 23, 17, 0),
+		.mdiv = REG_VAL(0x10, 24, 8),
+	},
+};
+
+static void __init ns2_lcpll_ddr_clk_init(struct device_node *node)
+{
+	iproc_pll_clk_setup(node, &lcpll_ddr, NULL, 0, lcpll_ddr_clk,
+			    ARRAY_SIZE(lcpll_ddr_clk));
+}
+CLK_OF_DECLARE(ns2_lcpll_ddr_clk, "brcm,ns2-lcpll-ddr",
+	       ns2_lcpll_ddr_clk_init);
+
+static const struct iproc_pll_ctrl lcpll_ports = {
+	.flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
+	.aon = AON_VAL(0x0, 2, 5, 4),
+	.reset = RESET_VAL(0x4, 2, 1),
+	.dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 1, 4),
+	.ndiv_int = REG_VAL(0x8, 4, 10),
+	.pdiv = REG_VAL(0x8, 0, 4),
+	.vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
+	.status = REG_VAL(0x0, 0, 1),
+};
+
+static const struct iproc_clk_ctrl lcpll_ports_clk[] = {
+	/* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
+	 * in NS2.  However, it doesn't appear to be used anywhere, so setting
+	 * it to 0.
+	 */
+	[BCM_NS2_LCPLL_PORTS_WAN_CLK] = {
+		.channel = BCM_NS2_LCPLL_PORTS_WAN_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 18, 12, 0),
+		.mdiv = REG_VAL(0x14, 0, 8),
+	},
+	[BCM_NS2_LCPLL_PORTS_RGMII_CLK] = {
+		.channel = BCM_NS2_LCPLL_PORTS_RGMII_CLK,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 19, 13, 0),
+		.mdiv = REG_VAL(0x14, 8, 8),
+	},
+	[BCM_NS2_LCPLL_PORTS_CH2_UNUSED] = {
+		.channel = BCM_NS2_LCPLL_PORTS_CH2_UNUSED,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 20, 14, 0),
+		.mdiv = REG_VAL(0x10, 0, 8),
+	},
+	[BCM_NS2_LCPLL_PORTS_CH3_UNUSED] = {
+		.channel = BCM_NS2_LCPLL_PORTS_CH3_UNUSED,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 21, 15, 0),
+		.mdiv = REG_VAL(0x10, 8, 8),
+	},
+	[BCM_NS2_LCPLL_PORTS_CH4_UNUSED] = {
+		.channel = BCM_NS2_LCPLL_PORTS_CH4_UNUSED,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 22, 16, 0),
+		.mdiv = REG_VAL(0x10, 16, 8),
+	},
+	[BCM_NS2_LCPLL_PORTS_CH5_UNUSED] = {
+		.channel = BCM_NS2_LCPLL_PORTS_CH5_UNUSED,
+		.flags = IPROC_CLK_AON,
+		.enable = ENABLE_VAL(0x0, 23, 17, 0),
+		.mdiv = REG_VAL(0x10, 24, 8),
+	},
+};
+
+static void __init ns2_lcpll_ports_clk_init(struct device_node *node)
+{
+	iproc_pll_clk_setup(node, &lcpll_ports, NULL, 0, lcpll_ports_clk,
+			    ARRAY_SIZE(lcpll_ports_clk));
+}
+CLK_OF_DECLARE(ns2_lcpll_ports_clk, "brcm,ns2-lcpll-ports",
+	       ns2_lcpll_ports_clk_init);
diff --git a/include/dt-bindings/clock/bcm-ns2.h b/include/dt-bindings/clock/bcm-ns2.h
new file mode 100644
index 0000000..d99c7a2
--- /dev/null
+++ b/include/dt-bindings/clock/bcm-ns2.h
@@ -0,0 +1,72 @@ 
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CLOCK_BCM_NS2_H
+#define _CLOCK_BCM_NS2_H
+
+/* GENPLL SCR clock channel ID */
+#define BCM_NS2_GENPLL_SCR		0
+#define BCM_NS2_GENPLL_SCR_SCR_CLK	1
+#define BCM_NS2_GENPLL_SCR_FS_CLK	2
+#define BCM_NS2_GENPLL_SCR_AUDIO_CLK	3
+#define BCM_NS2_GENPLL_SCR_CH3_UNUSED	4
+#define BCM_NS2_GENPLL_SCR_CH4_UNUSED	5
+#define BCM_NS2_GENPLL_SCR_CH5_UNUSED	6
+
+/* GENPLL SW clock channel ID */
+#define BCM_NS2_GENPLL_SW		0
+#define BCM_NS2_GENPLL_SW_RPE_CLK	1
+#define BCM_NS2_GENPLL_SW_250_CLK	2
+#define BCM_NS2_GENPLL_SW_NIC_CLK	3
+#define BCM_NS2_GENPLL_SW_CHIMP_CLK	4
+#define BCM_NS2_GENPLL_SW_PORT_CLK	5
+#define BCM_NS2_GENPLL_SW_SDIO_CLK	6
+
+/* LCPLL DDR clock channel ID */
+#define BCM_NS2_LCPLL_DDR		0
+#define BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK	1
+#define BCM_NS2_LCPLL_DDR_DDR_CLK	2
+#define BCM_NS2_LCPLL_DDR_CH2_UNUSED	3
+#define BCM_NS2_LCPLL_DDR_CH3_UNUSED	4
+#define BCM_NS2_LCPLL_DDR_CH4_UNUSED	5
+#define BCM_NS2_LCPLL_DDR_CH5_UNUSED	6
+
+/* LCPLL PORTS clock channel ID */
+#define BCM_NS2_LCPLL_PORTS		0
+#define BCM_NS2_LCPLL_PORTS_WAN_CLK	1
+#define BCM_NS2_LCPLL_PORTS_RGMII_CLK	2
+#define BCM_NS2_LCPLL_PORTS_CH2_UNUSED	3
+#define BCM_NS2_LCPLL_PORTS_CH3_UNUSED	4
+#define BCM_NS2_LCPLL_PORTS_CH4_UNUSED	5
+#define BCM_NS2_LCPLL_PORTS_CH5_UNUSED	6
+
+#endif /* _CLOCK_BCM_NS2_H */