aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Aaberg <jonas.aberg@stericsson.com>2011-06-13 16:45:53 +0200
committersaid m bagheri <ebgheri@steludxu2848.(none)>2011-06-29 10:30:30 +0200
commitb56ccf8470273e5a069cc5e76d32f24efd5963d0 (patch)
treebfc288117e16714bcc1471d8374576b6f8161e61
parentb523d596ee171e65a5adc80b97dfb60de941d728 (diff)
ARM: ux500: prcmu: Add A9 watchdog interface
ST-Ericsson Linux next: Not tested, ask SSM for ER ST-Ericsson ID: 339924 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I6b1d9aa38b547673355f0277dd233ce964c88df1 Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/25028
-rw-r--r--arch/arm/mach-ux500/include/mach/prcmu-db8500.h31
-rw-r--r--arch/arm/mach-ux500/prcmu-db8500.c89
2 files changed, 120 insertions, 0 deletions
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-db8500.h b/arch/arm/mach-ux500/include/mach/prcmu-db8500.h
index 4ba3b15d8fa..659f9205d2e 100644
--- a/arch/arm/mach-ux500/include/mach/prcmu-db8500.h
+++ b/arch/arm/mach-ux500/include/mach/prcmu-db8500.h
@@ -186,6 +186,12 @@ int prcmu_stop_temp_sense(void);
void prcmu_enable_spi2(void);
void prcmu_disable_spi2(void);
+int prcmu_config_a9wdog(u8 num, bool sleep_auto_off);
+int prcmu_enable_a9wdog(u8 id);
+int prcmu_disable_a9wdog(u8 id);
+int prcmu_kick_a9wdog(u8 id);
+int prcmu_load_a9wdog(u8 id, u32 val);
+
void db8500_prcmu_system_reset(u16 reset_code);
int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
bool keep_ap_pll);
@@ -329,6 +335,31 @@ static inline void db8500_prcmu_config_abb_event_readout(u32 abb_events) {}
static inline void db8500_prcmu_get_abb_event_buffer(void __iomem **buf) {}
+static inline int prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
+{
+ return 0;
+}
+
+static inline int prcmu_enable_a9wdog(u8 id)
+{
+ return 0;
+}
+
+static inline int prcmu_disable_a9wdog(u8 id)
+{
+ return 0;
+}
+
+static inline int prcmu_kick_a9wdog(u8 id)
+{
+ return 0;
+}
+
+static inline int prcmu_load_a9wdog(u8 id, u32 val)
+{
+ return 0;
+}
+
#endif /* CONFIG_UX500_SOC_DB8500 */
#endif /* __MACH_PRCMU_DB8500_H */
diff --git a/arch/arm/mach-ux500/prcmu-db8500.c b/arch/arm/mach-ux500/prcmu-db8500.c
index 58f5ec330f7..8ba0ac315f2 100644
--- a/arch/arm/mach-ux500/prcmu-db8500.c
+++ b/arch/arm/mach-ux500/prcmu-db8500.c
@@ -193,6 +193,11 @@
#define MB4H_HOTDOG 0x12
#define MB4H_HOTMON 0x13
#define MB4H_HOT_PERIOD 0x14
+#define MB4H_A9WDOG_CONF 0x16
+#define MB4H_A9WDOG_EN 0x17
+#define MB4H_A9WDOG_DIS 0x18
+#define MB4H_A9WDOG_LOAD 0x19
+#define MB4H_A9WDOG_KICK 0x20
/* Mailbox 4 Requests */
#define PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE (PRCM_REQ_MB4 + 0x0)
@@ -205,6 +210,13 @@
#define PRCM_REQ_MB4_HOT_PERIOD (PRCM_REQ_MB4 + 0x0)
#define HOTMON_CONFIG_LOW BIT(0)
#define HOTMON_CONFIG_HIGH BIT(1)
+#define PRCM_REQ_MB4_A9WDOG_0 (PRCM_REQ_MB4 + 0x0)
+#define PRCM_REQ_MB4_A9WDOG_1 (PRCM_REQ_MB4 + 0x1)
+#define PRCM_REQ_MB4_A9WDOG_2 (PRCM_REQ_MB4 + 0x2)
+#define PRCM_REQ_MB4_A9WDOG_3 (PRCM_REQ_MB4 + 0x3)
+#define A9WDOG_AUTO_OFF_EN BIT(7)
+#define A9WDOG_AUTO_OFF_DIS 0
+#define A9WDOG_ID_MASK 0xf
/* Mailbox 5 Requests */
#define PRCM_REQ_MB5_I2C_SLAVE_OP (PRCM_REQ_MB5 + 0x0)
@@ -1546,6 +1558,78 @@ int prcmu_stop_temp_sense(void)
return config_hot_period(0xFFFF);
}
+static int prcmu_a9wdog(u8 cmd, u8 d0, u8 d1, u8 d2, u8 d3)
+{
+
+ mutex_lock(&mb4_transfer.lock);
+
+ while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))
+ cpu_relax();
+
+ writeb(d0, (tcdm_base + PRCM_REQ_MB4_A9WDOG_0));
+ writeb(d1, (tcdm_base + PRCM_REQ_MB4_A9WDOG_1));
+ writeb(d2, (tcdm_base + PRCM_REQ_MB4_A9WDOG_2));
+ writeb(d3, (tcdm_base + PRCM_REQ_MB4_A9WDOG_3));
+
+ writeb(cmd, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));
+
+ writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+ wait_for_completion(&mb4_transfer.work);
+
+ mutex_unlock(&mb4_transfer.lock);
+
+ return 0;
+
+}
+
+int prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
+{
+ BUG_ON(num == 0 || num > 0xf);
+ return prcmu_a9wdog(MB4H_A9WDOG_CONF, num, 0, 0,
+ sleep_auto_off ? A9WDOG_AUTO_OFF_EN :
+ A9WDOG_AUTO_OFF_DIS);
+}
+
+int prcmu_enable_a9wdog(u8 id)
+{
+ return prcmu_a9wdog(MB4H_A9WDOG_EN, id, 0, 0, 0);
+}
+
+int prcmu_disable_a9wdog(u8 id)
+{
+ return prcmu_a9wdog(MB4H_A9WDOG_DIS, id, 0, 0, 0);
+}
+
+int prcmu_kick_a9wdog(u8 id)
+{
+ return prcmu_a9wdog(MB4H_A9WDOG_KICK, id, 0, 0, 0);
+}
+
+/*
+ * timeout is 28 bit, in ms.
+ */
+#define MAX_WATCHDOG_TIMEOUT 131000
+int prcmu_load_a9wdog(u8 id, u32 timeout)
+{
+ if (timeout > MAX_WATCHDOG_TIMEOUT)
+ /*
+ * Due to calculation bug in prcmu fw, timeouts
+ * can't be bigger than 131 seconds.
+ */
+ return -EINVAL;
+
+ return prcmu_a9wdog(MB4H_A9WDOG_LOAD,
+ (id & A9WDOG_ID_MASK) |
+ /*
+ * Put the lowest 28 bits of timeout at
+ * offset 4. Four first bits are used for id.
+ */
+ (u8)((timeout << 4) & 0xf0),
+ (u8)((timeout >> 4) & 0xff),
+ (u8)((timeout >> 12) & 0xff),
+ (u8)((timeout >> 20) & 0xff));
+}
+
/**
* prcmu_set_clock_divider() - Configure the clock divider.
* @clock: The clock for which the request is made.
@@ -1898,6 +1982,11 @@ static bool read_mailbox_4(void)
case MB4H_HOTDOG:
case MB4H_HOTMON:
case MB4H_HOT_PERIOD:
+ case MB4H_A9WDOG_CONF:
+ case MB4H_A9WDOG_EN:
+ case MB4H_A9WDOG_DIS:
+ case MB4H_A9WDOG_LOAD:
+ case MB4H_A9WDOG_KICK:
break;
default:
print_unknown_header_warning(4, header);