diff options
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/cpu.c | 8 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/interrupts.c | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/processor.h | 5 | ||||
-rw-r--r-- | arch/powerpc/lib/board.c | 3 | ||||
-rw-r--r-- | board/keymile/kmp204x/kmp204x.c | 15 | ||||
-rw-r--r-- | board/keymile/kmp204x/kmp204x.h | 7 | ||||
-rw-r--r-- | board/keymile/kmp204x/qrio.c | 32 | ||||
-rw-r--r-- | include/configs/km/kmp204x-common.h | 8 | ||||
-rw-r--r-- | include/watchdog.h | 4 |
9 files changed, 83 insertions, 1 deletions
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/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 */ 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 */ 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; diff --git a/board/keymile/kmp204x/kmp204x.c b/board/keymile/kmp204x/kmp204x.c index 6bc8eb8..cd08379 100644 --- a/board/keymile/kmp204x/kmp204x.c +++ b/board/keymile/kmp204x/kmp204x.c @@ -80,14 +80,29 @@ 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; + + /* 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); + /* 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 */ diff --git a/board/keymile/kmp204x/kmp204x.h b/board/keymile/kmp204x/kmp204x.h index afede99..e90e8ab 100644 --- a/board/keymile/kmp204x/kmp204x.h +++ b/board/keymile/kmp204x/kmp204x.h @@ -24,5 +24,12 @@ 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); + +#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 b6ba93a..edf3bf1 100644 --- a/board/keymile/kmp204x/qrio.c +++ b/board/keymile/kmp204x/qrio.c @@ -173,3 +173,35 @@ 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); +} + +#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); +} 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 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_ */ |