diff mbox

ARM: bcm281xx: Add L2 cache enable code

Message ID 1362451632-18806-1-git-send-email-csd@broadcom.com (mailing list archive)
State New, archived
Headers show

Commit Message

Christian Daudt March 5, 2013, 2:47 a.m. UTC
- Adds a module to provide calls into secure monitor mode
- Uses this module to make secure monitor calls to enable L2 cache.

NOTE: This patch applies on top of the yet-unmerged 28x11 timer patch:
https://patchwork.kernel.org/patch/2186561/

Signed-off-by: Christian Daudt <csd@broadcom.com>

Comments

Arnd Bergmann March 5, 2013, 9:01 a.m. UTC | #1
On Tuesday 05 March 2013, Christian Daudt wrote:

> diff --git a/Documentation/devicetree/bindings/misc/smc.txt b/Documentation/devicetree/bindings/misc/smc.txt
> new file mode 100644
> index 0000000..cd8c729
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/misc/smc.txt
> @@ -0,0 +1,14 @@
> +Broadcom Secure Monitor Bounce buffer
> +-----------------------------------------------------
> +This binding defines the location of the bounce buffer
> +used for non-secure to secure communications.
> +
> +Required properties:
> +- compatible : "bcm,kona-smc"
> +- reg : Location and size of bounce buffer
> +
> +Example:
> +	smc@0x3404c000 {
> +		compatible = "bcm,kona-smc";
> +		reg = <0x3404c000 0x400>; //1 KiB in SRAM
> +	};

For other firmware interfaces like this, we tend to list the specific commands
that the firmware understands. If you think there might be different versions
to consider, you might want to model this like

Documentation/devicetree/bindings/arm/psci.txt
> diff --git a/arch/arm/mach-bcm/bcm_kona_smc_asm.S b/arch/arm/mach-bcm/bcm_kona_smc_asm.S
> new file mode 100644
> index 0000000..a160848
> --- /dev/null
> +++ b/arch/arm/mach-bcm/bcm_kona_smc_asm.S
> +/*
> + * int bcm_kona_smc_asm(u32 service_id, u32 buffer_addr)
> + */
> +
> +ENTRY(bcm_kona_smc_asm)
> +	stmfd	sp!, {r4-r12, lr}
> +	mov	r4, r0		@ service_id
> +	mov	r5, #3		@ Keep IRQ and FIQ off in SM

Why not just use an inline assembly?

> +#ifdef CONFIG_CACHE_L2X0
> +static int __init kona_l2_cache_init(void)
> +{
> +	/*
> +	 * Currently there is no SSAPI for setting the L2 cache aux register,
> +	 * so the default value (0x1e050000) applies.
> +	 */
> +	bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0);

This can be written in a nicer way as

static int __init kona_l2_cache_init(void)
{
	if (!IS_ENABLED(CONFIG_CACHE_L2X0))
		return 0;
	...
}

To remove the need for the #ifdef.

> +static void __init init_irq(void)
> +{
> +	irqchip_init();
> +	bcm_kona_smc_init();
> +
> +#ifdef CONFIG_CACHE_L2X0
> +	kona_l2_cache_init();
> +#endif /* CONFIG_CACHE_L2X0 */
> +}

Why are you calling bcm_kona_smc_init() and kona_l2_cache_init() from init_irq()?

It seems completely unrelated to interrupt handling.

	Arnd
Stephen Warren March 5, 2013, 6:20 p.m. UTC | #2
On 03/04/2013 07:47 PM, Christian Daudt wrote:
> - Adds a module to provide calls into secure monitor mode
> - Uses this module to make secure monitor calls to enable L2 cache.

> diff --git a/Documentation/devicetree/bindings/misc/smc.txt b/Documentation/devicetree/bindings/misc/smc.txt

> +Example:
> +	smc@0x3404c000 {
> +		compatible = "bcm,kona-smc";

Both here in this example, and ...

> diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi

> +	smc@0x3404c000 {
> +		compatible = "bcm,kona-smc";

Here in the actual .dts file, you should include the specific ID of the
SoC too, so that if there are Soc-specific bugs, the compatible property
that's required to determine this is present from the start. In other words,

compatible = "bcm,bcm11351-smc", "bcm,kona-smc";

(which SoC ID you use in the example is arbitrary, but it may as well
match the .dts file you're editing in the patch).
Christian Daudt March 5, 2013, 10:54 p.m. UTC | #3
On 13-03-05 01:01 AM, Arnd Bergmann wrote:
> On Tuesday 05 March 2013, Christian Daudt wrote:
>
>> diff --git a/Documentation/devicetree/bindings/misc/smc.txt b/Documentation/devicetree/bindings/misc/smc.txt
>> new file mode 100644
>> index 0000000..cd8c729
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/misc/smc.txt
>> @@ -0,0 +1,14 @@
>> +Broadcom Secure Monitor Bounce buffer
>> +-----------------------------------------------------
>> +This binding defines the location of the bounce buffer
>> +used for non-secure to secure communications.
>> +
>> +Required properties:
>> +- compatible : "bcm,kona-smc"
>> +- reg : Location and size of bounce buffer
>> +
>> +Example:
>> +	smc@0x3404c000 {
>> +		compatible = "bcm,kona-smc";
>> +		reg = <0x3404c000 0x400>; //1 KiB in SRAM
>> +	};
> For other firmware interfaces like this, we tend to list the specific commands
> that the firmware understands. If you think there might be different versions
> to consider, you might want to model this like
>
> Documentation/devicetree/bindings/arm/psci.txt
This interface is stable and in shipping products at this time, and so 
the api will remain constant.

>> diff --git a/arch/arm/mach-bcm/bcm_kona_smc_asm.S b/arch/arm/mach-bcm/bcm_kona_smc_asm.S
>> new file mode 100644
>> index 0000000..a160848
>> --- /dev/null
>> +++ b/arch/arm/mach-bcm/bcm_kona_smc_asm.S
>> +/*
>> + * int bcm_kona_smc_asm(u32 service_id, u32 buffer_addr)
>> + */
>> +
>> +ENTRY(bcm_kona_smc_asm)
>> +	stmfd	sp!, {r4-r12, lr}
>> +	mov	r4, r0		@ service_id
>> +	mov	r5, #3		@ Keep IRQ and FIQ off in SM
> Why not just use an inline assembly?
We ran into problems with some gcc versions messing up the 
"arch_extension sec" when passing it to the assembler, so we broke it 
out to its own .S file following the example of omap and highbank. I 
suspect that they did it for the same reason.

>
>> +#ifdef CONFIG_CACHE_L2X0
>> +static int __init kona_l2_cache_init(void)
>> +{
>> +	/*
>> +	 * Currently there is no SSAPI for setting the L2 cache aux register,
>> +	 * so the default value (0x1e050000) applies.
>> +	 */
>> +	bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0);
> This can be written in a nicer way as
>
> static int __init kona_l2_cache_init(void)
> {
> 	if (!IS_ENABLED(CONFIG_CACHE_L2X0))
> 		return 0;
> 	...
> }
>
> To remove the need for the #ifdef.
ok. done.

>> +static void __init init_irq(void)
>> +{
>> +	irqchip_init();
>> +	bcm_kona_smc_init();
>> +
>> +#ifdef CONFIG_CACHE_L2X0
>> +	kona_l2_cache_init();
>> +#endif /* CONFIG_CACHE_L2X0 */
>> +}
> Why are you calling bcm_kona_smc_init() and kona_l2_cache_init() from init_irq()?
>
> It seems completely unrelated to interrupt handling.
>
It was originally in init_machine section but I was told that that was 
too late and init_irq would be better, and I saw that highbank also has 
it in init_irq. I agree that it is unrelated to irq - is there a better 
place to put this in ?

  thanks,
    csd
Christian Daudt March 5, 2013, 10:56 p.m. UTC | #4
On 13-03-05 10:20 AM, Stephen Warren wrote:
> On 03/04/2013 07:47 PM, Christian Daudt wrote:
>> - Adds a module to provide calls into secure monitor mode
>> - Uses this module to make secure monitor calls to enable L2 cache.
>> diff --git a/Documentation/devicetree/bindings/misc/smc.txt b/Documentation/devicetree/bindings/misc/smc.txt
>> +Example:
>> +	smc@0x3404c000 {
>> +		compatible = "bcm,kona-smc";
> Both here in this example, and ...
>
>> diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi
>> +	smc@0x3404c000 {
>> +		compatible = "bcm,kona-smc";
> Here in the actual .dts file, you should include the specific ID of the
> SoC too, so that if there are Soc-specific bugs, the compatible property
> that's required to determine this is present from the start. In other words,
>
> compatible = "bcm,bcm11351-smc", "bcm,kona-smc";
>
> (which SoC ID you use in the example is arbitrary, but it may as well
> match the .dts file you're editing in the patch).
>

ok. done.

  thanks,
    csd
Arnd Bergmann March 6, 2013, 6:31 a.m. UTC | #5
On Tuesday 05 March 2013, Christian Daudt wrote:
> On 13-03-05 01:01 AM, Arnd Bergmann wrote:
> > On Tuesday 05 March 2013, Christian Daudt wrote:
> > For other firmware interfaces like this, we tend to list the specific commands
> > that the firmware understands. If you think there might be different versions
> > to consider, you might want to model this like
> >
> > Documentation/devicetree/bindings/arm/psci.txt
> This interface is stable and in shipping products at this time, and so 
> the api will remain constant.

But what about future products? Wouldn't they be able to extend the
current interface in a compatible way?

> >> +static void __init init_irq(void)
> >> +{
> >> +	irqchip_init();
> >> +	bcm_kona_smc_init();
> >> +
> >> +#ifdef CONFIG_CACHE_L2X0
> >> +	kona_l2_cache_init();
> >> +#endif /* CONFIG_CACHE_L2X0 */
> >> +}
> > Why are you calling bcm_kona_smc_init() and kona_l2_cache_init() from init_irq()?
> >
> > It seems completely unrelated to interrupt handling.
> >
> It was originally in init_machine section but I was told that that was 
> too late and init_irq would be better, and I saw that highbank also has 
> it in init_irq. I agree that it is unrelated to irq - is there a better 
> place to put this in ?

IMHO the later the better. Do you know what issues were caused  by having it
in init_machine?

	Arnd
Arnd Bergmann March 6, 2013, 11:28 a.m. UTC | #6
On Wednesday 06 March 2013, Christian Daudt wrote:
> On 13-03-05 10:31 PM, Arnd Bergmann wrote:
> > On Tuesday 05 March 2013, Christian Daudt wrote:
> >> On 13-03-05 01:01 AM, Arnd Bergmann wrote:
> >>> On Tuesday 05 March 2013, Christian Daudt wrote:
> >>> For other firmware interfaces like this, we tend to list the specific commands
> >>> that the firmware understands. If you think there might be different versions
> >>> to consider, you might want to model this like
> >>>
> >>> Documentation/devicetree/bindings/arm/psci.txt
> >> This interface is stable and in shipping products at this time, and so
> >> the api will remain constant.
> > But what about future products? Wouldn't they be able to extend the
> > current interface in a compatible way?
>
> It is highly unlikely that for this family we will be extending that API 
> but even if that is done, it can just added #defines in the C header. Is 
> DT seen as the way to define Software APIs going forward ? It should be 
> trivial to implement this, I'm just trying to understand where the line 
> is drawn between describing APIs in DT vs C headers going forward.

We tend to do it in cases where the software has no other way to find out
what interfaces are supported. I guess if it becomes necessary, we can
use a different "compatible" value for an extended future version of this,
but that scales only to so many different variants.

> >> It was originally in init_machine section but I was told that that was
> >> too late and init_irq would be better, and I saw that highbank also has
> >> it in init_irq. I agree that it is unrelated to irq - is there a better
> >> place to put this in ?
> > IMHO the later the better. Do you know what issues were caused  by having it
> > in init_machine?
> This is some feedback I got a while back:
> "From kernel 3.4 on-wards i think ( if i remember correctly) cache sync
> might be called before your board_init function and you might have to do 
> this in init_irq. "
> 
> I just looked through where l2x0_of_init is currently called and here's 
> the list:
> early_initcall (exynos4, omap2, sirf, ux500)
> init_irq (highbank, imx6q)
> init_machine (socfpga, v2m_dt_init)
> 
> so seems to be everywhere :) So I can move it back to init_machineif 
> that's where itshould be.

Hmm, let's try to solve this another time, I don't think there is an easy
answer. Maybe we really need a common entry point for the cache
controller setup, or move it completely out of platform specific code
for the case where it can be probed from DT.

Thanks for doing the research!

	Arnd
Christian Daudt March 6, 2013, 3:05 p.m. UTC | #7
On 13-03-06 03:28 AM, Arnd Bergmann wrote:
>>>> It was originally in init_machine section but I was told that that was
>>>> too late and init_irq would be better, and I saw that highbank also has
>>>> it in init_irq. I agree that it is unrelated to irq - is there a better
>>>> place to put this in ?
>>> IMHO the later the better. Do you know what issues were caused  by having it
>>> in init_machine?
>> This is some feedback I got a while back:
>> "From kernel 3.4 on-wards i think ( if i remember correctly) cache sync
>> might be called before your board_init function and you might have to do
>> this in init_irq. "
>>
>> I just looked through where l2x0_of_init is currently called and here's
>> the list:
>> early_initcall (exynos4, omap2, sirf, ux500)
>> init_irq (highbank, imx6q)
>> init_machine (socfpga, v2m_dt_init)
>>
>> so seems to be everywhere :) So I can move it back to init_machineif
>> that's where itshould be.
> Hmm, let's try to solve this another time, I don't think there is an easy
> answer. Maybe we really need a common entry point for the cache
> controller setup, or move it completely out of platform specific code
> for the case where it can be probed from DT.
>
> Thanks for doing the research!
>
So for the time being should it stay in init_irq or init_machine ?

   Thanks,
    csd
Olof Johansson April 11, 2013, 6:52 a.m. UTC | #8
On Wed, Apr 10, 2013 at 10:33:37AM -0700, Christian Daudt wrote:
> Hi Arnd, Olof,
>  Please pull the branch below - it contains the BCM281xx l2 cache
> enabling code.
> 
>  Thanks,
>    csd
> 
> 
> The following changes since commit 07961ac7c0ee8b546658717034fe692fd12eefa9:
> 
>   Linux 3.9-rc5 (2013-03-31 15:12:43 -0700)
> 
> are available in the git repository at:
> 
>   git://github.com/broadcom/bcm11351.git tags/fw-for-3.10

Thanks, pulled into next/soc (local branch name bcm/smc-l2)


-Olof
Olof Johansson April 11, 2013, 8:52 a.m. UTC | #9
On Wed, Apr 10, 2013 at 11:52 PM, Olof Johansson <olof@lixom.net> wrote:
> On Wed, Apr 10, 2013 at 10:33:37AM -0700, Christian Daudt wrote:
>> Hi Arnd, Olof,
>>  Please pull the branch below - it contains the BCM281xx l2 cache
>> enabling code.
>>
>>  Thanks,
>>    csd
>>
>>
>> The following changes since commit 07961ac7c0ee8b546658717034fe692fd12eefa9:
>>
>>   Linux 3.9-rc5 (2013-03-31 15:12:43 -0700)
>>
>> are available in the git repository at:
>>
>>   git://github.com/broadcom/bcm11351.git tags/fw-for-3.10
>
> Thanks, pulled into next/soc (local branch name bcm/smc-l2)

Based on later thread about the exynos smc ops, I moved this branch
over to next/firmware instead.


-Olof
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/misc/smc.txt b/Documentation/devicetree/bindings/misc/smc.txt
new file mode 100644
index 0000000..cd8c729
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/smc.txt
@@ -0,0 +1,14 @@ 
+Broadcom Secure Monitor Bounce buffer
+-----------------------------------------------------
+This binding defines the location of the bounce buffer
+used for non-secure to secure communications.
+
+Required properties:
+- compatible : "bcm,kona-smc"
+- reg : Location and size of bounce buffer
+
+Example:
+	smc@0x3404c000 {
+		compatible = "bcm,kona-smc";
+		reg = <0x3404c000 0x400>; //1 KiB in SRAM
+	};
diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi
index 8f71f40..d057d27 100644
--- a/arch/arm/boot/dts/bcm11351.dtsi
+++ b/arch/arm/boot/dts/bcm11351.dtsi
@@ -55,4 +55,9 @@ 
 		clock-frequency = <32768>;
 	};
 
+	smc@0x3404c000 {
+		compatible = "bcm,kona-smc";
+		reg = <0x3404c000 0x400>; //1 KiB in SRAM
+	};
+
 };
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index bbf4122..6adb6aec 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -10,4 +10,6 @@ 
 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
-obj-$(CONFIG_ARCH_BCM) := board_bcm.o
+obj-$(CONFIG_ARCH_BCM)		:= board_bcm.o bcm_kona_smc.o bcm_kona_smc_asm.o
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_bcm_kona_smc_asm.o	:=-Wa,-march=armv7-a$(plus_sec)
diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c
new file mode 100644
index 0000000..5f1d131
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_kona_smc.c
@@ -0,0 +1,118 @@ 
+/*
+ * Copyright (C) 2013 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 <stdarg.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+
+#include <asm/cacheflush.h>
+#include <linux/of_address.h>
+
+#include "bcm_kona_smc.h"
+
+struct secure_bridge_data {
+	void __iomem *bounce;		/* virtual address */
+	u32 __iomem buffer_addr;	/* physical address */
+	int initialized;
+} bridge_data;
+
+struct bcm_kona_smc_data {
+	unsigned service_id;
+	unsigned arg0;
+	unsigned arg1;
+	unsigned arg2;
+	unsigned arg3;
+};
+
+static const struct of_device_id bcm_kona_smc_ids[] __initconst = {
+	{.compatible = "bcm,kona-smc"},
+	{},
+};
+
+/* Map in the bounce area */
+void bcm_kona_smc_init(void)
+{
+	struct device_node *node;
+
+	/* Read buffer addr and size from the device tree node */
+	node = of_find_matching_node(NULL, bcm_kona_smc_ids);
+	BUG_ON(!node);
+
+	/* Don't care about size or flags of the DT node */
+	bridge_data.buffer_addr =
+		be32_to_cpu(*of_get_address(node, 0, NULL, NULL));
+	BUG_ON(!bridge_data.buffer_addr);
+
+	bridge_data.bounce = of_iomap(node, 0);
+	BUG_ON(!bridge_data.bounce);
+
+	bridge_data.initialized = 1;
+
+	pr_info("Secure API initialized!\n");
+}
+
+/* __bcm_kona_smc() should only run on CPU 0, with pre-emption disabled */
+static void __bcm_kona_smc(void *info)
+{
+	struct bcm_kona_smc_data *data = info;
+	u32 *args = bridge_data.bounce;
+	int rc = 0;
+
+	/* Must run on CPU 0 */
+	BUG_ON(smp_processor_id() != 0);
+
+	/* Check map in the bounce area */
+	BUG_ON(!bridge_data.initialized);
+
+	/* Copy one 32 bit word into the bounce area */
+	args[0] = data->arg0;
+	args[1] = data->arg1;
+	args[2] = data->arg2;
+	args[3] = data->arg3;
+
+	/* Flush caches for input data passed to Secure Monitor */
+	if (data->service_id != SSAPI_BRCM_START_VC_CORE)
+		flush_cache_all();
+
+	/* Trap into Secure Monitor */
+	rc = bcm_kona_smc_asm(data->service_id, bridge_data.buffer_addr);
+
+	if (rc != SEC_ROM_RET_OK)
+		pr_err("Secure Monitor call failed (0x%x)!\n", rc);
+}
+
+unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1,
+		  unsigned arg2, unsigned arg3)
+{
+	struct bcm_kona_smc_data data;
+
+	data.service_id = service_id;
+	data.arg0 = arg0;
+	data.arg1 = arg1;
+	data.arg2 = arg2;
+	data.arg3 = arg3;
+
+	/*
+	 * Due to a limitation of the secure monitor, we must use the SMP
+	 * infrastructure to forward all secure monitor calls to Core 0.
+	 */
+	if (get_cpu() != 0)
+		smp_call_function_single(0, __bcm_kona_smc, (void *)&data, 1);
+	else
+		__bcm_kona_smc(&data);
+
+	put_cpu();
+
+	return 0;
+}
diff --git a/arch/arm/mach-bcm/bcm_kona_smc.h b/arch/arm/mach-bcm/bcm_kona_smc.h
new file mode 100644
index 0000000..3bedbed
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_kona_smc.h
@@ -0,0 +1,80 @@ 
+/*
+ * Copyright (C) 2013 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 BCM_KONA_SMC_H
+#define BCM_KONA_SMC_H
+
+#include <linux/types.h>
+#define FLAGS	(SEC_ROM_ICACHE_ENABLE_MASK | SEC_ROM_DCACHE_ENABLE_MASK | \
+			SEC_ROM_IRQ_ENABLE_MASK | SEC_ROM_FIQ_ENABLE_MASK)
+
+/*!
+ * Definitions for IRQ & FIQ Mask for ARM
+ */
+
+#define FIQ_IRQ_MASK						0xC0
+#define FIQ_MASK						0x40
+#define IRQ_MASK						0x80
+
+/*!
+ * Secure Mode FLAGs
+ */
+
+/* When set, enables ICache within the secure mode */
+#define SEC_ROM_ICACHE_ENABLE_MASK                        0x00000001
+
+/* When set, enables DCache within the secure mode */
+#define SEC_ROM_DCACHE_ENABLE_MASK                        0x00000002
+
+/* When set, enables IRQ within the secure mode */
+#define SEC_ROM_IRQ_ENABLE_MASK                           0x00000004
+
+/* When set, enables FIQ within the secure mode */
+#define SEC_ROM_FIQ_ENABLE_MASK                           0x00000008
+
+/* When set, enables Unified L2 cache within the secure mode */
+#define SEC_ROM_UL2_CACHE_ENABLE_MASK                     0x00000010
+
+/* Broadcom Secure Service API Service IDs */
+#define SSAPI_DORMANT_ENTRY_SERV                          0x01000000
+#define SSAPI_PUBLIC_OTP_SERV                             0x01000001
+#define SSAPI_ENABLE_L2_CACHE                             0x01000002
+#define SSAPI_DISABLE_L2_CACHE                            0x01000003
+#define SSAPI_WRITE_SCU_STATUS                            0x01000004
+#define SSAPI_WRITE_PWR_GATE                              0x01000005
+
+/* Broadcom Secure Service API Return Codes */
+#define SEC_ROM_RET_OK			0x00000001
+#define SEC_ROM_RET_FAIL		0x00000009
+
+#define SSAPI_RET_FROM_INT_SERV		0x4
+#define SEC_EXIT_NORMAL			0x1
+
+#define SSAPI_ROW_AES			0x0E000006
+#define SSAPI_BRCM_START_VC_CORE	0x0E000008
+
+#ifndef	__ASSEMBLY__
+extern void bcm_kona_smc_init(void);
+
+extern unsigned bcm_kona_smc(unsigned service_id,
+			     unsigned arg0,
+			     unsigned arg1,
+			     unsigned arg2,
+			     unsigned arg3);
+
+extern int bcm_kona_smc_asm(u32 service_id,
+			    u32 buffer_addr);
+
+#endif	/* __ASSEMBLY__ */
+
+#endif /* BCM_KONA_SMC_H */
diff --git a/arch/arm/mach-bcm/bcm_kona_smc_asm.S b/arch/arm/mach-bcm/bcm_kona_smc_asm.S
new file mode 100644
index 0000000..a160848
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_kona_smc_asm.S
@@ -0,0 +1,41 @@ 
+/*
+ * Copyright (C) 2013 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/linkage.h>
+#include "bcm_kona_smc.h"
+
+/*
+ * int bcm_kona_smc_asm(u32 service_id, u32 buffer_addr)
+ */
+
+ENTRY(bcm_kona_smc_asm)
+	stmfd	sp!, {r4-r12, lr}
+	mov	r4, r0		@ service_id
+	mov	r5, #3		@ Keep IRQ and FIQ off in SM
+	/*
+	 * Since interrupts are disabled in the open mode, we must keep
+	 * interrupts disabled in secure mode by setting R5=0x3. If interrupts
+	 * are enabled in open mode, we can set R5=0x0 to allow interrupts in
+	 * secure mode.  If we did this, the secure monitor would return back
+	 * control to the open mode to handle the interrupt prior to completing
+	 * the secure service. If this happened, R12 would not be
+	 * SEC_EXIT_NORMAL and we would need to call SMC again after resetting
+	 * R5 (it gets clobbered by the secure monitor) and setting R4 to
+	 * SSAPI_RET_FROM_INT_SERV to indicate that we want the secure monitor
+	 * to finish up the previous uncompleted secure service.
+	 */
+	mov	r6, r1		@ buffer_addr
+	smc	#0
+	/* Check r12 for SEC_EXIT_NORMAL here if interrupts are enabled */
+	ldmfd	sp!, {r4-r12, pc}
+ENDPROC(bcm_kona_smc_asm)
diff --git a/arch/arm/mach-bcm/board_bcm.c b/arch/arm/mach-bcm/board_bcm.c
index 2595935..1edd82e 100644
--- a/arch/arm/mach-bcm/board_bcm.c
+++ b/arch/arm/mach-bcm/board_bcm.c
@@ -16,12 +16,44 @@ 
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/irqchip.h>
+#include <asm/hardware/cache-l2x0.h>
 #include <linux/clocksource.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 
 
+#include "bcm_kona_smc.h"
+
+#ifdef CONFIG_CACHE_L2X0
+static int __init kona_l2_cache_init(void)
+{
+	/*
+	 * Currently there is no SSAPI for setting the L2 cache aux register,
+	 * so the default value (0x1e050000) applies.
+	 */
+	bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0);
+
+	/*
+	 * The aux_val and aux_mask have no effect since L2 cache is already
+	 * enabled.  Pass 0s for aux_val and 1s for aux_mask for default value.
+	 */
+	l2x0_of_init(0, ~0);
+
+	return 0;
+}
+#endif /* CONFIG_CACHE_L2X0 */
+
+static void __init init_irq(void)
+{
+	irqchip_init();
+	bcm_kona_smc_init();
+
+#ifdef CONFIG_CACHE_L2X0
+	kona_l2_cache_init();
+#endif /* CONFIG_CACHE_L2X0 */
+}
+
 static void __init board_init(void)
 {
 	of_platform_populate(NULL, of_default_bus_match_table, NULL,
@@ -31,7 +63,7 @@  static void __init board_init(void)
 static const char * const bcm11351_dt_compat[] = { "bcm,bcm11351", NULL, };
 
 DT_MACHINE_START(BCM11351_DT, "Broadcom Application Processor")
-	.init_irq = irqchip_init,
+	.init_irq = init_irq,
 	.init_time = clocksource_of_init,
 	.init_machine = board_init,
 	.dt_compat = bcm11351_dt_compat,