
If watchdog timer was already set to non-disabled value then it means that watchdog timer was already activated, has already expired and caused CPU reset. If this happened then due to CPLD firmware bug, writing to wd_cfg register has no effect and therefore it is not possible to reactivate watchdog timer again. Also if CPU was reset via watchdog then some peripherals like i2c do not work. Watchdog and i2c start working again after CPU reset via non-watchdog method.
Implement this workaround (reset CPU when it was reset by watchdog) to make watchdog usable again. Watchdog timer logic on these P1/P2 RDB boards is connected to CPLD, not to SoC itself.
Signed-off-by: Pali Rohár pali@kernel.org --- board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c index 26ea8a525228..24b5ec435e4e 100644 --- a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c +++ b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c @@ -86,6 +86,7 @@ struct cpld_data { void board_cpld_init(void) { struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + u8 prev_wd_cfg = in_8(&cpld_data->wd_cfg);
out_8(&cpld_data->wd_cfg, CPLD_WD_CFG); out_8(&cpld_data->status_led, CPLD_STATUS_LED); @@ -102,6 +103,23 @@ void board_cpld_init(void) * is to try to clear CPLD's system reset register as early as possible. */ out_8(&cpld_data->system_rst, CPLD_SYS_RST); + + /* + * If watchdog timer was already set to non-disabled value then it means + * that watchdog timer was already activated, has already expired and + * caused CPU reset. If this happened then due to CPLD firmware bug, + * writing to wd_cfg register has no effect and therefore it is not + * possible to reactivate watchdog timer again. Also if CPU was reset + * via watchdog then some peripherals like i2c do not work. Watchdog and + * i2c start working again after CPU reset via non-watchdog method. + * + * So in case watchdog timer register in CPLD was already enabled then + * disable it in CPLD and reset CPU which cause new boot. Watchdog timer + * is disabled few lines above, after reading CPLD previous value. + * This logic (disabling timer before reset) prevents reboot loop. + */ + if (prev_wd_cfg != CPLD_WD_CFG) + do_reset(NULL, 0, 0, NULL); }
void board_gpio_init(void)