summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2014-03-05 15:44:49 +0100
committerStefan Agner <stefan.agner@toradex.com>2014-03-06 17:55:42 +0100
commitb9815437624e6db85b4122544474073a6a1880dd (patch)
tree066f554e37e58bb3b58a4f4a9aaf72b16f87e208
parent1e0213ae29e657b2814a3b1f277c14f35e893f8a (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.c3
-rw-r--r--arch/arm/mach-mvf/system.c73
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mvf.h5
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, \