Diff
Modified: trunk/arch/blackfin/Kconfig (4163 => 4164)
--- trunk/arch/blackfin/Kconfig 2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/arch/blackfin/Kconfig 2008-01-29 13:28:33 UTC (rev 4164)
@@ -538,7 +538,7 @@
default y
help
If enabled, the entire ASM lowlevel exception and interrupt entry code
- (STORE/RESTORE CONTEXT) is linked into L1 instruction memory.
+ (STORE/RESTORE CONTEXT) is linked into L1 instruction memory.
(less latency)
config DO_IRQ_L1
@@ -895,30 +895,39 @@
source "kernel/power/Kconfig"
choice
- prompt "Select PM Wakeup Event Source"
- default PM_WAKEUP_GPIO_BY_SIC_IWR
+ prompt "Default Power Saving Mode"
depends on PM
+ default PM_BFIN_SLEEP_DEEPER
+config PM_BFIN_SLEEP_DEEPER
+ bool "Sleep Deeper"
help
- If you have a GPIO already configured as input with the corresponding PORTx_MASK
- bit set - "Specify Wakeup Event by SIC_IWR value"
+ Sleep "Deeper" Mode (High Power Savings) - This mode reduces dynamic
+ power dissipation by disabling the clock to the processor core (CCLK).
+ Furthermore, Standby sets the internal power supply voltage (VDDINT)
+ to 0.85 V to provide the greatest power savings, while preserving the
+ processor state.
+ The PLL and system clock (SCLK) continue to operate at a very low
+ frequency of about 3.3 MHz. To preserve data integrity in the SDRAM,
+ the SDRAM is put into Self Refresh Mode. Typically an external event
+ such as GPIO interrupt or RTC activity wakes up the processor.
+ Various Peripherals such as UART, SPORT, PPI may not function as
+ normal during Sleep Deeper, due to the reduced SCLK frequency.
+ When in the sleep mode, system DMA access to L1 memory is not supported.
-config PM_WAKEUP_GPIO_BY_SIC_IWR
- bool "Specify Wakeup Event by SIC_IWR value"
+config PM_BFIN_SLEEP
+ bool "Sleep"
+ help
+ Sleep Mode (High Power Savings) - The sleep mode reduces power
+ dissipation by disabling the clock to the processor core (CCLK).
+ The PLL and system clock (SCLK), however, continue to operate in
+ this mode. Typically an external event or RTC activity will wake
+ up the processor. When in the sleep mode,
+ system DMA access to L1 memory is not supported.
+endchoice
+
config PM_WAKEUP_BY_GPIO
bool "Cause Wakeup Event by GPIO"
-config PM_WAKEUP_GPIO_API
- bool "Configure Wakeup Event by PM GPIO API"
-endchoice
-
-config PM_WAKEUP_SIC_IWR
- hex "Wakeup Events (SIC_IWR)"
- depends on PM_WAKEUP_GPIO_BY_SIC_IWR
- default 0x8 if (BF537 || BF536 || BF534)
- default 0x80 if (BF533 || BF532 || BF531)
- default 0x80 if (BF54x)
- default 0x80 if (BF52x)
-
config PM_WAKEUP_GPIO_NUMBER
int "Wakeup GPIO number"
range 0 47
Modified: trunk/arch/blackfin/kernel/bfin_gpio.c (4163 => 4164)
--- trunk/arch/blackfin/kernel/bfin_gpio.c 2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/arch/blackfin/kernel/bfin_gpio.c 2008-01-29 13:28:33 UTC (rev 4164)
@@ -698,7 +698,6 @@
u32 gpio_pm_setup(void)
{
- u32 sic_iwr = 0;
u16 bank, mask, i, gpio;
for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
@@ -723,7 +722,8 @@
gpio = i;
while (mask) {
- if (mask & 1) {
+ if ((mask & 1) && (wakeup_flags_map[gpio] !=
+ PM_WAKE_IGNORE)) {
reserved_gpio_map[gpio_bank(gpio)] |=
gpio_bit(gpio);
bfin_gpio_wakeup_type(gpio,
@@ -734,18 +734,14 @@
mask >>= 1;
}
- sic_iwr |= 1 <<
- (sic_iwr_irqs[bank] - (IRQ_CORETMR + 1));
+ bfin_internal_set_wake(sic_iwr_irqs[bank], 1);
gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)];
}
}
AWA_DUMMY_READ(maskb_set);
- if (sic_iwr)
- return sic_iwr;
- else
- return IWR_ENABLE_ALL;
+ return 0;
}
void gpio_pm_restore(void)
@@ -768,7 +764,7 @@
reserved_gpio_map[bank] =
gpio_bank_saved[bank].reserved;
-
+ bfin_internal_set_wake(sic_iwr_irqs[bank], 0);
}
gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb;
Modified: trunk/arch/blackfin/mach-common/dpmc.S (4163 => 4164)
--- trunk/arch/blackfin/mach-common/dpmc.S 2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/arch/blackfin/mach-common/dpmc.S 2008-01-29 13:28:33 UTC (rev 4164)
@@ -191,6 +191,9 @@
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);
@@ -237,6 +240,10 @@
CLI R4;
+ R0 = IWR_ENABLE(0);
+ R1 = IWR_DISABLE_ALL;
+ R2 = IWR_DISABLE_ALL;
+
call _set_sic_iwr;
call _set_dram_srfs;
@@ -261,6 +268,9 @@
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);
@@ -286,7 +296,13 @@
CLI R4;
P3 = R0;
+ P4 = R1;
+ P5 = R2;
+
R0 = IWR_ENABLE(0);
+ R1 = IWR_DISABLE_ALL;
+ R2 = IWR_DISABLE_ALL;
+
call _set_sic_iwr;
call _set_dram_srfs; /* Set SDRAM Self Refresh */
@@ -327,6 +343,8 @@
call _test_pll_locked;
R0 = P3;
+ R1 = P4;
+ R3 = P5;
call _set_sic_iwr; /* Set Awake from IDLE */
P0.H = hi(PLL_CTL);
@@ -340,6 +358,9 @@
call _test_pll_locked;
R0 = IWR_ENABLE(0);
+ R1 = IWR_DISABLE_ALL;
+ R2 = IWR_DISABLE_ALL;
+
call _set_sic_iwr; /* Set Awake from IDLE PLL */
P0.H = hi(VR_CTL);
@@ -417,14 +438,23 @@
RTS;
ENTRY(_set_sic_iwr)
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
P0.H = hi(SIC_IWR0);
P0.L = lo(SIC_IWR0);
+ P1.H = hi(SIC_IWR1);
+ P1.L = lo(SIC_IWR1);
+ [P1] = R1;
+#if defined(CONFIG_BF54x)
+ P1.H = hi(SIC_IWR2);
+ P1.L = lo(SIC_IWR2);
+ [P1] = R2;
+#endif
#else
P0.H = hi(SIC_IWR);
P0.L = lo(SIC_IWR);
#endif
[P0] = R0;
+
SSYNC;
RTS;
Modified: trunk/arch/blackfin/mach-common/ints-priority.c (4163 => 4164)
--- trunk/arch/blackfin/mach-common/ints-priority.c 2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/arch/blackfin/mach-common/ints-priority.c 2008-01-29 13:28:33 UTC (rev 4164)
@@ -69,6 +69,10 @@
/* The number of spurious interrupts */
atomic_t num_spurious;
+#ifdef CONFIG_PM
+unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */
+#endif
+
struct ivgx {
/* irq number for request_irq, available in mach-bf533/irq.h */
unsigned int irqno;
@@ -178,6 +182,27 @@
SSYNC();
}
+#ifdef CONFIG_PM
+int bfin_internal_set_wake(unsigned int irq, unsigned int state)
+{
+ unsigned bank, bit;
+ unsigned long flags;
+ bank = (irq - (IRQ_CORETMR + 1)) / 32;
+ bit = (irq - (IRQ_CORETMR + 1)) % 32;
+
+ local_irq_save(flags);
+
+ if (state)
+ bfin_sic_iwr[bank] |= (1 << bit);
+ else
+ bfin_sic_iwr[bank] &= ~(1 << bit);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+#endif
+
static struct irq_chip bfin_core_irqchip = {
.ack = ack_noop,
.mask = bfin_core_mask_irq,
@@ -188,6 +213,9 @@
.ack = ack_noop,
.mask = bfin_internal_mask_irq,
.unmask = bfin_internal_unmask_irq,
+#ifdef CONFIG_PM
+ .set_wake = bfin_internal_set_wake,
+#endif
};
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
@@ -434,6 +462,20 @@
return 0;
}
+#ifdef CONFIG_PM
+int bfin_gpio_set_wake(unsigned int irq, unsigned int state)
+{
+ unsigned gpio = irq_to_gpio(irq);
+
+ if (state)
+ gpio_pm_wakeup_request(gpio, PM_WAKE_IGNORE);
+ else
+ gpio_pm_wakeup_free(gpio);
+
+ return 0;
+}
+#endif
+
static struct irq_chip bfin_gpio_irqchip = {
.ack = bfin_gpio_ack_irq,
.mask = bfin_gpio_mask_irq,
@@ -441,7 +483,10 @@
.unmask = bfin_gpio_unmask_irq,
.set_type = bfin_gpio_irq_type,
.startup = bfin_gpio_irq_startup,
- .shutdown = bfin_gpio_irq_shutdown
+ .shutdown = bfin_gpio_irq_shutdown,
+#ifdef CONFIG_PM
+ .set_wake = bfin_gpio_set_wake,
+#endif
};
static void bfin_demux_gpio_irq(unsigned int inta_irq,
@@ -487,7 +532,7 @@
}
if (search) {
- for (i = 0; i < MAX_BLACKFIN_GPIOS; i += 16) {
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
irq += i;
mask = get_gpiop_data(i) &
Modified: trunk/arch/blackfin/mach-common/pm.c (4163 => 4164)
--- trunk/arch/blackfin/mach-common/pm.c 2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/arch/blackfin/mach-common/pm.c 2008-01-29 13:28:33 UTC (rev 4164)
@@ -67,42 +67,30 @@
gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE);
#endif
-#if defined(CONFIG_PM_WAKEUP_BY_GPIO) || defined(CONFIG_PM_WAKEUP_GPIO_API)
- {
- u32 flags;
+ u32 flags;
- local_irq_save(flags);
+ local_irq_save(flags);
+ gpio_pm_setup();
- sleep_deeper(gpio_pm_setup()); /*Goto Sleep*/
-
- gpio_pm_restore();
-
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
- bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
- bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
-# ifdef CONFIG_BF54x
- bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
-# endif
+#ifdef CONFIG_PM_BFIN_SLEEP_DEEPER
+ sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]);
#else
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+ sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]);
#endif
- local_irq_restore(flags);
- }
-#endif
+ gpio_pm_restore();
-#if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR)
- sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR);
-# if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
-# ifdef CONFIG_BF54x
+# ifdef CONFIG_BF54x
bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
-# endif
-# else
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
# endif
-#endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */
+#else
+ bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+#endif
+
+ local_irq_restore(flags);
}
Modified: trunk/drivers/char/bfin_dpmc.c (4163 => 4164)
--- trunk/drivers/char/bfin_dpmc.c 2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/drivers/char/bfin_dpmc.c 2008-01-29 13:28:33 UTC (rev 4164)
@@ -182,6 +182,19 @@
return sdrrcval;
}
+void dpmc_iwr_enable_all(void)
+{
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
+ bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
+ bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
+# ifdef CONFIG_BF54x
+ bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
+# endif
+#else
+ dpmc_iwr_enable_all();
+#endif
+}
+
int get_closest_ssel(int a, int b, int c, unsigned long vco, unsigned long clock)
{
int t1, t2, t3;
@@ -261,7 +274,7 @@
change_baud(CONSOLE_BAUD_RATE);
#endif
change_baud(CONSOLE_BAUD_RATE);
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+ dpmc_iwr_enable_all();
SSYNC();
break;
@@ -269,18 +282,18 @@
case IOCTL_ACTIVE_MODE:
active_mode();
change_baud(CONSOLE_BAUD_RATE);
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+ dpmc_iwr_enable_all();
SSYNC();
break;
case IOCTL_SLEEP_MODE:
- sleep_mode(IWR_ENABLE(IRQ_RTC - IVG7));
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+ sleep_mode(IWR_ENABLE(IRQ_RTC - IVG7), IWR_DISABLE_ALL, IWR_DISABLE_ALL);
+ dpmc_iwr_enable_all();
SSYNC();
break;
case IOCTL_DEEP_SLEEP_MODE:
- deep_sleep(IWR_ENABLE(IRQ_RTC - IVG7));
+ deep_sleep(IWR_ENABLE(IRQ_RTC - IVG7), IWR_DISABLE_ALL, IWR_DISABLE_ALL);
/* Active Mode SCLK = CCLK is hazardous condition Anomlay 05000273 */
/* Changed deep_sleep to return to Full On Mode */
@@ -288,19 +301,19 @@
/* Needed since it comes back to active mode */
change_baud(CONSOLE_BAUD_RATE);
#endif
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+ dpmc_iwr_enable_all();
SSYNC();
break;
case IOCTL_SLEEP_DEEPER_MODE:
- sleep_deeper(IWR_ENABLE(IRQ_RTC - IVG7));
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+ sleep_deeper(IWR_ENABLE(IRQ_RTC - IVG7), IWR_DISABLE_ALL, IWR_DISABLE_ALL);
+ dpmc_iwr_enable_all();
SSYNC();
break;
case IOCTL_HIBERNATE_MODE:
- hibernate_mode(IWR_ENABLE(IRQ_RTC - IVG7));
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+ hibernate_mode(IWR_ENABLE(IRQ_RTC - IVG7), IWR_DISABLE_ALL, IWR_DISABLE_ALL);
+ dpmc_iwr_enable_all();
SSYNC();
break;
@@ -351,7 +364,7 @@
sclk_mhz = change_sclk((vco_mhz/(DEF_SSEL * MHZ)));
change_baud(CONSOLE_BAUD_RATE);
}
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+ dpmc_iwr_enable_all();
SSYNC();
copy_to_user((unsigned long *)arg, &vco_mhz, sizeof(unsigned long));
break;
@@ -833,8 +846,8 @@
}
if (val) {
- sleep_deeper(val);
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+ sleep_deeper(val, 0, 0);
+ dpmc_iwr_enable_all();
}
return count;
Modified: trunk/drivers/char/bfin_dpmc.h (4163 => 4164)
--- trunk/drivers/char/bfin_dpmc.h 2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/drivers/char/bfin_dpmc.h 2008-01-29 13:28:33 UTC (rev 4164)
@@ -40,9 +40,6 @@
void fullon_mode(void);
void active_mode(void);
-void sleep_mode(u32 sic_iwr);
-void deep_sleep(u32 sic_iwr);
-void hibernate_mode(u32 sic_iwr);
void program_wdog_timer(unsigned long);
void unmask_wdog_wakeup_evt(void);
void clear_wdog_wakeup_evt(void);
Modified: trunk/include/asm-blackfin/bfin-global.h (4163 => 4164)
--- trunk/include/asm-blackfin/bfin-global.h 2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/include/asm-blackfin/bfin-global.h 2008-01-29 13:28:33 UTC (rev 4164)
@@ -70,6 +70,7 @@
extern void evt14_softirq(void);
extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
extern void bfin_gpio_interrupt_setup(int irq, int irq_pfx, int type);
+extern int bfin_internal_set_wake(unsigned int irq, unsigned int state);
extern asmlinkage void finish_atomic_sections (struct pt_regs *regs);
extern char fixed_code_start;
@@ -121,6 +122,7 @@
extern unsigned long table_start, table_end;
+extern unsigned long bfin_sic_iwr[];
extern u16 _bfin_swrst; /* shadow for Software Reset Register (SWRST) */
extern struct file_operations dpmc_fops;
extern char _start;
Modified: trunk/include/asm-blackfin/dpmc.h (4163 => 4164)
--- trunk/include/asm-blackfin/dpmc.h 2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/include/asm-blackfin/dpmc.h 2008-01-29 13:28:33 UTC (rev 4164)
@@ -53,10 +53,10 @@
void change_baud(int baud);
void fullon_mode(void);
void active_mode(void);
-void sleep_mode(u32 sic_iwr);
-void deep_sleep(u32 sic_iwr);
-void hibernate_mode(u32 sic_iwr);
-void sleep_deeper(u32 sic_iwr);
+void sleep_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
+void deep_sleep(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
+void hibernate_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
+void sleep_deeper(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
void program_wdog_timer(unsigned long);
void unmask_wdog_wakeup_evt(void);
void clear_wdog_wakeup_evt(void);
Modified: trunk/include/asm-blackfin/gpio.h (4163 => 4164)
--- trunk/include/asm-blackfin/gpio.h 2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/include/asm-blackfin/gpio.h 2008-01-29 13:28:33 UTC (rev 4164)
@@ -381,6 +381,7 @@
#define PM_WAKE_HIGH 0x4
#define PM_WAKE_LOW 0x8
#define PM_WAKE_BOTH_EDGES (PM_WAKE_RISING | PM_WAKE_FALLING)
+#define PM_WAKE_IGNORE 0xF0
int gpio_pm_wakeup_request(unsigned gpio, unsigned char type);
void gpio_pm_wakeup_free(unsigned gpio);