diff options
author | Christian Daudt <csd@broadcom.com> | 2013-02-27 00:48:49 -0500 |
---|---|---|
committer | Christian Daudt <csd@broadcom.com> | 2013-04-09 12:18:13 -0400 |
commit | b8eb35fd594aa5b635e329d5c8efab8aaceb8619 (patch) | |
tree | 8c664f4d4daabc0a83435ef90cead2eeff751e5b /arch/arm/mach-bcm | |
parent | 07961ac7c0ee8b546658717034fe692fd12eefa9 (diff) |
ARM: bcm281xx: Add L2 cache enable code
- Adds a module to provide calls into secure monitor mode
- Uses this module to make secure monitor calls to enable L2 cache.
Updates from V1:
- Split DT portion into separate patch
- replace #ifdef-ed L2 code with "if".
- move init call to board init
Signed-off-by: Christian Daudt <csd@broadcom.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/mach-bcm')
-rw-r--r-- | arch/arm/mach-bcm/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-bcm/bcm_kona_smc.c | 118 | ||||
-rw-r--r-- | arch/arm/mach-bcm/bcm_kona_smc.h | 80 | ||||
-rw-r--r-- | arch/arm/mach-bcm/bcm_kona_smc_asm.S | 41 | ||||
-rw-r--r-- | arch/arm/mach-bcm/board_bcm.c | 23 |
5 files changed, 265 insertions, 1 deletions
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile index bbf412261e5e..6adb6aecf48f 100644 --- a/arch/arm/mach-bcm/Makefile +++ b/arch/arm/mach-bcm/Makefile | |||
@@ -10,4 +10,6 @@ | |||
10 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | # GNU General Public License for more details. | 11 | # GNU General Public License for more details. |
12 | 12 | ||
13 | obj-$(CONFIG_ARCH_BCM) := board_bcm.o | 13 | obj-$(CONFIG_ARCH_BCM) := board_bcm.o bcm_kona_smc.o bcm_kona_smc_asm.o |
14 | plus_sec := $(call as-instr,.arch_extension sec,+sec) | ||
15 | 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 000000000000..5f1d13175138 --- /dev/null +++ b/arch/arm/mach-bcm/bcm_kona_smc.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <stdarg.h> | ||
15 | #include <linux/smp.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/ioport.h> | ||
18 | |||
19 | #include <asm/cacheflush.h> | ||
20 | #include <linux/of_address.h> | ||
21 | |||
22 | #include "bcm_kona_smc.h" | ||
23 | |||
24 | struct secure_bridge_data { | ||
25 | void __iomem *bounce; /* virtual address */ | ||
26 | u32 __iomem buffer_addr; /* physical address */ | ||
27 | int initialized; | ||
28 | } bridge_data; | ||
29 | |||
30 | struct bcm_kona_smc_data { | ||
31 | unsigned service_id; | ||
32 | unsigned arg0; | ||
33 | unsigned arg1; | ||
34 | unsigned arg2; | ||
35 | unsigned arg3; | ||
36 | }; | ||
37 | |||
38 | static const struct of_device_id bcm_kona_smc_ids[] __initconst = { | ||
39 | {.compatible = "bcm,kona-smc"}, | ||
40 | {}, | ||
41 | }; | ||
42 | |||
43 | /* Map in the bounce area */ | ||
44 | void bcm_kona_smc_init(void) | ||
45 | { | ||
46 | struct device_node *node; | ||
47 | |||
48 | /* Read buffer addr and size from the device tree node */ | ||
49 | node = of_find_matching_node(NULL, bcm_kona_smc_ids); | ||
50 | BUG_ON(!node); | ||
51 | |||
52 | /* Don't care about size or flags of the DT node */ | ||
53 | bridge_data.buffer_addr = | ||
54 | be32_to_cpu(*of_get_address(node, 0, NULL, NULL)); | ||
55 | BUG_ON(!bridge_data.buffer_addr); | ||
56 | |||
57 | bridge_data.bounce = of_iomap(node, 0); | ||
58 | BUG_ON(!bridge_data.bounce); | ||
59 | |||
60 | bridge_data.initialized = 1; | ||
61 | |||
62 | pr_info("Secure API initialized!\n"); | ||
63 | } | ||
64 | |||
65 | /* __bcm_kona_smc() should only run on CPU 0, with pre-emption disabled */ | ||
66 | static void __bcm_kona_smc(void *info) | ||
67 | { | ||
68 | struct bcm_kona_smc_data *data = info; | ||
69 | u32 *args = bridge_data.bounce; | ||
70 | int rc = 0; | ||
71 | |||
72 | /* Must run on CPU 0 */ | ||
73 | BUG_ON(smp_processor_id() != 0); | ||
74 | |||
75 | /* Check map in the bounce area */ | ||
76 | BUG_ON(!bridge_data.initialized); | ||
77 | |||
78 | /* Copy one 32 bit word into the bounce area */ | ||
79 | args[0] = data->arg0; | ||
80 | args[1] = data->arg1; | ||
81 | args[2] = data->arg2; | ||
82 | args[3] = data->arg3; | ||
83 | |||
84 | /* Flush caches for input data passed to Secure Monitor */ | ||
85 | if (data->service_id != SSAPI_BRCM_START_VC_CORE) | ||
86 | flush_cache_all(); | ||
87 | |||
88 | /* Trap into Secure Monitor */ | ||
89 | rc = bcm_kona_smc_asm(data->service_id, bridge_data.buffer_addr); | ||
90 | |||
91 | if (rc != SEC_ROM_RET_OK) | ||
92 | pr_err("Secure Monitor call failed (0x%x)!\n", rc); | ||
93 | } | ||
94 | |||
95 | unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1, | ||
96 | unsigned arg2, unsigned arg3) | ||
97 | { | ||
98 | struct bcm_kona_smc_data data; | ||
99 | |||
100 | data.service_id = service_id; | ||
101 | data.arg0 = arg0; | ||
102 | data.arg1 = arg1; | ||
103 | data.arg2 = arg2; | ||
104 | data.arg3 = arg3; | ||
105 | |||
106 | /* | ||
107 | * Due to a limitation of the secure monitor, we must use the SMP | ||
108 | * infrastructure to forward all secure monitor calls to Core 0. | ||
109 | */ | ||
110 | if (get_cpu() != 0) | ||
111 | smp_call_function_single(0, __bcm_kona_smc, (void *)&data, 1); | ||
112 | else | ||
113 | __bcm_kona_smc(&data); | ||
114 | |||
115 | put_cpu(); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
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 000000000000..3bedbed1c21b --- /dev/null +++ b/arch/arm/mach-bcm/bcm_kona_smc.h | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef BCM_KONA_SMC_H | ||
15 | #define BCM_KONA_SMC_H | ||
16 | |||
17 | #include <linux/types.h> | ||
18 | #define FLAGS (SEC_ROM_ICACHE_ENABLE_MASK | SEC_ROM_DCACHE_ENABLE_MASK | \ | ||
19 | SEC_ROM_IRQ_ENABLE_MASK | SEC_ROM_FIQ_ENABLE_MASK) | ||
20 | |||
21 | /*! | ||
22 | * Definitions for IRQ & FIQ Mask for ARM | ||
23 | */ | ||
24 | |||
25 | #define FIQ_IRQ_MASK 0xC0 | ||
26 | #define FIQ_MASK 0x40 | ||
27 | #define IRQ_MASK 0x80 | ||
28 | |||
29 | /*! | ||
30 | * Secure Mode FLAGs | ||
31 | */ | ||
32 | |||
33 | /* When set, enables ICache within the secure mode */ | ||
34 | #define SEC_ROM_ICACHE_ENABLE_MASK 0x00000001 | ||
35 | |||
36 | /* When set, enables DCache within the secure mode */ | ||
37 | #define SEC_ROM_DCACHE_ENABLE_MASK 0x00000002 | ||
38 | |||
39 | /* When set, enables IRQ within the secure mode */ | ||
40 | #define SEC_ROM_IRQ_ENABLE_MASK 0x00000004 | ||
41 | |||
42 | /* When set, enables FIQ within the secure mode */ | ||
43 | #define SEC_ROM_FIQ_ENABLE_MASK 0x00000008 | ||
44 | |||
45 | /* When set, enables Unified L2 cache within the secure mode */ | ||
46 | #define SEC_ROM_UL2_CACHE_ENABLE_MASK 0x00000010 | ||
47 | |||
48 | /* Broadcom Secure Service API Service IDs */ | ||
49 | #define SSAPI_DORMANT_ENTRY_SERV 0x01000000 | ||
50 | #define SSAPI_PUBLIC_OTP_SERV 0x01000001 | ||
51 | #define SSAPI_ENABLE_L2_CACHE 0x01000002 | ||
52 | #define SSAPI_DISABLE_L2_CACHE 0x01000003 | ||
53 | #define SSAPI_WRITE_SCU_STATUS 0x01000004 | ||
54 | #define SSAPI_WRITE_PWR_GATE 0x01000005 | ||
55 | |||
56 | /* Broadcom Secure Service API Return Codes */ | ||
57 | #define SEC_ROM_RET_OK 0x00000001 | ||
58 | #define SEC_ROM_RET_FAIL 0x00000009 | ||
59 | |||
60 | #define SSAPI_RET_FROM_INT_SERV 0x4 | ||
61 | #define SEC_EXIT_NORMAL 0x1 | ||
62 | |||
63 | #define SSAPI_ROW_AES 0x0E000006 | ||
64 | #define SSAPI_BRCM_START_VC_CORE 0x0E000008 | ||
65 | |||
66 | #ifndef __ASSEMBLY__ | ||
67 | extern void bcm_kona_smc_init(void); | ||
68 | |||
69 | extern unsigned bcm_kona_smc(unsigned service_id, | ||
70 | unsigned arg0, | ||
71 | unsigned arg1, | ||
72 | unsigned arg2, | ||
73 | unsigned arg3); | ||
74 | |||
75 | extern int bcm_kona_smc_asm(u32 service_id, | ||
76 | u32 buffer_addr); | ||
77 | |||
78 | #endif /* __ASSEMBLY__ */ | ||
79 | |||
80 | #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 000000000000..a1608480d60d --- /dev/null +++ b/arch/arm/mach-bcm/bcm_kona_smc_asm.S | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/linkage.h> | ||
15 | #include "bcm_kona_smc.h" | ||
16 | |||
17 | /* | ||
18 | * int bcm_kona_smc_asm(u32 service_id, u32 buffer_addr) | ||
19 | */ | ||
20 | |||
21 | ENTRY(bcm_kona_smc_asm) | ||
22 | stmfd sp!, {r4-r12, lr} | ||
23 | mov r4, r0 @ service_id | ||
24 | mov r5, #3 @ Keep IRQ and FIQ off in SM | ||
25 | /* | ||
26 | * Since interrupts are disabled in the open mode, we must keep | ||
27 | * interrupts disabled in secure mode by setting R5=0x3. If interrupts | ||
28 | * are enabled in open mode, we can set R5=0x0 to allow interrupts in | ||
29 | * secure mode. If we did this, the secure monitor would return back | ||
30 | * control to the open mode to handle the interrupt prior to completing | ||
31 | * the secure service. If this happened, R12 would not be | ||
32 | * SEC_EXIT_NORMAL and we would need to call SMC again after resetting | ||
33 | * R5 (it gets clobbered by the secure monitor) and setting R4 to | ||
34 | * SSAPI_RET_FROM_INT_SERV to indicate that we want the secure monitor | ||
35 | * to finish up the previous uncompleted secure service. | ||
36 | */ | ||
37 | mov r6, r1 @ buffer_addr | ||
38 | smc #0 | ||
39 | /* Check r12 for SEC_EXIT_NORMAL here if interrupts are enabled */ | ||
40 | ldmfd sp!, {r4-r12, pc} | ||
41 | ENDPROC(bcm_kona_smc_asm) | ||
diff --git a/arch/arm/mach-bcm/board_bcm.c b/arch/arm/mach-bcm/board_bcm.c index f0f9abafad29..28be74e8273c 100644 --- a/arch/arm/mach-bcm/board_bcm.c +++ b/arch/arm/mach-bcm/board_bcm.c | |||
@@ -19,16 +19,39 @@ | |||
19 | 19 | ||
20 | #include <asm/mach/arch.h> | 20 | #include <asm/mach/arch.h> |
21 | #include <asm/mach/time.h> | 21 | #include <asm/mach/time.h> |
22 | #include <asm/hardware/cache-l2x0.h> | ||
22 | 23 | ||
23 | static void timer_init(void) | 24 | static void timer_init(void) |
24 | { | 25 | { |
25 | } | 26 | } |
26 | 27 | ||
27 | 28 | ||
29 | #include "bcm_kona_smc.h" | ||
30 | |||
31 | static int __init kona_l2_cache_init(void) | ||
32 | { | ||
33 | if (!IS_ENABLED(CONFIG_CACHE_L2X0)) | ||
34 | return 0; | ||
35 | |||
36 | bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0); | ||
37 | |||
38 | /* | ||
39 | * The aux_val and aux_mask have no effect since L2 cache is already | ||
40 | * enabled. Pass 0s for aux_val and 1s for aux_mask for default value. | ||
41 | */ | ||
42 | l2x0_of_init(0, ~0); | ||
43 | |||
44 | return 0; | ||
45 | } | ||
46 | |||
28 | static void __init board_init(void) | 47 | static void __init board_init(void) |
29 | { | 48 | { |
30 | of_platform_populate(NULL, of_default_bus_match_table, NULL, | 49 | of_platform_populate(NULL, of_default_bus_match_table, NULL, |
31 | &platform_bus); | 50 | &platform_bus); |
51 | |||
52 | bcm_kona_smc_init(); | ||
53 | |||
54 | kona_l2_cache_init(); | ||
32 | } | 55 | } |
33 | 56 | ||
34 | static const char * const bcm11351_dt_compat[] = { "bcm,bcm11351", NULL, }; | 57 | static const char * const bcm11351_dt_compat[] = { "bcm,bcm11351", NULL, }; |