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 <mirela.simonovic@aggios.com>
Acked-by: Jyotheeswar Reddy Mutthareddyvari <jyothee@xilinx.com>
This commit is contained in:
Mirela Simonovic 2015-05-31 21:13:54 -07:00 committed by Nava kishore Manne
parent 64ad843e0d
commit 568b6a1494
3 changed files with 73 additions and 1 deletions

View file

@ -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
********************************************************************/

View file

@ -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;

View file

@ -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