From 3345d18d5baad05807ecac36bc4125dbc74d288f Mon Sep 17 00:00:00 2001 From: "Boschung, Rainer" Date: Tue, 3 Jun 2014 09:05:12 +0200 Subject: mpc85xx: fix interrupt init to not affect watchdog TCR watchdog bit are overwritten when dec interrupt is enabled. This has been fixed with this patch. Signed-off-by: Rainer Boschung Reviewed-by: York Sun diff --git a/arch/powerpc/cpu/mpc85xx/interrupts.c b/arch/powerpc/cpu/mpc85xx/interrupts.c index a36a4af..daf46a9 100644 --- a/arch/powerpc/cpu/mpc85xx/interrupts.c +++ b/arch/powerpc/cpu/mpc85xx/interrupts.c @@ -42,7 +42,7 @@ int interrupt_init_cpu(unsigned int *decrementer_count) *decrementer_count = get_tbclk() / CONFIG_SYS_HZ; /* PIE is same as DIE, dec interrupt enable */ - mtspr(SPRN_TCR, TCR_PIE); + mtspr(SPRN_TCR, mfspr(SPRN_TCR) | TCR_PIE); #ifdef CONFIG_INTERRUPTS pic->iivpr1 = 0x810001; /* 50220 enable ecm interrupts */ -- cgit v0.10.2 From 60b295672d61fe79e6af3d9e4f3e8bd23bf3b4ad Mon Sep 17 00:00:00 2001 From: "Boschung, Rainer" Date: Tue, 3 Jun 2014 09:05:13 +0200 Subject: powerpc: macros for e500mc timer regs added For e500mc cores the watchdog timer period has to be set by means of a 6bit value, that defines the bit of the timebase counter used to signal a watchdog timer exception on its 0 to 1 transition. The macro used to set the watchdog period TCR_WP, was redefined for e500mc to support 6 WP setting. The parameter (x) given to the macro specifies the prescaling factor of the time base clock (fTB): watchdog_period = 1/fTB * 2^x Signed-off-by: Rainer Boschung Reviewed-by: York Sun diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 2445acd..1b98e0f 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -378,11 +378,16 @@ #else #define SPRN_TCR 0x154 /* Book E Timer Control Register */ #endif /* CONFIG_BOOKE */ +#ifdef CONFIG_E500MC +#define TCR_WP(x) (((64-x)&0x3)<<30)| \ + (((64-x)&0x3c)<<15) /* WDT Period 2^x clocks*/ +#else #define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */ #define WP_2_17 0 /* 2^17 clocks */ #define WP_2_21 1 /* 2^21 clocks */ #define WP_2_25 2 /* 2^25 clocks */ #define WP_2_29 3 /* 2^29 clocks */ +#endif /* CONFIG_E500 */ #define TCR_WRC(x) (((x)&0x3)<<28) /* WDT Reset Control */ #define WRC_NONE 0 /* No reset will occur */ #define WRC_CORE 1 /* Core reset will occur */ -- cgit v0.10.2 From 0f8062b25b31988bf62f166aa5b988add8454e42 Mon Sep 17 00:00:00 2001 From: "Boschung, Rainer" Date: Tue, 3 Jun 2014 09:05:14 +0200 Subject: mpc85xx: watchdog initialisation added Function to inititialize the cpu watchdog added. Signed-off-by: Rainer Boschung [York Sun: Add prototype in watchdog.h] Reviewed-by: York Sun diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 684d400..6274f92 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -310,6 +310,14 @@ __weak unsigned long get_tbclk (void) #if defined(CONFIG_WATCHDOG) +#define WATCHDOG_MASK (TCR_WP(63) | TCR_WRC(3) | TCR_WIE) +void +init_85xx_watchdog(void) +{ + mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WATCHDOG_MASK) | + TCR_WP(CONFIG_WATCHDOG_PRESC) | TCR_WRC(CONFIG_WATCHDOG_RC)); +} + void reset_85xx_watchdog(void) { diff --git a/include/watchdog.h b/include/watchdog.h index aacacb9..bd0a8d6 100644 --- a/include/watchdog.h +++ b/include/watchdog.h @@ -95,4 +95,8 @@ int init_func_watchdog_reset(void); #if defined(CONFIG_HW_WATCHDOG) && !defined(__ASSEMBLY__) void hw_watchdog_init(void); #endif + +#if defined(CONFIG_MPC85xx) && !defined(__ASSEMBLY__) + void init_85xx_watchdog(void); +#endif #endif /* _WATCHDOG_H_ */ -- cgit v0.10.2 From 919e05520fbf5c32d3a5d19756449dfd4706cd94 Mon Sep 17 00:00:00 2001 From: "Boschung, Rainer" Date: Tue, 3 Jun 2014 09:05:15 +0200 Subject: powerpc: mpc85xx watchdog init added to init_func When CONFIG_WATCHDOG is defined the board initialization just performs a WATCHDOG_RESET, an initialization of the watchdog is not done. This has been modified fot the MPC85xx, the board initialization calls its watchdog initialitzation allowing for full watchdog configuration very early in the boot phase. Signed-off-by: Rainer Boschung Reviewed-by: York Sun diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index 50eb820..0296205 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -226,6 +226,9 @@ static int init_func_spi(void) #if defined(CONFIG_WATCHDOG) int init_func_watchdog_init(void) { +#if defined(CONFIG_MPC85xx) + init_85xx_watchdog(); +#endif puts(" Watchdog enabled\n"); WATCHDOG_RESET(); return 0; -- cgit v0.10.2 From 88ac6ffabbe741b67ea94e33894fb1fdca57e776 Mon Sep 17 00:00:00 2001 From: "Boschung, Rainer" Date: Tue, 3 Jun 2014 09:05:16 +0200 Subject: kmp204x: CPU watchdog enabled The booting of the board is now protected by the CPU watchdog. A failure during the boot phase will end up in board reset. Signed-off-by: Rainer Boschung Reviewed-by: York Sun diff --git a/include/configs/km/kmp204x-common.h b/include/configs/km/kmp204x-common.h index efd9635..a0f9d29 100644 --- a/include/configs/km/kmp204x-common.h +++ b/include/configs/km/kmp204x-common.h @@ -377,6 +377,14 @@ int get_scl(void); #define CONFIG_SYS_LOADS_BAUD_CHANGE /* allow baudrate change */ /* + * Hardware Watchdog + */ +#define CONFIG_WATCHDOG /* enable CPU watchdog */ +#define CONFIG_WATCHDOG_PRESC 34 /* wdog prescaler 2^(64-34) (~10min) */ +#define CONFIG_WATCHDOG_RC WRC_CHIP /* reset chip on watchdog event */ + + +/* * additionnal command line configuration. */ #define CONFIG_CMD_PCI -- cgit v0.10.2 From 807d93d6de5f54cfdcc98bb6c392b2b1f4237dc8 Mon Sep 17 00:00:00 2001 From: "Boschung, Rainer" Date: Tue, 3 Jun 2014 09:05:17 +0200 Subject: kmp204x/qrio: prepare support for the CPU watchdog reset reason To achieve this, the qrio_cpuwd_flag() function that sets the CPU watchdog flag in the REASON1 reg is added. Signed-off-by: Rainer Boschung Signed-off-by: Valentin Longchamp Reviewed-by: York Sun diff --git a/board/keymile/kmp204x/kmp204x.h b/board/keymile/kmp204x/kmp204x.h index afede99..64c0afb 100644 --- a/board/keymile/kmp204x/kmp204x.h +++ b/board/keymile/kmp204x/kmp204x.h @@ -24,5 +24,7 @@ void qrio_wdmask(u8 bit, bool wden); void qrio_prstcfg(u8 bit, u8 mode); void qrio_set_leds(void); void qrio_enable_app_buffer(void); +void qrio_cpuwd_flag(bool flag); +int qrio_reset_reason(void); void pci_of_setup(void *blob, bd_t *bd); diff --git a/board/keymile/kmp204x/qrio.c b/board/keymile/kmp204x/qrio.c index b6ba93a..92e8022 100644 --- a/board/keymile/kmp204x/qrio.c +++ b/board/keymile/kmp204x/qrio.c @@ -173,3 +173,18 @@ void qrio_enable_app_buffer(void) ctrll |= (CTRLL_WRB_BUFENA); out_8(qrio_base + CTRLL_OFF, ctrll); } + +#define REASON1_OFF 0x12 +#define REASON1_CPUWD 0x01 + +void qrio_cpuwd_flag(bool flag) +{ + u8 reason1; + void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE; + reason1 = in_8(qrio_base + REASON1_OFF); + if (flag) + reason1 |= REASON1_CPUWD; + else + reason1 &= ~REASON1_CPUWD; + out_8(qrio_base + REASON1_OFF, reason1); +} -- cgit v0.10.2 From a09f470d49c4a6355f16fee6455d964211021e3d Mon Sep 17 00:00:00 2001 From: "Boschung, Rainer" Date: Tue, 3 Jun 2014 09:05:18 +0200 Subject: kmp204x: set CPU watchdog reset reason flag Check the core timer status register (TSR) for watchdog reset, and and set the QRIO's reset reason flag REASON1[0] accordingly. This allows the appliction SW to identify the cpu watchdog as a reset reason, by setting the REASON1[0] flag in the QRIO. Signed-off-by: Rainer Boschung Signed-off-by: Valentin Longchamp Reviewed-by: York Sun diff --git a/board/keymile/kmp204x/kmp204x.c b/board/keymile/kmp204x/kmp204x.c index 6bc8eb8..225262e 100644 --- a/board/keymile/kmp204x/kmp204x.c +++ b/board/keymile/kmp204x/kmp204x.c @@ -80,14 +80,26 @@ int get_scl(void) #define ZL30158_RST 8 #define BFTIC4_RST 0 +#define RSTRQSR1_WDT_RR 0x00200000 +#define RSTRQSR1_SW_RR 0x00100000 int board_early_init_f(void) { ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + bool cpuwd_flag = false; /* board only uses the DDR_MCK0, so disable the DDR_MCK1/2/3 */ setbits_be32(&gur->ddrclkdr, 0x001f000f); + /* set reset reason according CPU register */ + if ((gur->rstrqsr1 & (RSTRQSR1_WDT_RR | RSTRQSR1_SW_RR)) == + RSTRQSR1_WDT_RR) + cpuwd_flag = true; + + qrio_cpuwd_flag(cpuwd_flag); + /* clear CPU bits by writing 1 */ + setbits_be32(&gur->rstrqsr1, RSTRQSR1_WDT_RR | RSTRQSR1_SW_RR); + /* set the BFTIC's prstcfg to reset at power-up and unit reset only */ qrio_prstcfg(BFTIC4_RST, PRSTCFG_POWUP_UNIT_RST); /* and enable WD on it */ -- cgit v0.10.2 From 6caa185abd8bc42362c576a571792d5c63fa349d Mon Sep 17 00:00:00 2001 From: "Boschung, Rainer" Date: Tue, 3 Jun 2014 09:05:19 +0200 Subject: kmp204x/qrio: support for setting the CPU reset request mode To acheive this, the qrio_uprstreq() function that sets the UPRSTREQN flag in the qrio RESCNF reg is added. Signed-off-by: Rainer Boschung Signed-off-by: Valentin Longchamp Reviewed-by: York Sun diff --git a/board/keymile/kmp204x/kmp204x.h b/board/keymile/kmp204x/kmp204x.h index 64c0afb..e90e8ab 100644 --- a/board/keymile/kmp204x/kmp204x.h +++ b/board/keymile/kmp204x/kmp204x.h @@ -27,4 +27,9 @@ void qrio_enable_app_buffer(void); void qrio_cpuwd_flag(bool flag); int qrio_reset_reason(void); +#define UPREQ_UNIT_RST 0x0 +#define UPREQ_CORE_RST 0x1 + +void qrio_uprstreq(u8 mode); + void pci_of_setup(void *blob, bd_t *bd); diff --git a/board/keymile/kmp204x/qrio.c b/board/keymile/kmp204x/qrio.c index 92e8022..edf3bf1 100644 --- a/board/keymile/kmp204x/qrio.c +++ b/board/keymile/kmp204x/qrio.c @@ -188,3 +188,20 @@ void qrio_cpuwd_flag(bool flag) reason1 &= ~REASON1_CPUWD; out_8(qrio_base + REASON1_OFF, reason1); } + +#define RSTCFG_OFF 0x11 + +void qrio_uprstreq(u8 mode) +{ + u32 rstcfg; + void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE; + + rstcfg = in_8(qrio_base + RSTCFG_OFF); + + if (mode & UPREQ_CORE_RST) + rstcfg |= UPREQ_CORE_RST; + else + rstcfg &= ~UPREQ_CORE_RST; + + out_8(qrio_base + RSTCFG_OFF, rstcfg); +} -- cgit v0.10.2 From e3917b21c05776b41663bdfcc7666aca11a381a0 Mon Sep 17 00:00:00 2001 From: "Boschung, Rainer" Date: Tue, 3 Jun 2014 09:05:20 +0200 Subject: kmp204x: prepare to use CPU watchdog This patch configures the qrio to trigger a core reset on a CPU reset request. Signed-off-by: Rainer Boschung Signed-off-by: Valentin Longchamp Reviewed-by: York Sun diff --git a/board/keymile/kmp204x/kmp204x.c b/board/keymile/kmp204x/kmp204x.c index 225262e..cd08379 100644 --- a/board/keymile/kmp204x/kmp204x.c +++ b/board/keymile/kmp204x/kmp204x.c @@ -88,6 +88,9 @@ int board_early_init_f(void) ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); bool cpuwd_flag = false; + /* configure mode for uP reset request */ + qrio_uprstreq(UPREQ_CORE_RST); + /* board only uses the DDR_MCK0, so disable the DDR_MCK1/2/3 */ setbits_be32(&gur->ddrclkdr, 0x001f000f); -- cgit v0.10.2