board: freescale: p1_p2_rdb_pc: Add workaround for non-working watchdog
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. Watchdog starts 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. Note that reset does not occur immediately after calling do_reset(), but after few ms later as real reset is done by CPLD. So it is normal that function do_reset() returns. Therefore hangs after calling do_reset() to prevent CPU execution of the rest U-Boot code. Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Peng Fan <peng.fan@nxp.com>
This commit is contained in:
parent
1f90be6f34
commit
27b2bff6eb
@ -92,6 +92,7 @@ void board_reset(void)
|
||||
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);
|
||||
@ -111,6 +112,26 @@ void board_cpld_init(void)
|
||||
* and it has to be done in 100ms since the last start of reset.
|
||||
*/
|
||||
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) {
|
||||
eieio();
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
while (1); /* do_reset() does not occur immediately */
|
||||
}
|
||||
}
|
||||
|
||||
void board_gpio_init(void)
|
||||
|
Loading…
Reference in New Issue
Block a user