diff options
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r-- | arch/blackfin/mach-common/Makefile | 5 | ||||
-rw-r--r-- | arch/blackfin/mach-common/arch_checks.c | 9 | ||||
-rw-r--r-- | arch/blackfin/mach-common/cache.S | 115 | ||||
-rw-r--r-- | arch/blackfin/mach-common/cacheinit.S | 77 | ||||
-rw-r--r-- | arch/blackfin/mach-common/dpmc_modes.S | 56 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 34 | ||||
-rw-r--r-- | arch/blackfin/mach-common/head.S | 207 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 68 | ||||
-rw-r--r-- | arch/blackfin/mach-common/lock.S | 45 | ||||
-rw-r--r-- | arch/blackfin/mach-common/pm.c | 35 |
10 files changed, 349 insertions, 302 deletions
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile index 422bfee34adc..e6ed57c56d4b 100644 --- a/arch/blackfin/mach-common/Makefile +++ b/arch/blackfin/mach-common/Makefile | |||
@@ -3,9 +3,10 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := \ | 5 | obj-y := \ |
6 | cache.o cacheinit.o entry.o \ | 6 | cache.o entry.o head.o \ |
7 | interrupt.o lock.o irqpanic.o arch_checks.o ints-priority.o | 7 | interrupt.o irqpanic.o arch_checks.o ints-priority.o |
8 | 8 | ||
9 | obj-$(CONFIG_BFIN_ICACHE_LOCK) += lock.o | ||
9 | obj-$(CONFIG_PM) += pm.o dpmc_modes.o | 10 | obj-$(CONFIG_PM) += pm.o dpmc_modes.o |
10 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o | 11 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o |
11 | obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o | 12 | obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o |
diff --git a/arch/blackfin/mach-common/arch_checks.c b/arch/blackfin/mach-common/arch_checks.c index f9160d83b91f..5986758b2752 100644 --- a/arch/blackfin/mach-common/arch_checks.c +++ b/arch/blackfin/mach-common/arch_checks.c | |||
@@ -27,6 +27,7 @@ | |||
27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <asm/fixed_code.h> | ||
30 | #include <asm/mach/anomaly.h> | 31 | #include <asm/mach/anomaly.h> |
31 | #include <asm/mach-common/clocks.h> | 32 | #include <asm/mach-common/clocks.h> |
32 | 33 | ||
@@ -53,3 +54,11 @@ | |||
53 | # endif | 54 | # endif |
54 | 55 | ||
55 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ | 56 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ |
57 | |||
58 | #if CONFIG_BOOT_LOAD < FIXED_CODE_END | ||
59 | # error "The kernel load address must be after the fixed code section" | ||
60 | #endif | ||
61 | |||
62 | #if (CONFIG_BOOT_LOAD & 0x3) | ||
63 | # error "The kernel load address must be 4 byte aligned" | ||
64 | #endif | ||
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S index 0521b1588204..85f8c79b3c37 100644 --- a/arch/blackfin/mach-common/cache.S +++ b/arch/blackfin/mach-common/cache.S | |||
@@ -34,81 +34,6 @@ | |||
34 | #include <asm/cache.h> | 34 | #include <asm/cache.h> |
35 | 35 | ||
36 | .text | 36 | .text |
37 | .align 2 | ||
38 | ENTRY(_cache_invalidate) | ||
39 | |||
40 | /* | ||
41 | * Icache or DcacheA or DcacheB Invalidation | ||
42 | * or any combination thereof | ||
43 | * R0 has bits | ||
44 | * CPLB_ENABLE_ICACHE_P,CPLB_ENABLE_DCACHE_P,CPLB_ENABLE_DCACHE2_P | ||
45 | * set as required | ||
46 | */ | ||
47 | [--SP] = R7; | ||
48 | |||
49 | R7 = R0; | ||
50 | CC = BITTST(R7,CPLB_ENABLE_ICACHE_P); | ||
51 | IF !CC JUMP .Lno_icache; | ||
52 | [--SP] = RETS; | ||
53 | CALL _icache_invalidate; | ||
54 | RETS = [SP++]; | ||
55 | .Lno_icache: | ||
56 | CC = BITTST(R7,CPLB_ENABLE_DCACHE_P); | ||
57 | IF !CC JUMP .Lno_dcache_a; | ||
58 | R0 = 0; /* specifies bank A */ | ||
59 | [--SP] = RETS; | ||
60 | CALL _dcache_invalidate; | ||
61 | RETS = [SP++]; | ||
62 | .Lno_dcache_a: | ||
63 | CC = BITTST(R7,CPLB_ENABLE_DCACHE2_P); | ||
64 | IF !CC JUMP .Lno_dcache_b; | ||
65 | R0 = 0; | ||
66 | BITSET(R0, 23); /* specifies bank B */ | ||
67 | [--SP] = RETS; | ||
68 | CALL _dcache_invalidate; | ||
69 | RETS = [SP++]; | ||
70 | .Lno_dcache_b: | ||
71 | R7 = [SP++]; | ||
72 | RTS; | ||
73 | ENDPROC(_cache_invalidate) | ||
74 | |||
75 | /* Invalidate the Entire Instruction cache by | ||
76 | * disabling IMC bit | ||
77 | */ | ||
78 | ENTRY(_icache_invalidate) | ||
79 | ENTRY(_invalidate_entire_icache) | ||
80 | [--SP] = ( R7:5); | ||
81 | |||
82 | P0.L = LO(IMEM_CONTROL); | ||
83 | P0.H = HI(IMEM_CONTROL); | ||
84 | R7 = [P0]; | ||
85 | |||
86 | /* Clear the IMC bit , All valid bits in the instruction | ||
87 | * cache are set to the invalid state | ||
88 | */ | ||
89 | BITCLR(R7,IMC_P); | ||
90 | CLI R6; | ||
91 | SSYNC; /* SSYNC required before invalidating cache. */ | ||
92 | .align 8; | ||
93 | [P0] = R7; | ||
94 | SSYNC; | ||
95 | STI R6; | ||
96 | |||
97 | /* Configures the instruction cache agian */ | ||
98 | R6 = (IMC | ENICPLB); | ||
99 | R7 = R7 | R6; | ||
100 | |||
101 | CLI R6; | ||
102 | SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ | ||
103 | .align 8; | ||
104 | [P0] = R7; | ||
105 | SSYNC; | ||
106 | STI R6; | ||
107 | |||
108 | ( R7:5) = [SP++]; | ||
109 | RTS; | ||
110 | ENDPROC(_invalidate_entire_icache) | ||
111 | ENDPROC(_icache_invalidate) | ||
112 | 37 | ||
113 | /* | 38 | /* |
114 | * blackfin_cache_flush_range(start, end) | 39 | * blackfin_cache_flush_range(start, end) |
@@ -190,46 +115,6 @@ ENTRY(_blackfin_dcache_invalidate_range) | |||
190 | RTS; | 115 | RTS; |
191 | ENDPROC(_blackfin_dcache_invalidate_range) | 116 | ENDPROC(_blackfin_dcache_invalidate_range) |
192 | 117 | ||
193 | /* Invalidate the Entire Data cache by | ||
194 | * clearing DMC[1:0] bits | ||
195 | */ | ||
196 | ENTRY(_invalidate_entire_dcache) | ||
197 | ENTRY(_dcache_invalidate) | ||
198 | [--SP] = ( R7:6); | ||
199 | |||
200 | P0.L = LO(DMEM_CONTROL); | ||
201 | P0.H = HI(DMEM_CONTROL); | ||
202 | R7 = [P0]; | ||
203 | |||
204 | /* Clear the DMC[1:0] bits, All valid bits in the data | ||
205 | * cache are set to the invalid state | ||
206 | */ | ||
207 | BITCLR(R7,DMC0_P); | ||
208 | BITCLR(R7,DMC1_P); | ||
209 | CLI R6; | ||
210 | SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ | ||
211 | .align 8; | ||
212 | [P0] = R7; | ||
213 | SSYNC; | ||
214 | STI R6; | ||
215 | |||
216 | /* Configures the data cache again */ | ||
217 | |||
218 | R6 = DMEM_CNTR; | ||
219 | R7 = R7 | R6; | ||
220 | |||
221 | CLI R6; | ||
222 | SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ | ||
223 | .align 8; | ||
224 | [P0] = R7; | ||
225 | SSYNC; | ||
226 | STI R6; | ||
227 | |||
228 | ( R7:6) = [SP++]; | ||
229 | RTS; | ||
230 | ENDPROC(_dcache_invalidate) | ||
231 | ENDPROC(_invalidate_entire_dcache) | ||
232 | |||
233 | ENTRY(_blackfin_dcache_flush_range) | 118 | ENTRY(_blackfin_dcache_flush_range) |
234 | R2 = -L1_CACHE_BYTES; | 119 | R2 = -L1_CACHE_BYTES; |
235 | R2 = R0 & R2; | 120 | R2 = R0 & R2; |
diff --git a/arch/blackfin/mach-common/cacheinit.S b/arch/blackfin/mach-common/cacheinit.S deleted file mode 100644 index 22fada0c1cb3..000000000000 --- a/arch/blackfin/mach-common/cacheinit.S +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | /* | ||
2 | * File: arch/blackfin/mach-common/cacheinit.S | ||
3 | * Based on: | ||
4 | * Author: LG Soft India | ||
5 | * | ||
6 | * Created: ? | ||
7 | * Description: cache initialization | ||
8 | * | ||
9 | * Modified: | ||
10 | * Copyright 2004-2006 Analog Devices Inc. | ||
11 | * | ||
12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, see the file COPYING, or write | ||
26 | * to the Free Software Foundation, Inc., | ||
27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
28 | */ | ||
29 | |||
30 | /* This function sets up the data and instruction cache. The | ||
31 | * tables like icplb table, dcplb table and Page Descriptor table | ||
32 | * are defined in cplbtab.h. You can configure those tables for | ||
33 | * your suitable requirements | ||
34 | */ | ||
35 | |||
36 | #include <linux/linkage.h> | ||
37 | #include <asm/blackfin.h> | ||
38 | |||
39 | .text | ||
40 | |||
41 | #if ANOMALY_05000125 | ||
42 | #if defined(CONFIG_BFIN_ICACHE) | ||
43 | ENTRY(_bfin_write_IMEM_CONTROL) | ||
44 | |||
45 | /* Enable Instruction Cache */ | ||
46 | P0.l = LO(IMEM_CONTROL); | ||
47 | P0.h = HI(IMEM_CONTROL); | ||
48 | |||
49 | /* Anomaly 05000125 */ | ||
50 | CLI R1; | ||
51 | SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ | ||
52 | .align 8; | ||
53 | [P0] = R0; | ||
54 | SSYNC; | ||
55 | STI R1; | ||
56 | RTS; | ||
57 | |||
58 | ENDPROC(_bfin_write_IMEM_CONTROL) | ||
59 | #endif | ||
60 | |||
61 | #if defined(CONFIG_BFIN_DCACHE) | ||
62 | ENTRY(_bfin_write_DMEM_CONTROL) | ||
63 | P0.l = LO(DMEM_CONTROL); | ||
64 | P0.h = HI(DMEM_CONTROL); | ||
65 | |||
66 | CLI R1; | ||
67 | SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ | ||
68 | .align 8; | ||
69 | [P0] = R0; | ||
70 | SSYNC; | ||
71 | STI R1; | ||
72 | RTS; | ||
73 | |||
74 | ENDPROC(_bfin_write_DMEM_CONTROL) | ||
75 | #endif | ||
76 | |||
77 | #endif | ||
diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S index 5e3f1d8a4fb8..838b0b2ce9a5 100644 --- a/arch/blackfin/mach-common/dpmc_modes.S +++ b/arch/blackfin/mach-common/dpmc_modes.S | |||
@@ -78,62 +78,6 @@ ENTRY(_hibernate_mode) | |||
78 | jump .Lforever; | 78 | jump .Lforever; |
79 | ENDPROC(_hibernate_mode) | 79 | ENDPROC(_hibernate_mode) |
80 | 80 | ||
81 | ENTRY(_deep_sleep) | ||
82 | [--SP] = ( R7:0, P5:0 ); | ||
83 | [--SP] = RETS; | ||
84 | |||
85 | CLI R4; | ||
86 | |||
87 | R0 = IWR_ENABLE(0); | ||
88 | R1 = IWR_DISABLE_ALL; | ||
89 | R2 = IWR_DISABLE_ALL; | ||
90 | |||
91 | call _set_sic_iwr; | ||
92 | |||
93 | call _set_dram_srfs; | ||
94 | |||
95 | /* Clear all the interrupts,bits sticky */ | ||
96 | R0 = 0xFFFF (Z); | ||
97 | call _set_rtc_istat | ||
98 | |||
99 | P0.H = hi(PLL_CTL); | ||
100 | P0.L = lo(PLL_CTL); | ||
101 | R0 = W[P0](z); | ||
102 | BITSET (R0, 5); | ||
103 | W[P0] = R0.L; | ||
104 | |||
105 | call _test_pll_locked; | ||
106 | |||
107 | SSYNC; | ||
108 | IDLE; | ||
109 | |||
110 | call _unset_dram_srfs; | ||
111 | |||
112 | call _test_pll_locked; | ||
113 | |||
114 | R0 = IWR_ENABLE(0); | ||
115 | R1 = IWR_DISABLE_ALL; | ||
116 | R2 = IWR_DISABLE_ALL; | ||
117 | |||
118 | call _set_sic_iwr; | ||
119 | |||
120 | P0.H = hi(PLL_CTL); | ||
121 | P0.L = lo(PLL_CTL); | ||
122 | R0 = w[p0](z); | ||
123 | BITCLR (R0, 3); | ||
124 | BITCLR (R0, 5); | ||
125 | BITCLR (R0, 8); | ||
126 | w[p0] = R0; | ||
127 | IDLE; | ||
128 | call _test_pll_locked; | ||
129 | |||
130 | STI R4; | ||
131 | |||
132 | RETS = [SP++]; | ||
133 | ( R7:0, P5:0 ) = [SP++]; | ||
134 | RTS; | ||
135 | ENDPROC(_deep_sleep) | ||
136 | |||
137 | ENTRY(_sleep_deeper) | 81 | ENTRY(_sleep_deeper) |
138 | [--SP] = ( R7:0, P5:0 ); | 82 | [--SP] = ( R7:0, P5:0 ); |
139 | [--SP] = RETS; | 83 | [--SP] = RETS; |
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index eceb484d90f9..117c01c2c6b0 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -158,14 +158,16 @@ ENTRY(_ex_single_step) | |||
158 | cc = r7 == r6; | 158 | cc = r7 == r6; |
159 | if cc jump _bfin_return_from_exception; | 159 | if cc jump _bfin_return_from_exception; |
160 | 160 | ||
161 | #ifdef CONFIG_KGDB | ||
161 | /* Don't do single step in hardware exception handler */ | 162 | /* Don't do single step in hardware exception handler */ |
162 | p5.l = lo(IPEND); | 163 | p5.l = lo(IPEND); |
163 | p5.h = hi(IPEND); | 164 | p5.h = hi(IPEND); |
164 | r6 = [p5]; | 165 | r6 = [p5]; |
166 | cc = bittst(r6, 4); | ||
167 | if cc jump _bfin_return_from_exception; | ||
165 | cc = bittst(r6, 5); | 168 | cc = bittst(r6, 5); |
166 | if cc jump _bfin_return_from_exception; | 169 | if cc jump _bfin_return_from_exception; |
167 | 170 | ||
168 | #ifdef CONFIG_KGDB | ||
169 | /* skip single step if current interrupt priority is higher than | 171 | /* skip single step if current interrupt priority is higher than |
170 | * that of the first instruction, from which gdb starts single step */ | 172 | * that of the first instruction, from which gdb starts single step */ |
171 | r6 >>= 6; | 173 | r6 >>= 6; |
@@ -186,17 +188,27 @@ ENTRY(_ex_single_step) | |||
186 | if cc jump .Ldo_single_step; | 188 | if cc jump .Ldo_single_step; |
187 | r6 += -1; | 189 | r6 += -1; |
188 | cc = r6 < r7; | 190 | cc = r6 < r7; |
189 | if cc jump _bfin_return_from_exception; | 191 | if cc jump 1f; |
190 | .Ldo_single_step: | 192 | .Ldo_single_step: |
191 | #endif | 193 | #else |
192 | |||
193 | /* If we were in user mode, do the single step normally. */ | 194 | /* If we were in user mode, do the single step normally. */ |
195 | p5.l = lo(IPEND); | ||
196 | p5.h = hi(IPEND); | ||
194 | r6 = [p5]; | 197 | r6 = [p5]; |
195 | r7 = 0xffe0 (z); | 198 | r7 = 0xffe0 (z); |
196 | r7 = r7 & r6; | 199 | r7 = r7 & r6; |
197 | cc = r7 == 0; | 200 | cc = r7 == 0; |
198 | if cc jump 1f; | 201 | if !cc jump 1f; |
202 | #endif | ||
199 | 203 | ||
204 | /* Single stepping only a single instruction, so clear the trace | ||
205 | * bit here. */ | ||
206 | r7 = syscfg; | ||
207 | bitclr (r7, 0); | ||
208 | syscfg = R7; | ||
209 | jump _ex_trap_c; | ||
210 | |||
211 | 1: | ||
200 | /* | 212 | /* |
201 | * We were in an interrupt handler. By convention, all of them save | 213 | * We were in an interrupt handler. By convention, all of them save |
202 | * SYSCFG with their first instruction, so by checking whether our | 214 | * SYSCFG with their first instruction, so by checking whether our |
@@ -224,15 +236,11 @@ ENTRY(_ex_single_step) | |||
224 | cc = R7 == R6; | 236 | cc = R7 == R6; |
225 | if !cc jump _bfin_return_from_exception; | 237 | if !cc jump _bfin_return_from_exception; |
226 | 238 | ||
227 | 1: | ||
228 | /* Single stepping only a single instruction, so clear the trace | ||
229 | * bit here. */ | ||
230 | r7 = syscfg; | 239 | r7 = syscfg; |
231 | bitclr (r7, 0); | 240 | bitclr (r7, 0); |
232 | syscfg = R7; | 241 | syscfg = R7; |
233 | 242 | ||
234 | jump _ex_trap_c; | 243 | /* Fall through to _bfin_return_from_exception. */ |
235 | |||
236 | ENDPROC(_ex_single_step) | 244 | ENDPROC(_ex_single_step) |
237 | 245 | ||
238 | ENTRY(_bfin_return_from_exception) | 246 | ENTRY(_bfin_return_from_exception) |
@@ -1414,6 +1422,12 @@ ENTRY(_sys_call_table) | |||
1414 | .long _sys_semtimedop | 1422 | .long _sys_semtimedop |
1415 | .long _sys_timerfd_settime | 1423 | .long _sys_timerfd_settime |
1416 | .long _sys_timerfd_gettime | 1424 | .long _sys_timerfd_gettime |
1425 | .long _sys_signalfd4 /* 360 */ | ||
1426 | .long _sys_eventfd2 | ||
1427 | .long _sys_epoll_create1 | ||
1428 | .long _sys_dup3 | ||
1429 | .long _sys_pipe2 | ||
1430 | .long _sys_inotify_init1 /* 365 */ | ||
1417 | 1431 | ||
1418 | .rept NR_syscalls-(.-_sys_call_table)/4 | 1432 | .rept NR_syscalls-(.-_sys_call_table)/4 |
1419 | .long _sys_ni_syscall | 1433 | .long _sys_ni_syscall |
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S new file mode 100644 index 000000000000..191b4e974c4b --- /dev/null +++ b/arch/blackfin/mach-common/head.S | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | * Common Blackfin startup code | ||
3 | * | ||
4 | * Copyright 2004-2008 Analog Devices Inc. | ||
5 | * | ||
6 | * Enter bugs at http://blackfin.uclinux.org/ | ||
7 | * | ||
8 | * Licensed under the GPL-2 or later. | ||
9 | */ | ||
10 | |||
11 | #include <linux/linkage.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <asm/blackfin.h> | ||
14 | #include <asm/thread_info.h> | ||
15 | #include <asm/trace.h> | ||
16 | |||
17 | __INIT | ||
18 | |||
19 | #define INITIAL_STACK (L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) | ||
20 | |||
21 | ENTRY(__start) | ||
22 | /* R0: argument of command line string, passed from uboot, save it */ | ||
23 | R7 = R0; | ||
24 | /* Enable Cycle Counter and Nesting Of Interrupts */ | ||
25 | #ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES | ||
26 | R0 = SYSCFG_SNEN; | ||
27 | #else | ||
28 | R0 = SYSCFG_SNEN | SYSCFG_CCEN; | ||
29 | #endif | ||
30 | SYSCFG = R0; | ||
31 | R0 = 0; | ||
32 | |||
33 | /* Clear Out All the data and pointer Registers */ | ||
34 | R1 = R0; | ||
35 | R2 = R0; | ||
36 | R3 = R0; | ||
37 | R4 = R0; | ||
38 | R5 = R0; | ||
39 | R6 = R0; | ||
40 | |||
41 | P0 = R0; | ||
42 | P1 = R0; | ||
43 | P2 = R0; | ||
44 | P3 = R0; | ||
45 | P4 = R0; | ||
46 | P5 = R0; | ||
47 | |||
48 | LC0 = r0; | ||
49 | LC1 = r0; | ||
50 | L0 = r0; | ||
51 | L1 = r0; | ||
52 | L2 = r0; | ||
53 | L3 = r0; | ||
54 | |||
55 | /* Clear Out All the DAG Registers */ | ||
56 | B0 = r0; | ||
57 | B1 = r0; | ||
58 | B2 = r0; | ||
59 | B3 = r0; | ||
60 | |||
61 | I0 = r0; | ||
62 | I1 = r0; | ||
63 | I2 = r0; | ||
64 | I3 = r0; | ||
65 | |||
66 | M0 = r0; | ||
67 | M1 = r0; | ||
68 | M2 = r0; | ||
69 | M3 = r0; | ||
70 | |||
71 | trace_buffer_init(p0,r0); | ||
72 | P0 = R1; | ||
73 | R0 = R1; | ||
74 | |||
75 | /* Turn off the icache */ | ||
76 | p0.l = LO(IMEM_CONTROL); | ||
77 | p0.h = HI(IMEM_CONTROL); | ||
78 | R1 = [p0]; | ||
79 | R0 = ~ENICPLB; | ||
80 | R0 = R0 & R1; | ||
81 | [p0] = R0; | ||
82 | SSYNC; | ||
83 | |||
84 | /* Turn off the dcache */ | ||
85 | p0.l = LO(DMEM_CONTROL); | ||
86 | p0.h = HI(DMEM_CONTROL); | ||
87 | R1 = [p0]; | ||
88 | R0 = ~ENDCPLB; | ||
89 | R0 = R0 & R1; | ||
90 | [p0] = R0; | ||
91 | SSYNC; | ||
92 | |||
93 | /* Save RETX, in case of doublefault */ | ||
94 | p0.l = ___retx; | ||
95 | p0.h = ___retx; | ||
96 | R0 = RETX; | ||
97 | [P0] = R0; | ||
98 | |||
99 | /* Initialize stack pointer */ | ||
100 | sp.l = lo(INITIAL_STACK); | ||
101 | sp.h = hi(INITIAL_STACK); | ||
102 | fp = sp; | ||
103 | usp = sp; | ||
104 | |||
105 | #ifdef CONFIG_EARLY_PRINTK | ||
106 | call _init_early_exception_vectors; | ||
107 | #endif | ||
108 | |||
109 | /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ | ||
110 | call _bf53x_relocate_l1_mem; | ||
111 | #ifdef CONFIG_BFIN_KERNEL_CLOCK | ||
112 | call _start_dma_code; | ||
113 | #endif | ||
114 | |||
115 | /* This section keeps the processor in supervisor mode | ||
116 | * during kernel boot. Switches to user mode at end of boot. | ||
117 | * See page 3-9 of Hardware Reference manual for documentation. | ||
118 | */ | ||
119 | |||
120 | /* EVT15 = _real_start */ | ||
121 | |||
122 | p0.l = lo(EVT15); | ||
123 | p0.h = hi(EVT15); | ||
124 | p1.l = _real_start; | ||
125 | p1.h = _real_start; | ||
126 | [p0] = p1; | ||
127 | csync; | ||
128 | |||
129 | p0.l = lo(IMASK); | ||
130 | p0.h = hi(IMASK); | ||
131 | p1.l = IMASK_IVG15; | ||
132 | p1.h = 0x0; | ||
133 | [p0] = p1; | ||
134 | csync; | ||
135 | |||
136 | raise 15; | ||
137 | p0.l = .LWAIT_HERE; | ||
138 | p0.h = .LWAIT_HERE; | ||
139 | reti = p0; | ||
140 | #if ANOMALY_05000281 | ||
141 | nop; nop; nop; | ||
142 | #endif | ||
143 | rti; | ||
144 | |||
145 | .LWAIT_HERE: | ||
146 | jump .LWAIT_HERE; | ||
147 | ENDPROC(__start) | ||
148 | |||
149 | /* A little BF561 glue ... */ | ||
150 | #ifndef WDOG_CTL | ||
151 | # define WDOG_CTL WDOGA_CTL | ||
152 | #endif | ||
153 | |||
154 | ENTRY(_real_start) | ||
155 | /* Enable nested interrupts */ | ||
156 | [--sp] = reti; | ||
157 | |||
158 | /* watchdog off for now */ | ||
159 | p0.l = lo(WDOG_CTL); | ||
160 | p0.h = hi(WDOG_CTL); | ||
161 | r0 = 0xAD6(z); | ||
162 | w[p0] = r0; | ||
163 | ssync; | ||
164 | |||
165 | /* Zero out the bss region | ||
166 | * Note: this will fail if bss is 0 bytes ... | ||
167 | */ | ||
168 | r0 = 0 (z); | ||
169 | r1.l = ___bss_start; | ||
170 | r1.h = ___bss_start; | ||
171 | r2.l = ___bss_stop; | ||
172 | r2.h = ___bss_stop; | ||
173 | r2 = r2 - r1; | ||
174 | r2 >>= 2; | ||
175 | p1 = r1; | ||
176 | p2 = r2; | ||
177 | lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2; | ||
178 | .L_clear_bss: | ||
179 | [p1++] = r0; | ||
180 | |||
181 | /* In case there is a NULL pointer reference, | ||
182 | * zero out region before stext | ||
183 | */ | ||
184 | p1 = r0; | ||
185 | r2.l = __stext; | ||
186 | r2.h = __stext; | ||
187 | r2 >>= 2; | ||
188 | p2 = r2; | ||
189 | lsetup (.L_clear_zero, .L_clear_zero) lc0 = p2; | ||
190 | .L_clear_zero: | ||
191 | [p1++] = r0; | ||
192 | |||
193 | /* Pass the u-boot arguments to the global value command line */ | ||
194 | R0 = R7; | ||
195 | call _cmdline_init; | ||
196 | |||
197 | /* Load the current thread pointer and stack */ | ||
198 | sp.l = _init_thread_union; | ||
199 | sp.h = _init_thread_union; | ||
200 | p1 = THREAD_SIZE (z); | ||
201 | sp = sp + p1; | ||
202 | usp = sp; | ||
203 | fp = sp; | ||
204 | jump.l _start_kernel; | ||
205 | ENDPROC(_real_start) | ||
206 | |||
207 | __FINIT | ||
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 64d746114e4b..62f8883a5c27 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -71,6 +71,7 @@ atomic_t num_spurious; | |||
71 | 71 | ||
72 | #ifdef CONFIG_PM | 72 | #ifdef CONFIG_PM |
73 | unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */ | 73 | unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */ |
74 | unsigned vr_wakeup; | ||
74 | #endif | 75 | #endif |
75 | 76 | ||
76 | struct ivgx { | 77 | struct ivgx { |
@@ -184,17 +185,56 @@ static void bfin_internal_unmask_irq(unsigned int irq) | |||
184 | #ifdef CONFIG_PM | 185 | #ifdef CONFIG_PM |
185 | int bfin_internal_set_wake(unsigned int irq, unsigned int state) | 186 | int bfin_internal_set_wake(unsigned int irq, unsigned int state) |
186 | { | 187 | { |
187 | unsigned bank, bit; | 188 | unsigned bank, bit, wakeup = 0; |
188 | unsigned long flags; | 189 | unsigned long flags; |
189 | bank = SIC_SYSIRQ(irq) / 32; | 190 | bank = SIC_SYSIRQ(irq) / 32; |
190 | bit = SIC_SYSIRQ(irq) % 32; | 191 | bit = SIC_SYSIRQ(irq) % 32; |
191 | 192 | ||
193 | switch (irq) { | ||
194 | #ifdef IRQ_RTC | ||
195 | case IRQ_RTC: | ||
196 | wakeup |= WAKE; | ||
197 | break; | ||
198 | #endif | ||
199 | #ifdef IRQ_CAN0_RX | ||
200 | case IRQ_CAN0_RX: | ||
201 | wakeup |= CANWE; | ||
202 | break; | ||
203 | #endif | ||
204 | #ifdef IRQ_CAN1_RX | ||
205 | case IRQ_CAN1_RX: | ||
206 | wakeup |= CANWE; | ||
207 | break; | ||
208 | #endif | ||
209 | #ifdef IRQ_USB_INT0 | ||
210 | case IRQ_USB_INT0: | ||
211 | wakeup |= USBWE; | ||
212 | break; | ||
213 | #endif | ||
214 | #ifdef IRQ_KEY | ||
215 | case IRQ_KEY: | ||
216 | wakeup |= KPADWE; | ||
217 | break; | ||
218 | #endif | ||
219 | #ifdef IRQ_CNT | ||
220 | case IRQ_CNT: | ||
221 | wakeup |= ROTWE; | ||
222 | break; | ||
223 | #endif | ||
224 | default: | ||
225 | break; | ||
226 | } | ||
227 | |||
192 | local_irq_save(flags); | 228 | local_irq_save(flags); |
193 | 229 | ||
194 | if (state) | 230 | if (state) { |
195 | bfin_sic_iwr[bank] |= (1 << bit); | 231 | bfin_sic_iwr[bank] |= (1 << bit); |
196 | else | 232 | vr_wakeup |= wakeup; |
233 | |||
234 | } else { | ||
197 | bfin_sic_iwr[bank] &= ~(1 << bit); | 235 | bfin_sic_iwr[bank] &= ~(1 << bit); |
236 | vr_wakeup &= ~wakeup; | ||
237 | } | ||
198 | 238 | ||
199 | local_irq_restore(flags); | 239 | local_irq_restore(flags); |
200 | 240 | ||
@@ -943,6 +983,11 @@ int __init init_arch_irq(void) | |||
943 | 983 | ||
944 | local_irq_disable(); | 984 | local_irq_disable(); |
945 | 985 | ||
986 | #if defined(CONFIG_BF527) || defined(CONFIG_BF536) || defined(CONFIG_BF537) | ||
987 | /* Clear EMAC Interrupt Status bits so we can demux it later */ | ||
988 | bfin_write_EMAC_SYSTAT(-1); | ||
989 | #endif | ||
990 | |||
946 | #ifdef CONFIG_BF54x | 991 | #ifdef CONFIG_BF54x |
947 | # ifdef CONFIG_PINTx_REASSIGN | 992 | # ifdef CONFIG_PINTx_REASSIGN |
948 | pint[0]->assign = CONFIG_PINT0_ASSIGN; | 993 | pint[0]->assign = CONFIG_PINT0_ASSIGN; |
@@ -1028,13 +1073,22 @@ int __init init_arch_irq(void) | |||
1028 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; | 1073 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; |
1029 | 1074 | ||
1030 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) | 1075 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) |
1031 | bfin_write_SIC_IWR0(IWR_ENABLE_ALL); | 1076 | bfin_write_SIC_IWR0(IWR_DISABLE_ALL); |
1032 | bfin_write_SIC_IWR1(IWR_ENABLE_ALL); | 1077 | #if defined(CONFIG_BF52x) |
1078 | /* BF52x system reset does not properly reset SIC_IWR1 which | ||
1079 | * will screw up the bootrom as it relies on MDMA0/1 waking it | ||
1080 | * up from IDLE instructions. See this report for more info: | ||
1081 | * http://blackfin.uclinux.org/gf/tracker/4323 | ||
1082 | */ | ||
1083 | bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11)); | ||
1084 | #else | ||
1085 | bfin_write_SIC_IWR1(IWR_DISABLE_ALL); | ||
1086 | #endif | ||
1033 | # ifdef CONFIG_BF54x | 1087 | # ifdef CONFIG_BF54x |
1034 | bfin_write_SIC_IWR2(IWR_ENABLE_ALL); | 1088 | bfin_write_SIC_IWR2(IWR_DISABLE_ALL); |
1035 | # endif | 1089 | # endif |
1036 | #else | 1090 | #else |
1037 | bfin_write_SIC_IWR(IWR_ENABLE_ALL); | 1091 | bfin_write_SIC_IWR(IWR_DISABLE_ALL); |
1038 | #endif | 1092 | #endif |
1039 | 1093 | ||
1040 | return 0; | 1094 | return 0; |
diff --git a/arch/blackfin/mach-common/lock.S b/arch/blackfin/mach-common/lock.S index 30b887e67dd6..9daf01201e9f 100644 --- a/arch/blackfin/mach-common/lock.S +++ b/arch/blackfin/mach-common/lock.S | |||
@@ -28,13 +28,10 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/linkage.h> | 30 | #include <linux/linkage.h> |
31 | #include <asm/cplb.h> | ||
32 | #include <asm/blackfin.h> | 31 | #include <asm/blackfin.h> |
33 | 32 | ||
34 | .text | 33 | .text |
35 | 34 | ||
36 | #ifdef CONFIG_BFIN_ICACHE_LOCK | ||
37 | |||
38 | /* When you come here, it is assumed that | 35 | /* When you come here, it is assumed that |
39 | * R0 - Which way to be locked | 36 | * R0 - Which way to be locked |
40 | */ | 37 | */ |
@@ -189,18 +186,38 @@ ENTRY(_cache_lock) | |||
189 | RTS; | 186 | RTS; |
190 | ENDPROC(_cache_lock) | 187 | ENDPROC(_cache_lock) |
191 | 188 | ||
192 | #endif /* BFIN_ICACHE_LOCK */ | 189 | /* Invalidate the Entire Instruction cache by |
193 | 190 | * disabling IMC bit | |
194 | /* Return the ILOC bits of IMEM_CONTROL | ||
195 | */ | 191 | */ |
192 | ENTRY(_invalidate_entire_icache) | ||
193 | [--SP] = ( R7:5); | ||
196 | 194 | ||
197 | ENTRY(_read_iloc) | 195 | P0.L = LO(IMEM_CONTROL); |
198 | P1.H = HI(IMEM_CONTROL); | 196 | P0.H = HI(IMEM_CONTROL); |
199 | P1.L = LO(IMEM_CONTROL); | 197 | R7 = [P0]; |
200 | R1 = 0xF; | 198 | |
201 | R0 = [P1]; | 199 | /* Clear the IMC bit , All valid bits in the instruction |
202 | R0 = R0 >> 3; | 200 | * cache are set to the invalid state |
203 | R0 = R0 & R1; | 201 | */ |
202 | BITCLR(R7,IMC_P); | ||
203 | CLI R6; | ||
204 | SSYNC; /* SSYNC required before invalidating cache. */ | ||
205 | .align 8; | ||
206 | [P0] = R7; | ||
207 | SSYNC; | ||
208 | STI R6; | ||
209 | |||
210 | /* Configures the instruction cache agian */ | ||
211 | R6 = (IMC | ENICPLB); | ||
212 | R7 = R7 | R6; | ||
213 | |||
214 | CLI R6; | ||
215 | SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ | ||
216 | .align 8; | ||
217 | [P0] = R7; | ||
218 | SSYNC; | ||
219 | STI R6; | ||
204 | 220 | ||
221 | ( R7:5) = [SP++]; | ||
205 | RTS; | 222 | RTS; |
206 | ENDPROC(_read_iloc) | 223 | ENDPROC(_invalidate_entire_icache) |
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 4fe6a2366b13..e28c6af1f415 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c | |||
@@ -83,13 +83,22 @@ void bfin_pm_suspend_standby_enter(void) | |||
83 | bfin_pm_standby_restore(); | 83 | bfin_pm_standby_restore(); |
84 | 84 | ||
85 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) | 85 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) |
86 | bfin_write_SIC_IWR0(IWR_ENABLE_ALL); | 86 | bfin_write_SIC_IWR0(IWR_DISABLE_ALL); |
87 | bfin_write_SIC_IWR1(IWR_ENABLE_ALL); | 87 | #if defined(CONFIG_BF52x) |
88 | /* BF52x system reset does not properly reset SIC_IWR1 which | ||
89 | * will screw up the bootrom as it relies on MDMA0/1 waking it | ||
90 | * up from IDLE instructions. See this report for more info: | ||
91 | * http://blackfin.uclinux.org/gf/tracker/4323 | ||
92 | */ | ||
93 | bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11)); | ||
94 | #else | ||
95 | bfin_write_SIC_IWR1(IWR_DISABLE_ALL); | ||
96 | #endif | ||
88 | # ifdef CONFIG_BF54x | 97 | # ifdef CONFIG_BF54x |
89 | bfin_write_SIC_IWR2(IWR_ENABLE_ALL); | 98 | bfin_write_SIC_IWR2(IWR_DISABLE_ALL); |
90 | # endif | 99 | # endif |
91 | #else | 100 | #else |
92 | bfin_write_SIC_IWR(IWR_ENABLE_ALL); | 101 | bfin_write_SIC_IWR(IWR_DISABLE_ALL); |
93 | #endif | 102 | #endif |
94 | 103 | ||
95 | local_irq_restore(flags); | 104 | local_irq_restore(flags); |
@@ -229,28 +238,12 @@ int bfin_pm_suspend_mem_enter(void) | |||
229 | wakeup = bfin_read_VR_CTL() & ~FREQ; | 238 | wakeup = bfin_read_VR_CTL() & ~FREQ; |
230 | wakeup |= SCKELOW; | 239 | wakeup |= SCKELOW; |
231 | 240 | ||
232 | /* FIXME: merge this somehow with set_irq_wake */ | ||
233 | #ifdef CONFIG_PM_BFIN_WAKE_RTC | ||
234 | wakeup |= WAKE; | ||
235 | #endif | ||
236 | #ifdef CONFIG_PM_BFIN_WAKE_PH6 | 241 | #ifdef CONFIG_PM_BFIN_WAKE_PH6 |
237 | wakeup |= PHYWE; | 242 | wakeup |= PHYWE; |
238 | #endif | 243 | #endif |
239 | #ifdef CONFIG_PM_BFIN_WAKE_CAN | ||
240 | wakeup |= CANWE; | ||
241 | #endif | ||
242 | #ifdef CONFIG_PM_BFIN_WAKE_GP | 244 | #ifdef CONFIG_PM_BFIN_WAKE_GP |
243 | wakeup |= GPWE; | 245 | wakeup |= GPWE; |
244 | #endif | 246 | #endif |
245 | #ifdef CONFIG_PM_BFIN_WAKE_USB | ||
246 | wakeup |= USBWE; | ||
247 | #endif | ||
248 | #ifdef CONFIG_PM_BFIN_WAKE_KEYPAD | ||
249 | wakeup |= KPADWE; | ||
250 | #endif | ||
251 | #ifdef CONFIG_PM_BFIN_WAKE_ROTARY | ||
252 | wakeup |= ROTWE; | ||
253 | #endif | ||
254 | 247 | ||
255 | local_irq_save(flags); | 248 | local_irq_save(flags); |
256 | 249 | ||
@@ -268,7 +261,7 @@ int bfin_pm_suspend_mem_enter(void) | |||
268 | icache_disable(); | 261 | icache_disable(); |
269 | bf53x_suspend_l1_mem(memptr); | 262 | bf53x_suspend_l1_mem(memptr); |
270 | 263 | ||
271 | do_hibernate(wakeup); /* Goodbye */ | 264 | do_hibernate(wakeup | vr_wakeup); /* Goodbye */ |
272 | 265 | ||
273 | bf53x_resume_l1_mem(memptr); | 266 | bf53x_resume_l1_mem(memptr); |
274 | 267 | ||