summaryrefslogtreecommitdiff
path: root/arch/blackfin/mach-common
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r--arch/blackfin/mach-common/Makefile5
-rw-r--r--arch/blackfin/mach-common/arch_checks.c9
-rw-r--r--arch/blackfin/mach-common/cache.S115
-rw-r--r--arch/blackfin/mach-common/cacheinit.S77
-rw-r--r--arch/blackfin/mach-common/dpmc_modes.S56
-rw-r--r--arch/blackfin/mach-common/entry.S34
-rw-r--r--arch/blackfin/mach-common/head.S207
-rw-r--r--arch/blackfin/mach-common/ints-priority.c68
-rw-r--r--arch/blackfin/mach-common/lock.S45
-rw-r--r--arch/blackfin/mach-common/pm.c35
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 @@
#
obj-y := \
- cache.o cacheinit.o entry.o \
- interrupt.o lock.o irqpanic.o arch_checks.o ints-priority.o
+ cache.o entry.o head.o \
+ interrupt.o irqpanic.o arch_checks.o ints-priority.o
+obj-$(CONFIG_BFIN_ICACHE_LOCK) += lock.o
obj-$(CONFIG_PM) += pm.o dpmc_modes.o
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
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 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <asm/fixed_code.h>
#include <asm/mach/anomaly.h>
#include <asm/mach-common/clocks.h>
@@ -53,3 +54,11 @@
# endif
#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+#if CONFIG_BOOT_LOAD < FIXED_CODE_END
+# error "The kernel load address must be after the fixed code section"
+#endif
+
+#if (CONFIG_BOOT_LOAD & 0x3)
+# error "The kernel load address must be 4 byte aligned"
+#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 @@
#include <asm/cache.h>
.text
-.align 2
-ENTRY(_cache_invalidate)
-
- /*
- * Icache or DcacheA or DcacheB Invalidation
- * or any combination thereof
- * R0 has bits
- * CPLB_ENABLE_ICACHE_P,CPLB_ENABLE_DCACHE_P,CPLB_ENABLE_DCACHE2_P
- * set as required
- */
- [--SP] = R7;
-
- R7 = R0;
- CC = BITTST(R7,CPLB_ENABLE_ICACHE_P);
- IF !CC JUMP .Lno_icache;
- [--SP] = RETS;
- CALL _icache_invalidate;
- RETS = [SP++];
-.Lno_icache:
- CC = BITTST(R7,CPLB_ENABLE_DCACHE_P);
- IF !CC JUMP .Lno_dcache_a;
- R0 = 0; /* specifies bank A */
- [--SP] = RETS;
- CALL _dcache_invalidate;
- RETS = [SP++];
-.Lno_dcache_a:
- CC = BITTST(R7,CPLB_ENABLE_DCACHE2_P);
- IF !CC JUMP .Lno_dcache_b;
- R0 = 0;
- BITSET(R0, 23); /* specifies bank B */
- [--SP] = RETS;
- CALL _dcache_invalidate;
- RETS = [SP++];
-.Lno_dcache_b:
- R7 = [SP++];
- RTS;
-ENDPROC(_cache_invalidate)
-
-/* Invalidate the Entire Instruction cache by
- * disabling IMC bit
- */
-ENTRY(_icache_invalidate)
-ENTRY(_invalidate_entire_icache)
- [--SP] = ( R7:5);
-
- P0.L = LO(IMEM_CONTROL);
- P0.H = HI(IMEM_CONTROL);
- R7 = [P0];
-
- /* Clear the IMC bit , All valid bits in the instruction
- * cache are set to the invalid state
- */
- BITCLR(R7,IMC_P);
- CLI R6;
- SSYNC; /* SSYNC required before invalidating cache. */
- .align 8;
- [P0] = R7;
- SSYNC;
- STI R6;
-
- /* Configures the instruction cache agian */
- R6 = (IMC | ENICPLB);
- R7 = R7 | R6;
-
- CLI R6;
- SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
- .align 8;
- [P0] = R7;
- SSYNC;
- STI R6;
-
- ( R7:5) = [SP++];
- RTS;
-ENDPROC(_invalidate_entire_icache)
-ENDPROC(_icache_invalidate)
/*
* blackfin_cache_flush_range(start, end)
@@ -190,46 +115,6 @@ ENTRY(_blackfin_dcache_invalidate_range)
RTS;
ENDPROC(_blackfin_dcache_invalidate_range)
-/* Invalidate the Entire Data cache by
- * clearing DMC[1:0] bits
- */
-ENTRY(_invalidate_entire_dcache)
-ENTRY(_dcache_invalidate)
- [--SP] = ( R7:6);
-
- P0.L = LO(DMEM_CONTROL);
- P0.H = HI(DMEM_CONTROL);
- R7 = [P0];
-
- /* Clear the DMC[1:0] bits, All valid bits in the data
- * cache are set to the invalid state
- */
- BITCLR(R7,DMC0_P);
- BITCLR(R7,DMC1_P);
- CLI R6;
- SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
- .align 8;
- [P0] = R7;
- SSYNC;
- STI R6;
-
- /* Configures the data cache again */
-
- R6 = DMEM_CNTR;
- R7 = R7 | R6;
-
- CLI R6;
- SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
- .align 8;
- [P0] = R7;
- SSYNC;
- STI R6;
-
- ( R7:6) = [SP++];
- RTS;
-ENDPROC(_dcache_invalidate)
-ENDPROC(_invalidate_entire_dcache)
-
ENTRY(_blackfin_dcache_flush_range)
R2 = -L1_CACHE_BYTES;
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 @@
-/*
- * File: arch/blackfin/mach-common/cacheinit.S
- * Based on:
- * Author: LG Soft India
- *
- * Created: ?
- * Description: cache initialization
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* This function sets up the data and instruction cache. The
- * tables like icplb table, dcplb table and Page Descriptor table
- * are defined in cplbtab.h. You can configure those tables for
- * your suitable requirements
- */
-
-#include <linux/linkage.h>
-#include <asm/blackfin.h>
-
-.text
-
-#if ANOMALY_05000125
-#if defined(CONFIG_BFIN_ICACHE)
-ENTRY(_bfin_write_IMEM_CONTROL)
-
- /* Enable Instruction Cache */
- P0.l = LO(IMEM_CONTROL);
- P0.h = HI(IMEM_CONTROL);
-
- /* Anomaly 05000125 */
- CLI R1;
- SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
- .align 8;
- [P0] = R0;
- SSYNC;
- STI R1;
- RTS;
-
-ENDPROC(_bfin_write_IMEM_CONTROL)
-#endif
-
-#if defined(CONFIG_BFIN_DCACHE)
-ENTRY(_bfin_write_DMEM_CONTROL)
- P0.l = LO(DMEM_CONTROL);
- P0.h = HI(DMEM_CONTROL);
-
- CLI R1;
- SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
- .align 8;
- [P0] = R0;
- SSYNC;
- STI R1;
- RTS;
-
-ENDPROC(_bfin_write_DMEM_CONTROL)
-#endif
-
-#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)
jump .Lforever;
ENDPROC(_hibernate_mode)
-ENTRY(_deep_sleep)
- [--SP] = ( R7:0, P5:0 );
- [--SP] = RETS;
-
- CLI R4;
-
- R0 = IWR_ENABLE(0);
- R1 = IWR_DISABLE_ALL;
- R2 = IWR_DISABLE_ALL;
-
- call _set_sic_iwr;
-
- call _set_dram_srfs;
-
- /* Clear all the interrupts,bits sticky */
- R0 = 0xFFFF (Z);
- call _set_rtc_istat
-
- P0.H = hi(PLL_CTL);
- P0.L = lo(PLL_CTL);
- R0 = W[P0](z);
- BITSET (R0, 5);
- W[P0] = R0.L;
-
- call _test_pll_locked;
-
- SSYNC;
- IDLE;
-
- call _unset_dram_srfs;
-
- call _test_pll_locked;
-
- R0 = IWR_ENABLE(0);
- R1 = IWR_DISABLE_ALL;
- R2 = IWR_DISABLE_ALL;
-
- call _set_sic_iwr;
-
- P0.H = hi(PLL_CTL);
- P0.L = lo(PLL_CTL);
- R0 = w[p0](z);
- BITCLR (R0, 3);
- BITCLR (R0, 5);
- BITCLR (R0, 8);
- w[p0] = R0;
- IDLE;
- call _test_pll_locked;
-
- STI R4;
-
- RETS = [SP++];
- ( R7:0, P5:0 ) = [SP++];
- RTS;
-ENDPROC(_deep_sleep)
-
ENTRY(_sleep_deeper)
[--SP] = ( R7:0, P5:0 );
[--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)
cc = r7 == r6;
if cc jump _bfin_return_from_exception;
+#ifdef CONFIG_KGDB
/* Don't do single step in hardware exception handler */
p5.l = lo(IPEND);
p5.h = hi(IPEND);
r6 = [p5];
+ cc = bittst(r6, 4);
+ if cc jump _bfin_return_from_exception;
cc = bittst(r6, 5);
if cc jump _bfin_return_from_exception;
-#ifdef CONFIG_KGDB
/* skip single step if current interrupt priority is higher than
* that of the first instruction, from which gdb starts single step */
r6 >>= 6;
@@ -186,17 +188,27 @@ ENTRY(_ex_single_step)
if cc jump .Ldo_single_step;
r6 += -1;
cc = r6 < r7;
- if cc jump _bfin_return_from_exception;
+ if cc jump 1f;
.Ldo_single_step:
-#endif
-
+#else
/* If we were in user mode, do the single step normally. */
+ p5.l = lo(IPEND);
+ p5.h = hi(IPEND);
r6 = [p5];
r7 = 0xffe0 (z);
r7 = r7 & r6;
cc = r7 == 0;
- if cc jump 1f;
+ if !cc jump 1f;
+#endif
+ /* Single stepping only a single instruction, so clear the trace
+ * bit here. */
+ r7 = syscfg;
+ bitclr (r7, 0);
+ syscfg = R7;
+ jump _ex_trap_c;
+
+1:
/*
* We were in an interrupt handler. By convention, all of them save
* SYSCFG with their first instruction, so by checking whether our
@@ -224,15 +236,11 @@ ENTRY(_ex_single_step)
cc = R7 == R6;
if !cc jump _bfin_return_from_exception;
-1:
- /* Single stepping only a single instruction, so clear the trace
- * bit here. */
r7 = syscfg;
bitclr (r7, 0);
syscfg = R7;
- jump _ex_trap_c;
-
+ /* Fall through to _bfin_return_from_exception. */
ENDPROC(_ex_single_step)
ENTRY(_bfin_return_from_exception)
@@ -1414,6 +1422,12 @@ ENTRY(_sys_call_table)
.long _sys_semtimedop
.long _sys_timerfd_settime
.long _sys_timerfd_gettime
+ .long _sys_signalfd4 /* 360 */
+ .long _sys_eventfd2
+ .long _sys_epoll_create1
+ .long _sys_dup3
+ .long _sys_pipe2
+ .long _sys_inotify_init1 /* 365 */
.rept NR_syscalls-(.-_sys_call_table)/4
.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 @@
+/*
+ * Common Blackfin startup code
+ *
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/blackfin.h>
+#include <asm/thread_info.h>
+#include <asm/trace.h>
+
+__INIT
+
+#define INITIAL_STACK (L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
+
+ENTRY(__start)
+ /* R0: argument of command line string, passed from uboot, save it */
+ R7 = R0;
+ /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+ R0 = SYSCFG_SNEN;
+#else
+ R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
+ SYSCFG = R0;
+ R0 = 0;
+
+ /* Clear Out All the data and pointer Registers */
+ R1 = R0;
+ R2 = R0;
+ R3 = R0;
+ R4 = R0;
+ R5 = R0;
+ R6 = R0;
+
+ P0 = R0;
+ P1 = R0;
+ P2 = R0;
+ P3 = R0;
+ P4 = R0;
+ P5 = R0;
+
+ LC0 = r0;
+ LC1 = r0;
+ L0 = r0;
+ L1 = r0;
+ L2 = r0;
+ L3 = r0;
+
+ /* Clear Out All the DAG Registers */
+ B0 = r0;
+ B1 = r0;
+ B2 = r0;
+ B3 = r0;
+
+ I0 = r0;
+ I1 = r0;
+ I2 = r0;
+ I3 = r0;
+
+ M0 = r0;
+ M1 = r0;
+ M2 = r0;
+ M3 = r0;
+
+ trace_buffer_init(p0,r0);
+ P0 = R1;
+ R0 = R1;
+
+ /* Turn off the icache */
+ p0.l = LO(IMEM_CONTROL);
+ p0.h = HI(IMEM_CONTROL);
+ R1 = [p0];
+ R0 = ~ENICPLB;
+ R0 = R0 & R1;
+ [p0] = R0;
+ SSYNC;
+
+ /* Turn off the dcache */
+ p0.l = LO(DMEM_CONTROL);
+ p0.h = HI(DMEM_CONTROL);
+ R1 = [p0];
+ R0 = ~ENDCPLB;
+ R0 = R0 & R1;
+ [p0] = R0;
+ SSYNC;
+
+ /* Save RETX, in case of doublefault */
+ p0.l = ___retx;
+ p0.h = ___retx;
+ R0 = RETX;
+ [P0] = R0;
+
+ /* Initialize stack pointer */
+ sp.l = lo(INITIAL_STACK);
+ sp.h = hi(INITIAL_STACK);
+ fp = sp;
+ usp = sp;
+
+#ifdef CONFIG_EARLY_PRINTK
+ call _init_early_exception_vectors;
+#endif
+
+ /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
+ call _bf53x_relocate_l1_mem;
+#ifdef CONFIG_BFIN_KERNEL_CLOCK
+ call _start_dma_code;
+#endif
+
+ /* This section keeps the processor in supervisor mode
+ * during kernel boot. Switches to user mode at end of boot.
+ * See page 3-9 of Hardware Reference manual for documentation.
+ */
+
+ /* EVT15 = _real_start */
+
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _real_start;
+ p1.h = _real_start;
+ [p0] = p1;
+ csync;
+
+ p0.l = lo(IMASK);
+ p0.h = hi(IMASK);
+ p1.l = IMASK_IVG15;
+ p1.h = 0x0;
+ [p0] = p1;
+ csync;
+
+ raise 15;
+ p0.l = .LWAIT_HERE;
+ p0.h = .LWAIT_HERE;
+ reti = p0;
+#if ANOMALY_05000281
+ nop; nop; nop;
+#endif
+ rti;
+
+.LWAIT_HERE:
+ jump .LWAIT_HERE;
+ENDPROC(__start)
+
+/* A little BF561 glue ... */
+#ifndef WDOG_CTL
+# define WDOG_CTL WDOGA_CTL
+#endif
+
+ENTRY(_real_start)
+ /* Enable nested interrupts */
+ [--sp] = reti;
+
+ /* watchdog off for now */
+ p0.l = lo(WDOG_CTL);
+ p0.h = hi(WDOG_CTL);
+ r0 = 0xAD6(z);
+ w[p0] = r0;
+ ssync;
+
+ /* Zero out the bss region
+ * Note: this will fail if bss is 0 bytes ...
+ */
+ r0 = 0 (z);
+ r1.l = ___bss_start;
+ r1.h = ___bss_start;
+ r2.l = ___bss_stop;
+ r2.h = ___bss_stop;
+ r2 = r2 - r1;
+ r2 >>= 2;
+ p1 = r1;
+ p2 = r2;
+ lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2;
+.L_clear_bss:
+ [p1++] = r0;
+
+ /* In case there is a NULL pointer reference,
+ * zero out region before stext
+ */
+ p1 = r0;
+ r2.l = __stext;
+ r2.h = __stext;
+ r2 >>= 2;
+ p2 = r2;
+ lsetup (.L_clear_zero, .L_clear_zero) lc0 = p2;
+.L_clear_zero:
+ [p1++] = r0;
+
+ /* Pass the u-boot arguments to the global value command line */
+ R0 = R7;
+ call _cmdline_init;
+
+ /* Load the current thread pointer and stack */
+ sp.l = _init_thread_union;
+ sp.h = _init_thread_union;
+ p1 = THREAD_SIZE (z);
+ sp = sp + p1;
+ usp = sp;
+ fp = sp;
+ jump.l _start_kernel;
+ENDPROC(_real_start)
+
+__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;
#ifdef CONFIG_PM
unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */
+unsigned vr_wakeup;
#endif
struct ivgx {
@@ -184,17 +185,56 @@ static void bfin_internal_unmask_irq(unsigned int irq)
#ifdef CONFIG_PM
int bfin_internal_set_wake(unsigned int irq, unsigned int state)
{
- unsigned bank, bit;
+ unsigned bank, bit, wakeup = 0;
unsigned long flags;
bank = SIC_SYSIRQ(irq) / 32;
bit = SIC_SYSIRQ(irq) % 32;
+ switch (irq) {
+#ifdef IRQ_RTC
+ case IRQ_RTC:
+ wakeup |= WAKE;
+ break;
+#endif
+#ifdef IRQ_CAN0_RX
+ case IRQ_CAN0_RX:
+ wakeup |= CANWE;
+ break;
+#endif
+#ifdef IRQ_CAN1_RX
+ case IRQ_CAN1_RX:
+ wakeup |= CANWE;
+ break;
+#endif
+#ifdef IRQ_USB_INT0
+ case IRQ_USB_INT0:
+ wakeup |= USBWE;
+ break;
+#endif
+#ifdef IRQ_KEY
+ case IRQ_KEY:
+ wakeup |= KPADWE;
+ break;
+#endif
+#ifdef IRQ_CNT
+ case IRQ_CNT:
+ wakeup |= ROTWE;
+ break;
+#endif
+ default:
+ break;
+ }
+
local_irq_save(flags);
- if (state)
+ if (state) {
bfin_sic_iwr[bank] |= (1 << bit);
- else
+ vr_wakeup |= wakeup;
+
+ } else {
bfin_sic_iwr[bank] &= ~(1 << bit);
+ vr_wakeup &= ~wakeup;
+ }
local_irq_restore(flags);
@@ -943,6 +983,11 @@ int __init init_arch_irq(void)
local_irq_disable();
+#if defined(CONFIG_BF527) || defined(CONFIG_BF536) || defined(CONFIG_BF537)
+ /* Clear EMAC Interrupt Status bits so we can demux it later */
+ bfin_write_EMAC_SYSTAT(-1);
+#endif
+
#ifdef CONFIG_BF54x
# ifdef CONFIG_PINTx_REASSIGN
pint[0]->assign = CONFIG_PINT0_ASSIGN;
@@ -1028,13 +1073,22 @@ int __init init_arch_irq(void)
IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
- bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
- bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
+ bfin_write_SIC_IWR0(IWR_DISABLE_ALL);
+#if defined(CONFIG_BF52x)
+ /* BF52x system reset does not properly reset SIC_IWR1 which
+ * will screw up the bootrom as it relies on MDMA0/1 waking it
+ * up from IDLE instructions. See this report for more info:
+ * http://blackfin.uclinux.org/gf/tracker/4323
+ */
+ bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11));
+#else
+ bfin_write_SIC_IWR1(IWR_DISABLE_ALL);
+#endif
# ifdef CONFIG_BF54x
- bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
+ bfin_write_SIC_IWR2(IWR_DISABLE_ALL);
# endif
#else
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+ bfin_write_SIC_IWR(IWR_DISABLE_ALL);
#endif
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 @@
*/
#include <linux/linkage.h>
-#include <asm/cplb.h>
#include <asm/blackfin.h>
.text
-#ifdef CONFIG_BFIN_ICACHE_LOCK
-
/* When you come here, it is assumed that
* R0 - Which way to be locked
*/
@@ -189,18 +186,38 @@ ENTRY(_cache_lock)
RTS;
ENDPROC(_cache_lock)
-#endif /* BFIN_ICACHE_LOCK */
-
-/* Return the ILOC bits of IMEM_CONTROL
+/* Invalidate the Entire Instruction cache by
+ * disabling IMC bit
*/
+ENTRY(_invalidate_entire_icache)
+ [--SP] = ( R7:5);
-ENTRY(_read_iloc)
- P1.H = HI(IMEM_CONTROL);
- P1.L = LO(IMEM_CONTROL);
- R1 = 0xF;
- R0 = [P1];
- R0 = R0 >> 3;
- R0 = R0 & R1;
+ P0.L = LO(IMEM_CONTROL);
+ P0.H = HI(IMEM_CONTROL);
+ R7 = [P0];
+
+ /* Clear the IMC bit , All valid bits in the instruction
+ * cache are set to the invalid state
+ */
+ BITCLR(R7,IMC_P);
+ CLI R6;
+ SSYNC; /* SSYNC required before invalidating cache. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ /* Configures the instruction cache agian */
+ R6 = (IMC | ENICPLB);
+ R7 = R7 | R6;
+
+ CLI R6;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+ ( R7:5) = [SP++];
RTS;
-ENDPROC(_read_iloc)
+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)
bfin_pm_standby_restore();
#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
- bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
- bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
+ bfin_write_SIC_IWR0(IWR_DISABLE_ALL);
+#if defined(CONFIG_BF52x)
+ /* BF52x system reset does not properly reset SIC_IWR1 which
+ * will screw up the bootrom as it relies on MDMA0/1 waking it
+ * up from IDLE instructions. See this report for more info:
+ * http://blackfin.uclinux.org/gf/tracker/4323
+ */
+ bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11));
+#else
+ bfin_write_SIC_IWR1(IWR_DISABLE_ALL);
+#endif
# ifdef CONFIG_BF54x
- bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
+ bfin_write_SIC_IWR2(IWR_DISABLE_ALL);
# endif
#else
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+ bfin_write_SIC_IWR(IWR_DISABLE_ALL);
#endif
local_irq_restore(flags);
@@ -229,28 +238,12 @@ int bfin_pm_suspend_mem_enter(void)
wakeup = bfin_read_VR_CTL() & ~FREQ;
wakeup |= SCKELOW;
- /* FIXME: merge this somehow with set_irq_wake */
-#ifdef CONFIG_PM_BFIN_WAKE_RTC
- wakeup |= WAKE;
-#endif
#ifdef CONFIG_PM_BFIN_WAKE_PH6
wakeup |= PHYWE;
#endif
-#ifdef CONFIG_PM_BFIN_WAKE_CAN
- wakeup |= CANWE;
-#endif
#ifdef CONFIG_PM_BFIN_WAKE_GP
wakeup |= GPWE;
#endif
-#ifdef CONFIG_PM_BFIN_WAKE_USB
- wakeup |= USBWE;
-#endif
-#ifdef CONFIG_PM_BFIN_WAKE_KEYPAD
- wakeup |= KPADWE;
-#endif
-#ifdef CONFIG_PM_BFIN_WAKE_ROTARY
- wakeup |= ROTWE;
-#endif
local_irq_save(flags);
@@ -268,7 +261,7 @@ int bfin_pm_suspend_mem_enter(void)
icache_disable();
bf53x_suspend_l1_mem(memptr);
- do_hibernate(wakeup); /* Goodbye */
+ do_hibernate(wakeup | vr_wakeup); /* Goodbye */
bf53x_resume_l1_mem(memptr);