PMUFW: PM: pm_master: Added default requirements, set upon entering active state

-Added default requirements field in PmRequirements structure
-Added notification of master when primary processor switches from
 forced powerdown to active state. Master has to make sure that all
 default requirements gets set before primary processor enters active
 state.
-In PmMasterNotify, changed behavior when wake event is received:
 if primary processor is in sleep state, everything works as before,
 if primary processor is in forced powerdown, default requirements
 are requested and configured
-In PmRequirementReleaseAll added a check is master using slave and
 if yes, usage flag and requirements are cleared
-Added PmRequirementRequestDefault function called before primary
 processor switches from forced powerdown to active. Function
 automatically requests all default requirements which are later
 configured by PmRequirementUpdateScheduled
-In PmRequirementUpdateScheduled when swapping requirements added
 a check whether master has default requirements. If yes, default
 reqs are saved as next reqs instead of current. Default requirements
 have priority over current requirement. Example: RPU0 keeps boot code
 in one TCM bank and when booted, during the runtime, it keeps that
 bank in retention. For this bank RPU0 should have default requirements
 = on state, and when it boots up it can request retention. If default
 requirements wouldn't exist, it would have to request for boot bank to
 switch from retention to on before calling self suspend, just to get
 on state in scheduled reqs

Signed-off-by: Mirela Simonovic <mirela.simonovic@aggios.com>
Acked-by: Sören Brinkmann <soren.brinkmann@xilinx.com>
Acked-by: Jyotheeswar Reddy Mutthareddyvari <jyothee@xilinx.com>
This commit is contained in:
Mirela Simonovic 2015-03-03 14:35:52 +01:00 committed by Nava kishore Manne
parent 2ff64bf7a9
commit 13e22f9eb0
4 changed files with 103 additions and 21 deletions

View file

@ -49,6 +49,7 @@ PmRequirement pmApuReq_g[PM_MASTER_APU_SLAVE_MAX] = {
.slave = &pmSlaveOcm0_g.slv,
.requestor = &pmMasterApu_g,
.info = PM_MASTER_USING_SLAVE_MASK,
.defaultReq = 0U,
.currReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.nextReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
},
@ -56,6 +57,7 @@ PmRequirement pmApuReq_g[PM_MASTER_APU_SLAVE_MAX] = {
.slave = &pmSlaveOcm1_g.slv,
.requestor = &pmMasterApu_g,
.info = PM_MASTER_USING_SLAVE_MASK,
.defaultReq = 0U,
.currReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.nextReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
},
@ -63,6 +65,7 @@ PmRequirement pmApuReq_g[PM_MASTER_APU_SLAVE_MAX] = {
.slave = &pmSlaveOcm2_g.slv,
.requestor = &pmMasterApu_g,
.info = PM_MASTER_USING_SLAVE_MASK,
.defaultReq = 0U,
.currReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.nextReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
},
@ -70,6 +73,7 @@ PmRequirement pmApuReq_g[PM_MASTER_APU_SLAVE_MAX] = {
.slave = &pmSlaveOcm3_g.slv,
.requestor = &pmMasterApu_g,
.info = PM_MASTER_USING_SLAVE_MASK,
.defaultReq = 0U,
.currReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.nextReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
},
@ -77,6 +81,7 @@ PmRequirement pmApuReq_g[PM_MASTER_APU_SLAVE_MAX] = {
.slave = &pmSlaveL2_g.slv,
.requestor = &pmMasterApu_g,
.info = PM_MASTER_USING_SLAVE_MASK,
.defaultReq = 0U,
.currReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.nextReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
},
@ -84,6 +89,7 @@ PmRequirement pmApuReq_g[PM_MASTER_APU_SLAVE_MAX] = {
.slave = &pmSlaveUsb0_g.slv,
.requestor = &pmMasterApu_g,
.info = 0U,
.defaultReq = 0U,
.currReq = 0U,
.nextReq = 0U,
},
@ -91,6 +97,7 @@ PmRequirement pmApuReq_g[PM_MASTER_APU_SLAVE_MAX] = {
.slave = &pmSlaveUsb1_g.slv,
.requestor = &pmMasterApu_g,
.info = 0U,
.defaultReq = 0U,
.currReq = 0U,
.nextReq = 0U,
},
@ -98,6 +105,7 @@ PmRequirement pmApuReq_g[PM_MASTER_APU_SLAVE_MAX] = {
.slave = &pmSlaveTtc0_g.slv,
.requestor = &pmMasterApu_g,
.info = 0U,
.defaultReq = 0U,
.currReq = 0U,
.nextReq = 0U,
},
@ -105,6 +113,7 @@ PmRequirement pmApuReq_g[PM_MASTER_APU_SLAVE_MAX] = {
.slave = &pmSlaveSata_g.slv,
.requestor = &pmMasterApu_g,
.info = 0U,
.defaultReq = 0U,
.currReq = 0U,
.nextReq = 0U,
},
@ -116,6 +125,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveOcm0_g.slv,
.requestor = &pmMasterRpu0_g,
.info = 0U,
.defaultReq = 0U,
.currReq = 0U,
.nextReq = 0U,
},
@ -123,6 +133,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveOcm1_g.slv,
.requestor = &pmMasterRpu0_g,
.info = 0U,
.defaultReq = 0U,
.currReq = 0U,
.nextReq = 0U,
},
@ -130,6 +141,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveOcm2_g.slv,
.requestor = &pmMasterRpu0_g,
.info = 0U,
.defaultReq = 0U,
.currReq = 0U,
.nextReq = 0U,
},
@ -137,6 +149,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveOcm3_g.slv,
.requestor = &pmMasterRpu0_g,
.info = PM_MASTER_USING_SLAVE_MASK,
.defaultReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.currReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.nextReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
},
@ -144,6 +157,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveTcm0A_g.slv,
.requestor = &pmMasterRpu0_g,
.info = PM_MASTER_USING_SLAVE_MASK,
.defaultReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.currReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.nextReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
},
@ -151,6 +165,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveTcm0B_g.slv,
.requestor = &pmMasterRpu0_g,
.info = PM_MASTER_USING_SLAVE_MASK,
.defaultReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.currReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.nextReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
},
@ -158,6 +173,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveTcm1A_g.slv,
.requestor = &pmMasterRpu0_g,
.info = PM_MASTER_USING_SLAVE_MASK,
.defaultReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.currReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.nextReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
},
@ -165,6 +181,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveTcm1B_g.slv,
.requestor = &pmMasterRpu0_g,
.info = PM_MASTER_USING_SLAVE_MASK,
.defaultReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.currReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
.nextReq = PM_CAP_ACCESS | PM_CAP_CONTEXT,
},
@ -172,6 +189,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveUsb0_g.slv,
.requestor = &pmMasterRpu0_g,
.info = 0U,
.defaultReq = 0U,
.currReq = 0U,
.nextReq = 0U,
},
@ -179,6 +197,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveUsb1_g.slv,
.requestor = &pmMasterRpu0_g,
.info = 0U,
.defaultReq = 0U,
.currReq = 0U,
.nextReq = 0U,
},
@ -186,6 +205,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveTtc0_g.slv,
.requestor = &pmMasterRpu0_g,
.info = 0U,
.defaultReq = 0U,
.currReq = 0U,
.nextReq = 0U,
},
@ -193,6 +213,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
.slave = &pmSlaveSata_g.slv,
.requestor = &pmMasterRpu0_g,
.info = 0U,
.defaultReq = 0U,
.currReq = 0U,
.nextReq = 0U,
},
@ -304,20 +325,24 @@ done:
}
/**
* PmRequirementUpdateScheduled() - Triggers the setting for scheduled requirements
* PmRequirementUpdateScheduled() - Triggers the setting for scheduled
( requirements
* @master Master which changed the state and whose scheduled requirements are
* triggered
* @swap Flag stating should current requirement be saved as next
* @swap Flag stating should current/default requirements be saved as next
*
* a) swap=false
* Set scheduled requirements of a master without swapping current and
* next requirements - means the current requirements will be dropped.
* Upon every self suspend, master has to explicitly re-request
* slave requirements.
* Set scheduled requirements of a master without swapping current/default and
* next requirements - means the current requirements will be dropped and
* default requirements has no effect. Upon every self suspend, master has to
* explicitly re-request slave requirements.
* b) swap=true
* Set scheduled requirements of a master with swapping current and
* next requirements (swapping means the current requirements will be
* saved as next, and will be configured once master wakes-up)
* Set scheduled requirements of a master with swapping current/default and
* next requirements (swapping means the current/default requirements will be
* saved as next, and will be configured once master wakes-up). If the master
* has default requirements, default requirements are saved as next instead of
* current requirements. Default requirements has priority over current
* requirements.
*/
static void PmRequirementUpdateScheduled(const PmMaster* const master,
const bool swap)
@ -332,8 +357,18 @@ static void PmRequirementUpdateScheduled(const PmMaster* const master,
u32 tmpReq = master->reqs[i].nextReq;
if (true == swap) {
/* Swap current and next requirements */
master->reqs[i].nextReq = master->reqs[i].currReq;
if (0U != master->reqs[i].defaultReq) {
/* Master has default requirements for
* this slave, default has priority over
* current requirements.
*/
master->reqs[i].nextReq =
master->reqs[i].defaultReq;
} else {
/* Save current requirements as next */
master->reqs[i].nextReq =
master->reqs[i].currReq;
}
}
master->reqs[i].currReq = tmpReq;
@ -368,6 +403,29 @@ void PmRequirementCancelScheduled(const PmMaster* const master)
}
}
/**
* PmRequirementRequestDefault() - Request default requirements for master
* @master Master whose default requirements are requested
*
* When waking up from forced power down, master might have some default
* requirements to be configured before it enters active state (example TCM for
* RPU). This function loops all slaves, find those for which this master has
* default requirements and updates next requirements in master/slave
* requirement structure.
*/
static void PmRequirementRequestDefault(const PmMaster* const master)
{
PmRequirementId i;
for (i = 0; i < master->reqsCnt; i++) {
if (0U != master->reqs[i].defaultReq) {
/* Set flag to state that master is using slave */
master->reqs[i].info |= PM_MASTER_USING_SLAVE_MASK;
master->reqs[i].nextReq = master->reqs[i].defaultReq;
}
}
}
/**
* PmRequirementReleaseAll() - Called when master primary processor is forced to
* power down, so all requirements of the processor
@ -380,14 +438,19 @@ static void PmRequirementReleaseAll(const PmMaster* const master)
PmRequirementId i;
for (i = 0; i < master->reqsCnt; i++) {
master->reqs[i].currReq = 0U;
master->reqs[i].nextReq = 0U;
/* Update slave setting */
status = PmUpdateSlave(master->reqs[i].slave);
/* if pmu rom works correctly, status should be always ok */
if (PM_RET_SUCCESS != status) {
PmDbg("ERROR setting slave node %s\n",
PmStrNode(master->reqs[i].slave->node.nodeId));
if (0U != (PM_MASTER_USING_SLAVE_MASK & master->reqs[i].info)) {
/* Clear flag - master is not using slave anymore */
master->reqs[i].info &= ~PM_MASTER_USING_SLAVE_MASK;
/* Release current and next requirements */
master->reqs[i].currReq = 0U;
master->reqs[i].nextReq = 0U;
/* Update slave setting */
status = PmUpdateSlave(master->reqs[i].slave);
/* if pmu rom works correctly, status should be always ok */
if (PM_RET_SUCCESS != status) {
PmDbg("ERROR setting slave node %s\n",
PmStrNode(master->reqs[i].slave->node.nodeId));
}
}
}
}
@ -697,8 +760,14 @@ void PmMasterNotify(PmMaster* const master, const PmProcEvent event)
PmWakeUpCancelScheduled(master);
break;
case PM_PROC_EVENT_WAKE:
if (PM_PROC_STATE_SLEEP == master->procs->node.currState) {
PmWakeUpDisableAll(master);
} else if (PM_PROC_STATE_FORCEDOFF ==
master->procs->node.currState) {
PmRequirementRequestDefault(master);
} else {
}
PmRequirementUpdateScheduled(master, false);
PmWakeUpDisableAll(master);
break;
case PM_PROC_EVENT_FORCE_PWRDN:
PmRequirementReleaseAll(master);

View file

@ -99,6 +99,9 @@ typedef struct PmMaster PmMaster;
* @info Contains information about master's request - a bit for
* encoding has master requested or released node, and a bit to
* encode has master requested a wake-up of this slave.
* @defaultReq Default requirements of a master - requirements for slave
* capabilities without which master's primary processor cannot
* switch to active state.
* @currReq Currently holding requirements of a master for this slave
* @nextReq Requirements of a master to be configured when it changes the
* state (after it goes to sleep or before it gets awake)
@ -107,6 +110,7 @@ typedef struct PmRequirement {
PmSlave* const slave;
PmMaster* const requestor;
u8 info;
const u32 defaultReq;
u32 currReq;
u32 nextReq;
} PmRequirement;

View file

@ -331,6 +331,15 @@ static u32 PmProcTrForcePwrdnToActive(PmProc* const proc)
{
PmDbg("FORCED_PWRDN->ACTIVE %s\n", PmStrNode(proc->node.nodeId));
if (true == proc->isPrimary) {
/*
* Notify master to update slave capabilities according to the
* scheduled requests. For waking-up from forced powerdown,
* these requirements are always only default requirements.
*/
PmMasterNotify(proc->master, PM_PROC_EVENT_WAKE);
}
return PmProcWake(&proc->node);
}

View file

@ -1,4 +1,4 @@
#ifndef ZYNQMP_XPFW_VERSION__H_
#define ZYNQMP_XPFW_VERSION__H_
#define ZYNQMP_XPFW_VERSION "2015.1-swbeta2-27-g58a81909d7b5"
#define ZYNQMP_XPFW_VERSION "2015.1-swbeta2-28-gcb1b9c3b28ae"
#endif