From dff2a597f936674a2d3513150554a0be276d362d Mon Sep 17 00:00:00 2001 From: Sarat Chand Savitala Date: Thu, 30 Jul 2015 20:30:55 +0530 Subject: [PATCH] sw_apps:zynqmp_fsbl: Added watchdog support This patch adds System Watchdog Timer support Signed-off-by: Sarat Chand Savitala Acked-by: Krishna Chaitanya Patakamuri --- lib/sw_apps/zynqmp_fsbl/src/xfsbl_config.h | 5 ++++ lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c | 5 ++++ lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h | 23 ++++++++++++++++-- .../zynqmp_fsbl/src/xfsbl_initialization.c | 19 +++++++++------ lib/sw_apps/zynqmp_fsbl/src/xfsbl_main.c | 5 ++++ .../zynqmp_fsbl/src/xfsbl_misc_drivers.c | 24 +++++++++++++++++++ .../zynqmp_fsbl/src/xfsbl_misc_drivers.h | 2 ++ .../zynqmp_fsbl/src/xfsbl_partition_load.c | 5 ++++ 8 files changed, 79 insertions(+), 9 deletions(-) diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_config.h b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_config.h index 632df53d..6669bdcd 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_config.h +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_config.h @@ -123,6 +123,7 @@ extern "C" { * - FSBL_BS_EXCLUDE PL bitstream code will be excluded * - FSBL_SHA2_EXCLUDE SHA2 code will be excluded * - FSBL_EARLY_HANDOFF_EXCLUDE Early handoff related code will be excluded + * - FSBL_WDT_EXCLUDE WDT code will be excluded */ #define FSBL_NAND_EXCLUDE_VAL (0U) #define FSBL_QSPI_EXCLUDE_VAL (0U) @@ -132,6 +133,7 @@ extern "C" { #define FSBL_BS_EXCLUDE_VAL (0U) #define FSBL_SHA2_EXCLUDE_VAL (1U) #define FSBL_EARLY_HANDOFF_EXCLUDE_VAL (0U) +#define FSBL_WDT_EXCLUDE_VAL (0U) #if FSBL_NAND_EXCLUDE_VAL #define FSBL_NAND_EXCLUDE @@ -165,6 +167,9 @@ extern "C" { #define FSBL_EARLY_HANDOFF_EXCLUDE #endif +#if FSBL_WDT_EXCLUDE_VAL +#define FSBL_WDT_EXCLUDE +#endif /************************** Function Prototypes ******************************/ diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c index 1514be43..a353e8db 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c @@ -538,6 +538,11 @@ END: void XFsbl_HandoffExit(u64 HandoffAddress, u32 Flags) { +#ifdef XFSBL_WDT_PRESENT + /* Stop WDT as we are exiting FSBL */ + XFsbl_StopWdt(); +#endif + /** * Flush the L1 data cache and L2 cache, Disable Data Cache */ diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h index a401b5fd..aab204dd 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h @@ -237,6 +237,10 @@ extern "C" { #define CRL_APB_PCAP_CTRL_DIVISOR0_MASK 0X00003F00U #define CRL_APB_PCAP_CTRL_CLKACT_MASK 0X01000000U +/* Register: CRL_APB_RESET_REASON */ +#define CRL_APB_RESET_REASON ( ( CRL_APB_BASEADDR ) + 0X00000220U ) +#define CRL_APB_RESET_REASON_PMU_SYS_RESET_MASK 0X00000004U + /* apu */ /** @@ -342,6 +346,21 @@ extern "C" { #define PMU_GLOBAL_PWR_STATE_ACPU1_MASK 0X00000002U #define PMU_GLOBAL_PWR_STATE_ACPU0_MASK 0X00000001U +/* Register: PMU_GLOBAL_ERROR_STATUS_1 */ +#define PMU_GLOBAL_ERROR_STATUS_1 ( ( PMU_GLOBAL_BASEADDR ) + 0X00000530U ) +#define PMU_GLOBAL_ERROR_STATUS_1_LPD_SWDT_MASK 0X00001000U + +/* Register: PMU_GLOBAL_ERROR_SRST_EN_1 */ +#define PMU_GLOBAL_ERROR_SRST_EN_1 ( ( PMU_GLOBAL_BASEADDR ) + 0X0000056CU ) +#define PMU_GLOBAL_ERROR_SRST_EN_1_LPD_SWDT_MASK 0X00001000U + +/* Register: PMU_GLOBAL_ERROR_SRST_DIS_1 */ +#define PMU_GLOBAL_ERROR_SRST_DIS_1 ( ( PMU_GLOBAL_BASEADDR ) + 0X00000570U ) +#define PMU_GLOBAL_ERROR_SRST_DIS_1_LPD_SWDT_MASK 0X00001000U + +/* Register: PMU_GLOBAL_ERROR_EN_1 */ +#define PMU_GLOBAL_ERROR_EN_1 ( ( PMU_GLOBAL_BASEADDR ) + 0X000005A0U ) +#define PMU_GLOBAL_ERROR_EN_1_LPD_SWDT_MASK 0X00001000U /* rpu */ @@ -503,8 +522,8 @@ extern "C" { /** * Definition for WDT to be included */ -#ifdef XPAR_XWDTPS_0_DEVICE_ID -/*#define XFSBL_WDT_PRESENT*/ +#if (!defined(FSBL_WDT_EXCLUDE) && defined(XPAR_XWDTPS_0_DEVICE_ID)) +#define XFSBL_WDT_PRESENT #endif /** diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_initialization.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_initialization.c index 2270f40b..cac6070c 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_initialization.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_initialization.c @@ -308,9 +308,9 @@ static u32 XFsbl_ProcessorInit(XFsblPs * FsblInstancePtr) static u32 XFsbl_ResetValidation(XFsblPs * FsblInstancePtr) { u32 Status = XFSBL_SUCCESS; -#if 0 u32 FsblErrorStatus=0U; u32 ResetReasonValue=0U; + u32 ErrStatusRegValue; /** * Read the Error Status register @@ -319,15 +319,16 @@ static u32 XFsbl_ResetValidation(XFsblPs * FsblInstancePtr) FsblErrorStatus = XFsbl_In32(XFSBL_ERROR_STATUS_REGISTER_OFFSET); ResetReasonValue = XFsbl_In32(CRL_APB_RESET_REASON); + ErrStatusRegValue = XFsbl_In32(PMU_GLOBAL_ERROR_STATUS_1); /** - * Add LPD_SWDT for r5 - * check if the reset is due to system WDT during + * Check if the reset is due to system WDT during * previous FSBL execution */ - /* WDT reset is missing in reset reason */ - if (((ResetReasonValue & CRL_APB_RESET_REASON_FPD_SWDT_MASK) - == CRL_APB_RESET_REASON_FPD_SWDT_MASK) && + if (((ResetReasonValue & CRL_APB_RESET_REASON_PMU_SYS_RESET_MASK) + == CRL_APB_RESET_REASON_PMU_SYS_RESET_MASK) && + ((ErrStatusRegValue & PMU_GLOBAL_ERROR_STATUS_1_LPD_SWDT_MASK) + == PMU_GLOBAL_ERROR_STATUS_1_LPD_SWDT_MASK) && (FsblErrorStatus == XFSBL_RUNNING)) { /** * reset is due to System WDT. @@ -353,7 +354,6 @@ static u32 XFsbl_ResetValidation(XFsblPs * FsblInstancePtr) */ END: -#endif return Status; } @@ -457,6 +457,11 @@ static u32 XFsbl_PrimaryBootDeviceInit(XFsblPs * FsblInstancePtr) { XFsbl_Printf(DEBUG_GENERAL,"In JTAG Boot Mode \n\r"); Status = XFSBL_STATUS_JTAG; + +#ifdef XFSBL_WDT_PRESENT + /* Stop WDT as we are in JTAG boot mode */ + XFsbl_StopWdt(); +#endif } break; diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_main.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_main.c index 93323848..c6005441 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_main.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_main.c @@ -408,6 +408,11 @@ void XFsbl_FallBack(void) { u32 RegValue; +#ifdef XFSBL_WDT_PRESENT + /* Stop WDT as we are restarting */ + XFsbl_StopWdt(); +#endif + /* Hook before FSBL Fallback */ XFsbl_HookBeforeFallback(); diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.c index 6aa7b122..4028fcc0 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.c @@ -99,6 +99,8 @@ u32 XFsbl_InitWdt() u32 Status = XFSBL_SUCCESS; XWdtPs_Config *ConfigPtr; /* Config structure of the WatchDog Timer */ u32 CounterValue = 1; + u32 RegValue; + /** * Initialize the WDT timer @@ -135,6 +137,16 @@ u32 XFsbl_InitWdt() */ XWdtPs_EnableOutput(&Watchdog, XWDTPS_RESET_SIGNAL); + /* Enable generation of system reset by PMU due to LPD SWDT */ + RegValue = XFsbl_In32(PMU_GLOBAL_ERROR_SRST_EN_1); + RegValue |= PMU_GLOBAL_ERROR_SRST_EN_1_LPD_SWDT_MASK; + XFsbl_Out32(PMU_GLOBAL_ERROR_SRST_EN_1, RegValue); + + /* Enable LPD System Watchdog Timer Error */ + RegValue = XFsbl_In32(PMU_GLOBAL_ERROR_EN_1); + RegValue |= PMU_GLOBAL_ERROR_EN_1_LPD_SWDT_MASK; + XFsbl_Out32(PMU_GLOBAL_ERROR_EN_1, RegValue); + /** * Start the Watchdog timer */ @@ -216,7 +228,19 @@ void XFsbl_RestartWdt() *******************************************************************************/ void XFsbl_StopWdt() { + u32 RegValue; + XWdtPs_Stop(&Watchdog); + + /* Disable LPD System Watchdog Timer Error */ + RegValue = XFsbl_In32(PMU_GLOBAL_ERROR_EN_1); + RegValue &= ~(PMU_GLOBAL_ERROR_EN_1_LPD_SWDT_MASK); + XFsbl_Out32(PMU_GLOBAL_ERROR_EN_1, RegValue); + + /* Disable generation of system reset by PMU due to LPD SWDT */ + RegValue = XFsbl_In32(PMU_GLOBAL_ERROR_SRST_DIS_1); + RegValue |= PMU_GLOBAL_ERROR_SRST_DIS_1_LPD_SWDT_MASK; + XFsbl_Out32(PMU_GLOBAL_ERROR_SRST_DIS_1, RegValue); } #endif /** end of WDT wrapper code */ diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.h b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.h index 45807d74..da9828a3 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.h +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.h @@ -77,6 +77,8 @@ extern "C" { #ifdef XFSBL_WDT_PRESENT u32 XFsbl_InitWdt(); u32 XFsbl_ConvertTime_WdtCounter(u32 seconds); +void XFsbl_StopWdt(); +void XFsbl_RestartWdt(); #endif /************************** Variable Definitions *****************************/ diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c index 48753786..d631ffde 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c @@ -113,6 +113,11 @@ u32 XFsbl_PartitionLoad(XFsblPs * FsblInstancePtr, u32 PartitionNum) { u32 Status=XFSBL_SUCCESS; +#ifdef XFSBL_WDT_PRESENT + /* Restart WDT as partition copy can take more time */ + XFsbl_RestartWdt(); +#endif + /** * Load and validate the partition */