diff mbox

[RESEND,1/5] ARM: BCM63XX: add basic support for the Broadcom BCM63138 DSL SoC

Message ID 1398130758-19456-2-git-send-email-f.fainelli@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Florian Fainelli April 22, 2014, 1:39 a.m. UTC
This patch adds basic support for the Broadcom BCM63138 DSL SoC which is
using a dual-core Cortex A9 system. Add the very minimum required code
boot Linux on this SoC.

Due to the two specific register address spaces located at 0x8000_0000
and 0xfffe_0000, we need to setup a specific iotable descriptor for
those to be remapped at the expected virtual addresses.

Finally, the PL310 cache controller requires a bit of tweaking before
handing its initialization over l2x0_of_init(), this is also taken care
of to make sure that its size is properly configured.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 .../devicetree/bindings/arm/bcm/bcm63138.txt       |  9 +++
 arch/arm/mach-bcm/Kconfig                          | 20 +++++
 arch/arm/mach-bcm/Makefile                         |  1 +
 arch/arm/mach-bcm/bcm63xx.h                        | 29 +++++++
 arch/arm/mach-bcm/board_bcm63xx.c                  | 94 ++++++++++++++++++++++
 5 files changed, 153 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/bcm/bcm63138.txt
 create mode 100644 arch/arm/mach-bcm/bcm63xx.h
 create mode 100644 arch/arm/mach-bcm/board_bcm63xx.c

Comments

Arnd Bergmann April 22, 2014, 10:45 a.m. UTC | #1
On Monday 21 April 2014 18:39:14 Florian Fainelli wrote:
> This patch adds basic support for the Broadcom BCM63138 DSL SoC which is
> using a dual-core Cortex A9 system. Add the very minimum required code
> boot Linux on this SoC.
> 
> Due to the two specific register address spaces located at 0x8000_0000
> and 0xfffe_0000, we need to setup a specific iotable descriptor for
> those to be remapped at the expected virtual addresses.

What is the significance of the "expected virtual address"? All drivers
nowadays should call ioremap() and use whatever virtual address comes
out of that.

> Finally, the PL310 cache controller requires a bit of tweaking before
> handing its initialization over l2x0_of_init(), this is also taken care
> of to make sure that its size is properly configured.

Russell has just spent a lot of work on cleaning up the l2x0 setup
of various platforms. I really don't want to see new platform specific
code for this.

> diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
> index 49c914cd9c7a..26b51bcf878c 100644
> --- a/arch/arm/mach-bcm/Kconfig
> +++ b/arch/arm/mach-bcm/Kconfig
> @@ -69,6 +69,26 @@ config ARCH_BCM_5301X
>  	  different SoC or with the older BCM47XX and BCM53XX based
>  	  network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
>  
> +config ARCH_BCM_63XX
> +	bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7
> +	depends on MMU
> +	select ARM_ERRATA_754322
> +	select ARM_ERRATA_764369 if SMP
> +	select ARM_GIC
> +	select ARM_GLOBAL_TIMER
> +	select CACHE_L2X0
> +	select COMMON_CLK
> +	select CPU_V7
> +	select GENERIC_CLOCKEVENTS
> +	select HAVE_ARM_ARCH_TIMER
> +	select HAVE_ARM_TWD if SMP
> +	select HAVE_ARM_SCU if SMP
> +	select HAVE_SMP

A lot of these are already selected by ARCH_MULTI_V7 and can be
omitted here.

> +#ifndef __ARM_BCM63XX_H
> +#define __ARM_BCM63XX_H
> +
> +#define IO_ADDRESS(x)		(((x) & 0x00ffffff) + 0xfc000000)
> +
> +/* AHB register space */
> +#define BCM63XX_AHB_PHYS	0x80001000
> +#define BCM63XX_AHB_VIRT	IO_ADDRESS(BCM63XX_AHB_PHYS)
> +#define BCM63XX_AHB_SIZE	0x800000
> +
> +/* PERIPH (legacy) register space */
> +#define BCM63XX_PERIPH_PHYS	0xfffe8000
> +#define BCM63XX_PERIPH_VIRT	IO_ADDRESS(BCM63XX_PERIPH_PHYS)
> +#define BCM63XX_PERIPH_SIZE	0x10000

You shouldn't need these any more. If you do, just move all of this
into the main file, to ensure no other file accidentally relies
on hardcoded values.

Note that BCM63XX_AHB_PHYS is nor aligned, so AFAICT you don't
actually get a huge page entry for it, and there is no point
doing this at all, as it has neither functional nor performance
relevance.

You may have out-of-tree drivers that you haven't cleaned up
or posted yet relying on specific static mappings, but that is
no reason to have these mappings in the mainline kernel.

> diff --git a/arch/arm/mach-bcm/board_bcm63xx.c b/arch/arm/mach-bcm/board_bcm63xx.c
> new file mode 100644
> index 000000000000..a779aca673c4
> --- /dev/null
> +++ b/arch/arm/mach-bcm/board_bcm63xx.c

Maybe just "bcm63xx.c"? We don't really do "board" files any more.

> +static void __init bcm63xx_l2cc_init(void)
> +{
> +	u32 auxctl_val = 0, auxctl_msk = ~0UL;
> +
> +	/* 16-way cache */
> +	auxctl_val |= (1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT);
> +	auxctl_msk &= ~(1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT);
> +	/* 32 KB */
> +	auxctl_val |= (2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
> +	auxctl_msk &= ~(L2X0_AUX_CTRL_WAY_SIZE_MASK);
> +
> +	/*
> +	 * Set bit 22 in the auxiliary control register. If this bit
> +	 * is cleared, PL310 treats Normal Shared Non-cacheable
> +	 * accesses as Cacheable no-allocate.
> +	 */
> +	auxctl_val |= (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT);
> +
> +	/* Allow non-secure access */
> +	auxctl_val |= (1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT);
> +	/* Instruction prefetch */
> +	auxctl_val |= (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT);
> +	/* Early BRESP */
> +	auxctl_val |= (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT);
> +
> +	l2x0_of_init(auxctl_val, auxctl_msk);
> +}

What are the power-on values of bits you override here? Are you sure
you have to force all of them?

Don't we already have ways to specify the same things in DT properties?

	Arnd
Florian Fainelli May 2, 2014, 5:32 a.m. UTC | #2
2014-04-22 3:45 GMT-07:00 Arnd Bergmann <arnd@arndb.de>:
> On Monday 21 April 2014 18:39:14 Florian Fainelli wrote:
>> This patch adds basic support for the Broadcom BCM63138 DSL SoC which is
>> using a dual-core Cortex A9 system. Add the very minimum required code
>> boot Linux on this SoC.
>>
>> Due to the two specific register address spaces located at 0x8000_0000
>> and 0xfffe_0000, we need to setup a specific iotable descriptor for
>> those to be remapped at the expected virtual addresses.
>
> What is the significance of the "expected virtual address"? All drivers
> nowadays should call ioremap() and use whatever virtual address comes
> out of that.
>
>> Finally, the PL310 cache controller requires a bit of tweaking before
>> handing its initialization over l2x0_of_init(), this is also taken care
>> of to make sure that its size is properly configured.
>
> Russell has just spent a lot of work on cleaning up the l2x0 setup
> of various platforms. I really don't want to see new platform specific
> code for this.

Ok, I will try with his cleanup patchset applied and see if I need any
platform specific implementation.

>
>> diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
>> index 49c914cd9c7a..26b51bcf878c 100644
>> --- a/arch/arm/mach-bcm/Kconfig
>> +++ b/arch/arm/mach-bcm/Kconfig
>> @@ -69,6 +69,26 @@ config ARCH_BCM_5301X
>>         different SoC or with the older BCM47XX and BCM53XX based
>>         network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
>>
>> +config ARCH_BCM_63XX
>> +     bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7
>> +     depends on MMU
>> +     select ARM_ERRATA_754322
>> +     select ARM_ERRATA_764369 if SMP
>> +     select ARM_GIC
>> +     select ARM_GLOBAL_TIMER
>> +     select CACHE_L2X0
>> +     select COMMON_CLK
>> +     select CPU_V7
>> +     select GENERIC_CLOCKEVENTS
>> +     select HAVE_ARM_ARCH_TIMER
>> +     select HAVE_ARM_TWD if SMP
>> +     select HAVE_ARM_SCU if SMP
>> +     select HAVE_SMP
>
> A lot of these are already selected by ARCH_MULTI_V7 and can be
> omitted here.
>
>> +#ifndef __ARM_BCM63XX_H
>> +#define __ARM_BCM63XX_H
>> +
>> +#define IO_ADDRESS(x)                (((x) & 0x00ffffff) + 0xfc000000)
>> +
>> +/* AHB register space */
>> +#define BCM63XX_AHB_PHYS     0x80001000
>> +#define BCM63XX_AHB_VIRT     IO_ADDRESS(BCM63XX_AHB_PHYS)
>> +#define BCM63XX_AHB_SIZE     0x800000
>> +
>> +/* PERIPH (legacy) register space */
>> +#define BCM63XX_PERIPH_PHYS  0xfffe8000
>> +#define BCM63XX_PERIPH_VIRT  IO_ADDRESS(BCM63XX_PERIPH_PHYS)
>> +#define BCM63XX_PERIPH_SIZE  0x10000
>
> You shouldn't need these any more. If you do, just move all of this
> into the main file, to ensure no other file accidentally relies
> on hardcoded values.
>
> Note that BCM63XX_AHB_PHYS is nor aligned, so AFAICT you don't
> actually get a huge page entry for it, and there is no point
> doing this at all, as it has neither functional nor performance
> relevance.
>
> You may have out-of-tree drivers that you haven't cleaned up
> or posted yet relying on specific static mappings, but that is
> no reason to have these mappings in the mainline kernel.

I tried without the iotable entries, and any register access to these
regions did hang the system, I will check harder what was going on
there.

>
>> diff --git a/arch/arm/mach-bcm/board_bcm63xx.c b/arch/arm/mach-bcm/board_bcm63xx.c
>> new file mode 100644
>> index 000000000000..a779aca673c4
>> --- /dev/null
>> +++ b/arch/arm/mach-bcm/board_bcm63xx.c
>
> Maybe just "bcm63xx.c"? We don't really do "board" files any more.

Makes sense, there is nothing board specific here (and there should
not be anyway).

>
>> +static void __init bcm63xx_l2cc_init(void)
>> +{
>> +     u32 auxctl_val = 0, auxctl_msk = ~0UL;
>> +
>> +     /* 16-way cache */
>> +     auxctl_val |= (1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT);
>> +     auxctl_msk &= ~(1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT);
>> +     /* 32 KB */
>> +     auxctl_val |= (2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
>> +     auxctl_msk &= ~(L2X0_AUX_CTRL_WAY_SIZE_MASK);
>> +
>> +     /*
>> +      * Set bit 22 in the auxiliary control register. If this bit
>> +      * is cleared, PL310 treats Normal Shared Non-cacheable
>> +      * accesses as Cacheable no-allocate.
>> +      */
>> +     auxctl_val |= (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT);
>> +
>> +     /* Allow non-secure access */
>> +     auxctl_val |= (1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT);
>> +     /* Instruction prefetch */
>> +     auxctl_val |= (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT);
>> +     /* Early BRESP */
>> +     auxctl_val |= (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT);
>> +
>> +     l2x0_of_init(auxctl_val, auxctl_msk);
>> +}
>
> What are the power-on values of bits you override here? Are you sure
> you have to force all of them?
>
> Don't we already have ways to specify the same things in DT properties?
>
>         Arnd
Arnd Bergmann May 2, 2014, 7:55 a.m. UTC | #3
On Thursday 01 May 2014 22:32:27 Florian Fainelli wrote:
> >> +#ifndef __ARM_BCM63XX_H
> >> +#define __ARM_BCM63XX_H
> >> +
> >> +#define IO_ADDRESS(x)                (((x) & 0x00ffffff) + 0xfc000000)
> >> +
> >> +/* AHB register space */
> >> +#define BCM63XX_AHB_PHYS     0x80001000
> >> +#define BCM63XX_AHB_VIRT     IO_ADDRESS(BCM63XX_AHB_PHYS)
> >> +#define BCM63XX_AHB_SIZE     0x800000
> >> +
> >> +/* PERIPH (legacy) register space */
> >> +#define BCM63XX_PERIPH_PHYS  0xfffe8000
> >> +#define BCM63XX_PERIPH_VIRT  IO_ADDRESS(BCM63XX_PERIPH_PHYS)
> >> +#define BCM63XX_PERIPH_SIZE  0x10000
> >
> > You shouldn't need these any more. If you do, just move all of this
> > into the main file, to ensure no other file accidentally relies
> > on hardcoded values.
> >
> > Note that BCM63XX_AHB_PHYS is nor aligned, so AFAICT you don't
> > actually get a huge page entry for it, and there is no point
> > doing this at all, as it has neither functional nor performance
> > relevance.
> >
> > You may have out-of-tree drivers that you haven't cleaned up
> > or posted yet relying on specific static mappings, but that is
> > no reason to have these mappings in the mainline kernel.
> 
> I tried without the iotable entries, and any register access to these
> regions did hang the system, I will check harder what was going on
> there.

Can you clarify what you mean with 'any register access to these
regions did hang the system'? If you remove the call to iotable_init,
you obviously can't access the registers through BCM63XX_{AHB,PERIPH}_VIRT
any longer, but accesses through a pointer returned from ioremap()
should keep working as before.

The DEBUG_LL early output is a special case here, these need one
of three options:

- .map_io is NULL (preferred)
- .map_io points to a function that calls debug_ll_io_init()
- .map_io points to a function that calls iotable_init with
  an equivalent or larger mapping as debug_ll_io_init() would.

I suspect you were doing the third here for historic reasons.

	Arnd
Florian Fainelli May 5, 2014, 10:41 p.m. UTC | #4
2014-05-02 0:55 GMT-07:00 Arnd Bergmann <arnd@arndb.de>:
> On Thursday 01 May 2014 22:32:27 Florian Fainelli wrote:
>> >> +#ifndef __ARM_BCM63XX_H
>> >> +#define __ARM_BCM63XX_H
>> >> +
>> >> +#define IO_ADDRESS(x)                (((x) & 0x00ffffff) + 0xfc000000)
>> >> +
>> >> +/* AHB register space */
>> >> +#define BCM63XX_AHB_PHYS     0x80001000
>> >> +#define BCM63XX_AHB_VIRT     IO_ADDRESS(BCM63XX_AHB_PHYS)
>> >> +#define BCM63XX_AHB_SIZE     0x800000
>> >> +
>> >> +/* PERIPH (legacy) register space */
>> >> +#define BCM63XX_PERIPH_PHYS  0xfffe8000
>> >> +#define BCM63XX_PERIPH_VIRT  IO_ADDRESS(BCM63XX_PERIPH_PHYS)
>> >> +#define BCM63XX_PERIPH_SIZE  0x10000
>> >
>> > You shouldn't need these any more. If you do, just move all of this
>> > into the main file, to ensure no other file accidentally relies
>> > on hardcoded values.
>> >
>> > Note that BCM63XX_AHB_PHYS is nor aligned, so AFAICT you don't
>> > actually get a huge page entry for it, and there is no point
>> > doing this at all, as it has neither functional nor performance
>> > relevance.
>> >
>> > You may have out-of-tree drivers that you haven't cleaned up
>> > or posted yet relying on specific static mappings, but that is
>> > no reason to have these mappings in the mainline kernel.
>>
>> I tried without the iotable entries, and any register access to these
>> regions did hang the system, I will check harder what was going on
>> there.
>
> Can you clarify what you mean with 'any register access to these
> regions did hang the system'?

I would not get any console output progress around the time we
initialize the MMU (roughly), neither would I get an exception since
that is too early in the boot process.

> If you remove the call to iotable_init,
> you obviously can't access the registers through BCM63XX_{AHB,PERIPH}_VIRT
> any longer, but accesses through a pointer returned from ioremap()
> should keep working as before.
>
> The DEBUG_LL early output is a special case here, these need one
> of three options:
>
> - .map_io is NULL (preferred)
> - .map_io points to a function that calls debug_ll_io_init()
> - .map_io points to a function that calls iotable_init with
>   an equivalent or larger mapping as debug_ll_io_init() would.
>
> I suspect you were doing the third here for historic reasons.

I think you are right, I was in the 3rd case where accessing the UART
using its virtual address would make the system. Reading through
devicemaps_init(), defining a custom map_io() functions means you are
in control and you explicitely need to call debug_ll_io_init(), which
I was not doing when I removed my custom map_io() implementation.

Thanks!
Arnd Bergmann May 6, 2014, 9:32 a.m. UTC | #5
On Monday 05 May 2014 15:41:43 Florian Fainelli wrote:
> 2014-05-02 0:55 GMT-07:00 Arnd Bergmann <arnd@arndb.de>:
> > On Thursday 01 May 2014 22:32:27 Florian Fainelli wrote:
> > If you remove the call to iotable_init,
> > you obviously can't access the registers through BCM63XX_{AHB,PERIPH}_VIRT
> > any longer, but accesses through a pointer returned from ioremap()
> > should keep working as before.
> >
> > The DEBUG_LL early output is a special case here, these need one
> > of three options:
> >
> > - .map_io is NULL (preferred)
> > - .map_io points to a function that calls debug_ll_io_init()
> > - .map_io points to a function that calls iotable_init with
> >   an equivalent or larger mapping as debug_ll_io_init() would.
> >
> > I suspect you were doing the third here for historic reasons.
> 
> I think you are right, I was in the 3rd case where accessing the UART
> using its virtual address would make the system. Reading through
> devicemaps_init(), defining a custom map_io() functions means you are
> in control and you explicitely need to call debug_ll_io_init(), which
> I was not doing when I removed my custom map_io() implementation.

Ok, so I guess it should all work now if you remove the function from
the submission, or keep one in your private tree that sets up any
mapping needed by drivers that are not converted along with
debug_ll_io_init().

	Arnd
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/arm/bcm/bcm63138.txt b/Documentation/devicetree/bindings/arm/bcm/bcm63138.txt
new file mode 100644
index 000000000000..bd49987a8812
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/bcm/bcm63138.txt
@@ -0,0 +1,9 @@ 
+Broadcom BCM63138 DSL System-on-a-Chip device tree bindings
+-----------------------------------------------------------
+
+Boards compatible with the BCM63138 DSL System-on-a-Chip should have the
+following properties:
+
+Required root node property:
+
+compatible: should be "brcm,bcm63138"
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 49c914cd9c7a..26b51bcf878c 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -69,6 +69,26 @@  config ARCH_BCM_5301X
 	  different SoC or with the older BCM47XX and BCM53XX based
 	  network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
 
+config ARCH_BCM_63XX
+	bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7
+	depends on MMU
+	select ARM_ERRATA_754322
+	select ARM_ERRATA_764369 if SMP
+	select ARM_GIC
+	select ARM_GLOBAL_TIMER
+	select CACHE_L2X0
+	select COMMON_CLK
+	select CPU_V7
+	select GENERIC_CLOCKEVENTS
+	select HAVE_ARM_ARCH_TIMER
+	select HAVE_ARM_TWD if SMP
+	select HAVE_ARM_SCU if SMP
+	select HAVE_SMP
+	help
+	  This enables support for systems based on Broadcom DSL SoCs.
+	  It currently supports the 'BCM63XX' ARM-based family, which includes
+	  the BCM63138 variant.
+
 endmenu
 
 endif
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index a326b28c4406..c24ba586297d 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -17,3 +17,4 @@  obj-$(CONFIG_ARCH_BCM2835)	+= board_bcm2835.o
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_bcm_kona_smc_asm.o	:=-Wa,-march=armv7-a$(plus_sec)
 obj-$(CONFIG_ARCH_BCM_5301X)	+= bcm_5301x.o
+obj-$(CONFIG_ARCH_BCM_63XX)	:= board_bcm63xx.o
diff --git a/arch/arm/mach-bcm/bcm63xx.h b/arch/arm/mach-bcm/bcm63xx.h
new file mode 100644
index 000000000000..95872c8131f6
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm63xx.h
@@ -0,0 +1,29 @@ 
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef __ARM_BCM63XX_H
+#define __ARM_BCM63XX_H
+
+#define IO_ADDRESS(x)		(((x) & 0x00ffffff) + 0xfc000000)
+
+/* AHB register space */
+#define BCM63XX_AHB_PHYS	0x80001000
+#define BCM63XX_AHB_VIRT	IO_ADDRESS(BCM63XX_AHB_PHYS)
+#define BCM63XX_AHB_SIZE	0x800000
+
+/* PERIPH (legacy) register space */
+#define BCM63XX_PERIPH_PHYS	0xfffe8000
+#define BCM63XX_PERIPH_VIRT	IO_ADDRESS(BCM63XX_PERIPH_PHYS)
+#define BCM63XX_PERIPH_SIZE	0x10000
+
+#endif /* __ARM_BCM63XX_H */
diff --git a/arch/arm/mach-bcm/board_bcm63xx.c b/arch/arm/mach-bcm/board_bcm63xx.c
new file mode 100644
index 000000000000..a779aca673c4
--- /dev/null
+++ b/arch/arm/mach-bcm/board_bcm63xx.c
@@ -0,0 +1,94 @@ 
+/*
+ * Copyright (C) 2014 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/of_platform.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/clocksource.h>
+#include <linux/irqchip.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "bcm63xx.h"
+
+static void __init bcm63xx_l2cc_init(void)
+{
+	u32 auxctl_val = 0, auxctl_msk = ~0UL;
+
+	/* 16-way cache */
+	auxctl_val |= (1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT);
+	auxctl_msk &= ~(1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT);
+	/* 32 KB */
+	auxctl_val |= (2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
+	auxctl_msk &= ~(L2X0_AUX_CTRL_WAY_SIZE_MASK);
+
+	/*
+	 * Set bit 22 in the auxiliary control register. If this bit
+	 * is cleared, PL310 treats Normal Shared Non-cacheable
+	 * accesses as Cacheable no-allocate.
+	 */
+	auxctl_val |= (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT);
+
+	/* Allow non-secure access */
+	auxctl_val |= (1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT);
+	/* Instruction prefetch */
+	auxctl_val |= (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT);
+	/* Early BRESP */
+	auxctl_val |= (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT);
+
+	l2x0_of_init(auxctl_val, auxctl_msk);
+}
+
+static void __init bcm63xx_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL,
+		&platform_bus);
+	bcm63xx_l2cc_init();
+}
+
+static const char * const bcm63xx_dt_compat[] = {
+	"brcm,bcm63138",
+	NULL
+};
+
+static struct map_desc bcm63xx_map_desc[] __initdata = {
+	/* AHB register space */
+	{
+		.virtual = BCM63XX_AHB_VIRT,
+		.pfn = __phys_to_pfn(BCM63XX_AHB_PHYS),
+		.length	= BCM63XX_AHB_SIZE,
+		.type = MT_DEVICE,
+	},
+	/* PERIPH register space */
+	{
+		.virtual = BCM63XX_PERIPH_VIRT,
+		.pfn = __phys_to_pfn(BCM63XX_PERIPH_PHYS),
+		.length = BCM63XX_PERIPH_SIZE,
+		.type = MT_DEVICE,
+	},
+};
+
+static void __init bcm63xx_map_io(void)
+{
+	iotable_init(bcm63xx_map_desc, ARRAY_SIZE(bcm63xx_map_desc));
+}
+
+DT_MACHINE_START(BCM63XXX_DT, "BCM63xx DSL SoC")
+	.map_io		= bcm63xx_map_io,
+	.init_machine	= bcm63xx_init,
+	.dt_compat	= bcm63xx_dt_compat,
+MACHINE_END