From 568b6a14941cd81fc616c2315d9e1cff97db4195 Mon Sep 17 00:00:00 2001 From: Mirela Simonovic Date: Sun, 31 May 2015 21:13:54 -0700 Subject: [PATCH] PMUFW: PM: Save/restore CRF_APB's context on FPD power down/up -Added array of CRF_APB module's register address/value pairs used for saving/restoring CRF_APB register contents (excluding PLL registers - PLLs have their own logic for save/restore) -Added saving context of CRF_APB registers before FPD is powered down and restoring saved context after FPD is powered up Signed-off-by: Mirela Simonovic Acked-by: Jyotheeswar Reddy Mutthareddyvari --- lib/sw_apps/zynqmp_pmufw/src/pm_common.h | 14 +++++ lib/sw_apps/zynqmp_pmufw/src/pm_power.c | 58 +++++++++++++++++++++ lib/sw_apps/zynqmp_pmufw/src/xpfw_version.h | 2 +- 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_common.h b/lib/sw_apps/zynqmp_pmufw/src/pm_common.h index 30dd0c60..30d05e0b 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_common.h +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_common.h @@ -117,6 +117,20 @@ typedef u32 (*const PmTranHandler)(void); /* PMU internal capabilities used in definition of slaves' states */ #define PM_CAP_POWER 0x8U +/********************************************************************* + * Structure definitions + ********************************************************************/ +/** + * PmRegisterContext - A pair of address/value used for saving/restoring context + * of a register + * @addr Address of a register + * @value Variable to store register content + */ +typedef struct PmRegisterContext { + const u32 addr; + u32 value; +} PmRegisterContext; + /********************************************************************* * Function declarations ********************************************************************/ diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_power.c b/lib/sw_apps/zynqmp_pmufw/src/pm_power.c index 2ef3d601..31eda68a 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_power.c +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_power.c @@ -40,6 +40,60 @@ #include "pm_sram.h" #include "pm_periph.h" #include "xpfw_rom_interface.h" +#include "crf_apb.h" + +/* + * Note: PLL registers will never be saved/restored as part of CRF_APB module + * context. PLLs have separate logic, which is part of PmSlavePll (pm_pll.h/c) + */ +static PmRegisterContext pmCrfContext[] = { + { .addr = CRF_APB_ERR_CTRL }, + { .addr = CRF_APB_CRF_WPROT }, + { .addr = CRF_APB_ACPU_CTRL, }, + { .addr = CRF_APB_DBG_TRACE_CTRL }, + { .addr = CRF_APB_DBG_FPD_CTRL }, + { .addr = CRF_APB_DP_VIDEO_REF_CTRL }, + { .addr = CRF_APB_DP_AUDIO_REF_CTRL }, + { .addr = CRF_APB_DP_STC_REF_CTRL }, + { .addr = CRF_APB_DDR_CTRL }, + { .addr = CRF_APB_GPU_REF_CTRL }, + { .addr = CRF_APB_SATA_REF_CTRL }, + { .addr = CRF_APB_PCIE_REF_CTRL }, + { .addr = CRF_APB_GDMA_REF_CTRL }, + { .addr = CRF_APB_DPDMA_REF_CTRL }, + { .addr = CRF_APB_TOPSW_MAIN_CTRL }, + { .addr = CRF_APB_TOPSW_LSBUS_CTRL }, + { .addr = CRF_APB_GTGREF0_REF_CTRL }, + { .addr = CRF_APB_DBG_TSTMP_CTRL }, + { .addr = CRF_APB_RST_FPD_TOP }, + { .addr = CRF_APB_RST_FPD_APU }, + { .addr = CRF_APB_RST_DDR_SS }, +}; + +/** + * PmCrfSaveContext() - Save context of CRF_APB module due to powering down FPD + */ +static void PmCrfSaveContext(void) +{ + u32 i; + + for (i = 0U; i < ARRAY_SIZE(pmCrfContext); i++) { + pmCrfContext[i].value = XPfw_Read32(pmCrfContext[i].addr); + } +} + +/** + * PmCrfRestoreContext() - Restore context of CRF_APB module (FPD has been + * powered up) + */ +static void PmCrfRestoreContext(void) +{ + u32 i; + + for (i = 0U; i < ARRAY_SIZE(pmCrfContext); i++) { + XPfw_Write32(pmCrfContext[i].addr, pmCrfContext[i].value); + } +} /** * PmPowerDownFpd() - Power down FPD domain @@ -51,6 +105,7 @@ static int PmPowerDownFpd(void) int status = XpbrRstFpdHandler(); if (XST_SUCCESS == status) { + PmCrfSaveContext(); status = XpbrPwrDnFpdHandler(); /* * When FPD is powered off, the APU-GIC will be affected too. @@ -131,6 +186,9 @@ static int PmPwrUpHandler(PmNode* const nodePtr) status = XST_SUCCESS; } #endif + if (XST_SUCCESS == status) { + PmCrfRestoreContext(); + } break; case NODE_APU: status = XST_SUCCESS; diff --git a/lib/sw_apps/zynqmp_pmufw/src/xpfw_version.h b/lib/sw_apps/zynqmp_pmufw/src/xpfw_version.h index 7e3a7937..bec37440 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/xpfw_version.h +++ b/lib/sw_apps/zynqmp_pmufw/src/xpfw_version.h @@ -1,4 +1,4 @@ #ifndef ZYNQMP_XPFW_VERSION__H_ #define ZYNQMP_XPFW_VERSION__H_ - #define ZYNQMP_XPFW_VERSION "2015.1-swbeta2-39-g8cd4c95b44ef" + #define ZYNQMP_XPFW_VERSION "2015.1-swbeta2-40-ge46a2aec66e8" #endif