diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2014-03-05 15:44:49 +0100 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2014-03-06 17:55:42 +0100 |
commit | b9815437624e6db85b4122544474073a6a1880dd (patch) | |
tree | 066f554e37e58bb3b58a4f4a9aaf72b16f87e208 | |
parent | 1e0213ae29e657b2814a3b1f277c14f35e893f8a (diff) |
colibri_vf: enable wake-up pins
Register wake-up pins on SO-DIMM 43/45 (PTB19/PTB20) to trigger
on falling edge. This allows to wake up the SoC from low-power
modes such das suspend-to-RAM or standby.
Also, on standby (when pheripherials are on) we allow to wake
using serial interrupt (UART0).
-rw-r--r-- | arch/arm/mach-mvf/board-colibri_vf.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-mvf/system.c | 73 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/iomux-mvf.h | 5 |
3 files changed, 58 insertions, 23 deletions
diff --git a/arch/arm/mach-mvf/board-colibri_vf.c b/arch/arm/mach-mvf/board-colibri_vf.c index c6a4eb1f055a..e9048676faad 100644 --- a/arch/arm/mach-mvf/board-colibri_vf.c +++ b/arch/arm/mach-mvf/board-colibri_vf.c @@ -184,6 +184,8 @@ static iomux_v3_cfg_t mvf600_pads[] = { MVF600_PAD30_PTB8_FTM1CH0, //PWM<B> MVF600_PAD31_PTB9_FTM1CH1, //PWM<D> multiplexed MVF600_PAD51_PTC6_VID6 + /* Wake-Up GPIO */ + MVF600_PAD41_PTB19__GPIO, #if 0 /* NAND */ MVF600_PAD71_PTD23_NF_IO7, @@ -209,7 +211,6 @@ static iomux_v3_cfg_t mvf600_pads[] = { //MVF600_PAD39_PTB17_GPIO, //MVF600_PAD40_PTB18_GPIO, /* IOMUXC_CCM_AUD_EXT_CLK_SELECT_INPUT 2 // Selecting Pad: PTB18 for Mode: ALT2. */ -//MVF600_PAD41_PTB19_GPIO, //MVF600_PAD43_PTB21_GPIO, /* CAN_INT */ //MVF600_PAD44_PTB22_GPIO, //MVF600_PAD63_PTD31_GPIO, diff --git a/arch/arm/mach-mvf/system.c b/arch/arm/mach-mvf/system.c index 989c75a02ed1..6eaefb0dbbb6 100644 --- a/arch/arm/mach-mvf/system.c +++ b/arch/arm/mach-mvf/system.c @@ -32,16 +32,24 @@ #include "regs-anadig.h" #include "regs-pm.h" -#define SW1_WAKEUP_PIN 38 -#define SW1_PORT1_PCR6_ADDR 0x4004a018 +/* PTB19, GPIO 41, SO-DIMM 45 */ +#define SW1_WAKEUP_GPIO 41 +#define SW1_WAKEUP_PIN 12 +#define SW1_PORT1_PCR9_ADDR MVF_IO_ADDRESS(0x4004a024) + +/* PTB20, GPIO 42, SO-DIMM 43 */ +#define SW2_WAKEUP_GPIO 42 +#define SW2_WAKEUP_PIN 13 +#define SW2_PORT1_PCR10_ADDR MVF_IO_ADDRESS(0x4004a028) static void __iomem *gpc_base = MVF_GPC_BASE; void gpc_set_wakeup(void) { __raw_writel(0xffffffff, gpc_base + GPC_IMR1_OFFSET); - __raw_writel(0xffffffff, gpc_base + GPC_IMR2_OFFSET); - /* unmask WKPU0 interrupt */ + /* unmask UART0 */ + __raw_writel(0xdfffffff, gpc_base + GPC_IMR2_OFFSET); + /* unmask WKPU12/13 interrupt */ __raw_writel(0xefffffff, gpc_base + GPC_IMR3_OFFSET); /* unmask GPIO4 interrupt */ __raw_writel(0xffff7fff, gpc_base + GPC_IMR4_OFFSET); @@ -51,13 +59,22 @@ void gpc_set_wakeup(void) void enable_wkpu(u32 source, u32 rise_fall) { - __raw_writel(1 << source, MVF_WKPU_BASE + WKPU_IRER_OFFSET); - __raw_writel(1 << source, MVF_WKPU_BASE + WKPU_WRER_OFFSET); - - if (rise_fall == RISING_EDGE_ENABLED) - __raw_writel(1 << source, MVF_WKPU_BASE + WKPU_WIREER_OFFSET); - else - __raw_writel(1 << source, MVF_WKPU_BASE + WKPU_WIFEER_OFFSET); + u32 tmp; + tmp = __raw_readl(MVF_WKPU_BASE + WKPU_IRER_OFFSET); + __raw_writel(tmp | 1 << source, MVF_WKPU_BASE + WKPU_IRER_OFFSET); + + tmp = __raw_readl(MVF_WKPU_BASE + WKPU_WRER_OFFSET); + __raw_writel(tmp | 1 << source, MVF_WKPU_BASE + WKPU_WRER_OFFSET); + + if (rise_fall == RISING_EDGE_ENABLED) { + tmp = __raw_readl(MVF_WKPU_BASE + WKPU_WIREER_OFFSET); + tmp |= 1 << source; + __raw_writel(tmp, MVF_WKPU_BASE + WKPU_WIREER_OFFSET); + } else { + tmp = __raw_readl(MVF_WKPU_BASE + WKPU_WIFEER_OFFSET); + tmp |= 1 << source; + __raw_writel(tmp, MVF_WKPU_BASE + WKPU_WIFEER_OFFSET); + } } static irqreturn_t wkpu_irq(int irq, void *dev_id) @@ -71,29 +88,41 @@ static irqreturn_t wkpu_irq(int irq, void *dev_id) return IRQ_NONE; } +static void mvf_configure_wakeup_pin(int gpio, int wkup_pin, + const volatile void __iomem *pinctl_addr) +{ + u32 tmp; + + /* config SW1 for waking up system */ + gpio_request_one(gpio, GPIOF_IN, "SW wakeup"); + gpio_set_value(gpio, 0); + + /* Disable IRQC interrupt/dma request in pin contorl register */ + tmp = __raw_readl(pinctl_addr); + tmp &= ~0x000f0000; + __raw_writel(tmp, pinctl_addr); + + /* enable WKPU interrupt for this wakeup pin */ + enable_wkpu(wkup_pin, FALLING_EDGE_ENABLED); +} + /* set cpu multiple modes before WFI instruction */ void mvf_cpu_lp_set(enum mvf_cpu_pwr_mode mode) { u32 ccm_ccsr, ccm_clpcr, ccm_ccr; - u32 tmp; int ret; if ((mode == LOW_POWER_STOP) || (mode == STOP_MODE)) { - /* config SW1 for waking up system */ - gpio_request_one(SW1_WAKEUP_PIN, GPIOF_IN, "SW1 wakeup"); - gpio_set_value(SW1_WAKEUP_PIN, 0); - /* PORT1_PCR6 IRQC interrupt/dma request disabled */ - tmp = __raw_readl(MVF_IO_ADDRESS(SW1_PORT1_PCR6_ADDR)); - tmp &= ~0x000f0000; - __raw_writel(tmp, MVF_IO_ADDRESS(SW1_PORT1_PCR6_ADDR)); - ret = request_irq(MVF_INT_WKPU0, wkpu_irq, IRQF_DISABLED, "wkpu irq", NULL); + if (ret) printk(KERN_ERR "Request wkpu IRQ failed\n"); - /* enable WKPU interrupt */ - enable_wkpu(11, FALLING_EDGE_ENABLED); + mvf_configure_wakeup_pin(SW1_WAKEUP_GPIO, SW1_WAKEUP_PIN, + SW1_PORT1_PCR9_ADDR); + mvf_configure_wakeup_pin(SW2_WAKEUP_GPIO, SW2_WAKEUP_PIN, + SW2_PORT1_PCR10_ADDR); } ccm_ccr = __raw_readl(MXC_CCM_CCR); diff --git a/arch/arm/plat-mxc/include/mach/iomux-mvf.h b/arch/arm/plat-mxc/include/mach/iomux-mvf.h index dc0c40b914d0..d68e5f1c944f 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mvf.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mvf.h @@ -105,6 +105,11 @@ typedef enum iomux_config { IOMUX_PAD(0x00a8, 0x00a8, 0, 0x0000, 0, \ MVF600_GPIO_GENERAL_CTRL | PAD_CTL_IBE_ENABLE) +/*GPIO Wake-Up*/ +#define MVF600_PAD41_PTB19__GPIO \ + IOMUX_PAD(0x00a4, 0x00a4, 0, 0x0000, 0, \ + MVF600_GPIO_GENERAL_CTRL | PAD_CTL_IBE_ENABLE) + /*I2C0*/ #define MVF600_PAD36_PTB14__I2C0_SCL \ IOMUX_PAD(0x0090, 0x0090, 2, 0x033C, 1, \ |