mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-03-16 23:07:00 +00:00
- turris_omnia: enable A385 watchdog before disabling MCU watchdog (Pali) - a37xx: Reset whole UART when changing parent clock from TBG to XTAL (Pali)
This commit is contained in:
commit
4a14bfffd4
2 changed files with 75 additions and 3 deletions
|
@ -43,6 +43,23 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
#define OMNIA_I2C_EEPROM_CHIP_LEN 2
|
||||
#define OMNIA_I2C_EEPROM_MAGIC 0x0341a034
|
||||
|
||||
#define SYS_RSTOUT_MASK MVEBU_REGISTER(0x18260)
|
||||
#define SYS_RSTOUT_MASK_WD BIT(10)
|
||||
|
||||
#define A385_WDT_GLOBAL_CTRL MVEBU_REGISTER(0x20300)
|
||||
#define A385_WDT_GLOBAL_RATIO_MASK GENMASK(18, 16)
|
||||
#define A385_WDT_GLOBAL_RATIO_SHIFT 16
|
||||
#define A385_WDT_GLOBAL_25MHZ BIT(10)
|
||||
#define A385_WDT_GLOBAL_ENABLE BIT(8)
|
||||
|
||||
#define A385_WDT_GLOBAL_STATUS MVEBU_REGISTER(0x20304)
|
||||
#define A385_WDT_GLOBAL_EXPIRED BIT(31)
|
||||
|
||||
#define A385_WDT_DURATION MVEBU_REGISTER(0x20334)
|
||||
|
||||
#define A385_WD_RSTOUT_UNMASK MVEBU_REGISTER(0x20704)
|
||||
#define A385_WD_RSTOUT_UNMASK_GLOBAL BIT(8)
|
||||
|
||||
enum mcu_commands {
|
||||
CMD_GET_STATUS_WORD = 0x01,
|
||||
CMD_GET_RESET = 0x09,
|
||||
|
@ -141,6 +158,47 @@ static int omnia_mcu_write(u8 cmd, const void *buf, int len)
|
|||
return dm_i2c_write(chip, cmd, buf, len);
|
||||
}
|
||||
|
||||
static void enable_a385_watchdog(unsigned int timeout_minutes)
|
||||
{
|
||||
struct sar_freq_modes sar_freq;
|
||||
u32 watchdog_freq;
|
||||
|
||||
printf("Enabling A385 watchdog with %u minutes timeout...\n",
|
||||
timeout_minutes);
|
||||
|
||||
/*
|
||||
* Use NBCLK clock (a.k.a. L2 clock) as watchdog input clock with
|
||||
* its maximal ratio 7 instead of default fixed 25 MHz clock.
|
||||
* It allows to set watchdog duration up to the 22 minutes.
|
||||
*/
|
||||
clrsetbits_32(A385_WDT_GLOBAL_CTRL,
|
||||
A385_WDT_GLOBAL_25MHZ | A385_WDT_GLOBAL_RATIO_MASK,
|
||||
7 << A385_WDT_GLOBAL_RATIO_SHIFT);
|
||||
|
||||
/*
|
||||
* Calculate watchdog clock frequency. It is defined by formula:
|
||||
* freq = NBCLK / 2 / (2 ^ ratio)
|
||||
* We set ratio to the maximal possible value 7.
|
||||
*/
|
||||
get_sar_freq(&sar_freq);
|
||||
watchdog_freq = sar_freq.nb_clk * 1000000 / 2 / (1 << 7);
|
||||
|
||||
/* Set watchdog duration */
|
||||
writel(timeout_minutes * 60 * watchdog_freq, A385_WDT_DURATION);
|
||||
|
||||
/* Clear the watchdog expiration bit */
|
||||
clrbits_32(A385_WDT_GLOBAL_STATUS, A385_WDT_GLOBAL_EXPIRED);
|
||||
|
||||
/* Enable watchdog timer */
|
||||
setbits_32(A385_WDT_GLOBAL_CTRL, A385_WDT_GLOBAL_ENABLE);
|
||||
|
||||
/* Enable reset on watchdog */
|
||||
setbits_32(A385_WD_RSTOUT_UNMASK, A385_WD_RSTOUT_UNMASK_GLOBAL);
|
||||
|
||||
/* Unmask reset for watchdog */
|
||||
clrbits_32(SYS_RSTOUT_MASK, SYS_RSTOUT_MASK_WD);
|
||||
}
|
||||
|
||||
static bool disable_mcu_watchdog(void)
|
||||
{
|
||||
int ret;
|
||||
|
@ -423,10 +481,13 @@ void spl_board_init(void)
|
|||
{
|
||||
/*
|
||||
* If booting from UART, disable MCU watchdog in SPL, since uploading
|
||||
* U-Boot proper can take too much time and trigger it.
|
||||
* U-Boot proper can take too much time and trigger it. Instead enable
|
||||
* A385 watchdog with very high timeout (10 minutes) to prevent hangup.
|
||||
*/
|
||||
if (get_boot_device() == BOOT_DEVICE_UART)
|
||||
if (get_boot_device() == BOOT_DEVICE_UART) {
|
||||
enable_a385_watchdog(10);
|
||||
disable_mcu_watchdog();
|
||||
}
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <serial.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <mach/soc.h>
|
||||
|
||||
struct mvebu_plat {
|
||||
void __iomem *base;
|
||||
|
@ -213,6 +214,7 @@ static int mvebu_serial_remove(struct udevice *dev)
|
|||
u32 new_oversampling;
|
||||
u32 oversampling;
|
||||
u32 d1, d2;
|
||||
u32 nb_rst;
|
||||
|
||||
/*
|
||||
* Switch UART base clock back to XTAL because older Linux kernel
|
||||
|
@ -260,12 +262,22 @@ static int mvebu_serial_remove(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* wait until TX empty */
|
||||
while (!(readl(base + UART_STATUS_REG) & UART_STATUS_TX_EMPTY))
|
||||
;
|
||||
|
||||
/* external reset of UART via North Bridge Peripheral */
|
||||
nb_rst = readl(MVEBU_REGISTER(0x12400));
|
||||
writel(nb_rst & ~BIT(3), MVEBU_REGISTER(0x12400));
|
||||
writel(nb_rst | BIT(3), MVEBU_REGISTER(0x12400));
|
||||
|
||||
/* set baudrate and oversampling */
|
||||
writel(new_divider, base + UART_BAUD_REG);
|
||||
writel(new_oversampling, base + UART_POSSR_REG);
|
||||
|
||||
/* No Parity, 1 Stop */
|
||||
writel(0, base + UART_CTRL_REG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -305,7 +317,6 @@ U_BOOT_DRIVER(serial_mvebu) = {
|
|||
#ifdef CONFIG_DEBUG_MVEBU_A3700_UART
|
||||
|
||||
#include <debug_uart.h>
|
||||
#include <mach/soc.h>
|
||||
|
||||
static inline void _debug_uart_init(void)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue