diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c index 9a2f9d3..58e8c02 100644 --- a/plat/intel/soc/stratix10/bl2_plat_setup.c +++ b/plat/intel/soc/stratix10/bl2_plat_setup.c @@ -32,6 +32,7 @@ #include "aarch64/stratix10_private.h" #include "include/s10_mailbox.h" #include "drivers/qspi/cadence_qspi.h" +#include "drivers/wdt/watchdog.h" const mmap_region_t plat_stratix10_mmap[] = { @@ -72,6 +73,8 @@ deassert_peripheral_reset(); config_hps_hs_before_warm_reset(); + watchdog_init(get_wdt_clk(&reverse_handoff_ptr)); + console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE, &console); diff --git a/plat/intel/soc/stratix10/drivers/wdt/watchdog.c b/plat/intel/soc/stratix10/drivers/wdt/watchdog.c new file mode 100644 index 0000000..b4dbe5f --- /dev/null +++ b/plat/intel/soc/stratix10/drivers/wdt/watchdog.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "watchdog.h" + + +/* Reset watchdog timer */ +void watchdog_sw_rst(void) +{ + mmio_write_32(WDT_CRR, WDT_SW_RST); +} + +/* Print component information */ +void watchdog_info(void) +{ + INFO("Component Type : %x\r\n", mmio_read_32(WDT_COMP_VERSION)); + INFO("Component Version : %x\r\n", mmio_read_32(WDT_COMP_TYPE)); +} + +/* Check watchdog current status */ +void watchdog_status(void) +{ + if (mmio_read_32(WDT_CR) & 1) { + INFO("Watchdog Timer in currently enabled\n"); + INFO("Current Counter : 0x%x\r\n", mmio_read_32(WDT_CCVR)); + } else { + INFO("Watchdog Timer in currently disabled\n"); + } +} + +/* Initialize & enable watchdog */ +void watchdog_init(int watchdog_clk) +{ + uint8_t cycles_i = 0; + uint32_t wdt_cycles = WDT_MIN_CYCLES; + uint32_t top_init_cycles = WDT_PERIOD * watchdog_clk; + + while ((cycles_i < 15) && (wdt_cycles < top_init_cycles)) { + wdt_cycles = (wdt_cycles << 1); + cycles_i++; + } + + mmio_write_32(WDT_TORR, (cycles_i << 4) | cycles_i); + + watchdog_enable(); +} + +void watchdog_enable(void) +{ + mmio_write_32(WDT_CR, WDT_CR_RMOD|WDT_CR_EN); +} diff --git a/plat/intel/soc/stratix10/drivers/wdt/watchdog.h b/plat/intel/soc/stratix10/drivers/wdt/watchdog.h new file mode 100644 index 0000000..e920236 --- /dev/null +++ b/plat/intel/soc/stratix10/drivers/wdt/watchdog.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __CAD_WATCHDOG_H__ +#define __CAD_WATCHDOG_H__ + +#define WDT_BASE (0xFFD00200) +#define WDT_REG_SIZE_OFFSET (0x4) +#define WDT_MIN_CYCLES (65536) +#define WDT_PERIOD (20) + +#define WDT_CR (WDT_BASE + 0x0) +#define WDT_TORR (WDT_BASE + 0x4) + +#define WDT_CRR (WDT_BASE + 0xC) + +#define WDT_CCVR (WDT_BASE + 0x8) +#define WDT_STAT (WDT_BASE + 0x10) +#define WDT_EOI (WDT_BASE + 0x14) + +#define WDT_COMP_PARAM_1 (WDT_BASE + 0xF4) +#define WDT_COMP_VERSION (WDT_BASE + 0xF8) +#define WDT_COMP_TYPE (WDT_BASE + 0XFC) + +#define WDT_CR_RMOD (0x0) +#define WDT_CR_EN (0x1) + +#define WDT_SW_RST (0x76) + + +void watchdog_init(int watchdog_clk); +void watchdog_enable(void); +void watchdog_info(void); +void watchdog_status(void); +void watchdog_sw_rst(void); + +#endif diff --git a/plat/intel/soc/stratix10/include/s10_clock_manager.h b/plat/intel/soc/stratix10/include/s10_clock_manager.h index 28192fa..99eb7a6 100644 --- a/plat/intel/soc/stratix10/include/s10_clock_manager.h +++ b/plat/intel/soc/stratix10/include/s10_clock_manager.h @@ -50,6 +50,11 @@ #define ALT_CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000000ff) #define ALT_CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET(x) (((x) << 9) & 0x0001fe00) +#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC(x) (((x) & 0x00030000) >> 16) +#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1 0x0 +#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC 0x1 +#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S 0x2 + #define ALT_CLKMGR_PERPLL 0xffd100a4 #define ALT_CLKMGR_PERPLL_EN 0x0 #define ALT_CLKMGR_PERPLL_BYPASS 0xc @@ -78,6 +83,14 @@ #define ALT_CLKMGR_PERPLL_VCOCALIB_MSCNT_SET(x) (((x) << 9) & 0x0001fe00) #define ALT_CLKMGR_PERPLL_VCOCALIB 0x58 + +typedef struct { + uint32_t clk_freq_of_eosc1; + uint32_t clk_freq_of_f2h_free; + uint32_t clk_freq_of_cb_intosc_ls; +} CLOCK_SOURCE_CONFIG; + void config_clkmgr_handoff(handoff *hoff_ptr); +int get_wdt_clk(handoff *hoff_ptr); #endif diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk index 1f06fbd..fdd6e45 100644 --- a/plat/intel/soc/stratix10/platform.mk +++ b/plat/intel/soc/stratix10/platform.mk @@ -46,7 +46,8 @@ plat/intel/soc/stratix10/soc/s10_system_manager.c \ common/desc_image_load.c \ plat/intel/soc/stratix10/soc/s10_mailbox.c \ - plat/intel/soc/stratix10/drivers/qspi/cadence_qspi.c + plat/intel/soc/stratix10/drivers/qspi/cadence_qspi.c \ + plat/intel/soc/stratix10/drivers/wdt/watchdog.c BL31_SOURCES += drivers/arm/cci/cci.c \ lib/cpus/aarch64/cortex_a53.S \ diff --git a/plat/intel/soc/stratix10/soc/s10_clock_manager.c b/plat/intel/soc/stratix10/soc/s10_clock_manager.c index 9d4617a..dc90076 100644 --- a/plat/intel/soc/stratix10/soc/s10_clock_manager.c +++ b/plat/intel/soc/stratix10/soc/s10_clock_manager.c @@ -15,6 +15,14 @@ #include "s10_clock_manager.h" #include "s10_handoff.h" +static const CLOCK_SOURCE_CONFIG clk_source = { + /* clk_freq_of_eosc1 */ + (uint32_t) 25000000, + /* clk_freq_of_f2h_free */ + (uint32_t) 460000000, + /* clk_freq_of_cb_intosc_ls */ + (uint32_t) 50000000, +}; void wait_pll_lock(void) { @@ -190,3 +198,37 @@ ALT_CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK); } +int get_wdt_clk(handoff *hoff_ptr) +{ + int main_noc_base_clk, l3_main_free_clk, l4_sys_free_clk; + int data32, mdiv, refclkdiv, ref_clk; + + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB); + + switch (ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC(data32)) { + case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1: + ref_clk = clk_source.clk_freq_of_eosc1; + break; + case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC: + ref_clk = clk_source.clk_freq_of_cb_intosc_ls; + break; + case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S: + ref_clk = clk_source.clk_freq_of_f2h_free; + break; + default: + ref_clk = 0; + assert(0); + break; + } + + refclkdiv = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(data32); + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK); + mdiv = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(data32); + ref_clk = (ref_clk / refclkdiv) * (6 + mdiv); + + main_noc_base_clk = ref_clk / (hoff_ptr->main_pll_pllc1 & 0xff); + l3_main_free_clk = main_noc_base_clk / (hoff_ptr->main_pll_nocclk + 1); + l4_sys_free_clk = l3_main_free_clk / 4; + + return l4_sys_free_clk; +}