PMUFW: PM: system_shutdown: Implemented shutdown call for shutdown argument
-Added macros in pm_defs.h for system shutdown argument 'restart' -Exposed array of all masters needed to initiate their suspend upon receiving of system shutdown call -Added checking for restart argument of system shutdown call in pm_api.c -Implemented PmSystemShutdown for argument restart=0 (shutdown) -Further improvement in PmSystemShutdown depend on timeout implementation Signed-off-by: Mirela Simonovic <mirela.simonovic@aggios.com> Signed-off-by: Sören Brinkmann <soren.brinkmann@xilinx.com> Acked-by: Jyotheeswar Reddy Mutthareddyvari <jyothee@xilinx.com>
This commit is contained in:
parent
245017b13c
commit
4c9c9b51a9
6 changed files with 106 additions and 22 deletions
|
@ -159,6 +159,7 @@ static PmPayloadStatus PmCheckArgument(const u8 argType,
|
|||
}
|
||||
break;
|
||||
case ARG_ENABLE:
|
||||
case ARG_RESTART:
|
||||
if (arg != 1U && arg != 0U) {
|
||||
status = PM_PAYLOAD_ERR_ENABLE;
|
||||
}
|
||||
|
|
|
@ -110,10 +110,17 @@ done:
|
|||
/**
|
||||
* PmRequestSuspend() - Requested suspend by a PU for another processor
|
||||
* @master PU from which the request is initiated
|
||||
* @node Processor or subsystem node to be suspended
|
||||
* @node PU/processor node to be suspended
|
||||
* @ack Acknowledge request
|
||||
* @latency Desired wakeup latency - Not supported
|
||||
* @state Desired power status - Not supported
|
||||
* @state Desired power state - Not supported
|
||||
*
|
||||
* If suspend has been successfully requested, the requested PU needs to
|
||||
* initiate its own self suspend. Remember to acknowledge to the requestor
|
||||
* after:
|
||||
* 1. PU/processor gets powered down (after it has initiates self suspend),
|
||||
* 2. PU/processor aborts suspend,
|
||||
* 3. PU/processor does not respond to the request (timeout) - not supported
|
||||
*/
|
||||
static void PmRequestSuspend(const PmMaster *const master,
|
||||
const u32 node,
|
||||
|
@ -123,6 +130,7 @@ static void PmRequestSuspend(const PmMaster *const master,
|
|||
{
|
||||
int status;
|
||||
PmProc* proc;
|
||||
PmMaster* target = NULL;
|
||||
|
||||
PmDbg("(%s, %s, %d, %d)\n", PmStrNode(node), PmStrAck(ack),
|
||||
latency, state);
|
||||
|
@ -134,29 +142,43 @@ static void PmRequestSuspend(const PmMaster *const master,
|
|||
}
|
||||
|
||||
proc = PmGetProcOfOtherMaster(master, node);
|
||||
if (NULL == proc) {
|
||||
PmDbg("ERROR: irregular node %s\n", PmStrNode(node));
|
||||
if (NULL != proc) {
|
||||
/* Node is processor, request suspend to it's master */
|
||||
target = proc->master;
|
||||
} else {
|
||||
/* Check whether the target is placeholder in PU */
|
||||
target = PmMasterGetPlaceholder(node);
|
||||
}
|
||||
|
||||
if (NULL == target) {
|
||||
PmDbg("ERROR: invalid node argument\n");
|
||||
status = XST_INVALID_PARAM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (false == PmCanRequestSuspend(master, proc->master)) {
|
||||
PmDbg("ERROR: %s not allowed to request suspend of %s\n",
|
||||
PmStrNode(master->procs->node.nodeId),
|
||||
PmStrNode(proc->node.nodeId));
|
||||
if (false == PmCanRequestSuspend(master, target)) {
|
||||
PmDbg("ERROR: not allowed to request suspend of %s\n",
|
||||
PmStrNode(node));
|
||||
status = XST_PM_NO_ACCESS;
|
||||
goto done;
|
||||
}
|
||||
|
||||
PmInitSuspendCb(proc->master, node, SUSPEND_REASON_PU_REQ, latency,
|
||||
state, MAX_LATENCY);
|
||||
/*
|
||||
* Suspend has been successfully requested, but the requested PU now
|
||||
* needs to initiate its own self suspend. Remember to acknowledge to
|
||||
* the requestor when: 1. PU gets powered down, 2. PU aborts suspend,
|
||||
* Remember to acknowledge to the requestor when:
|
||||
* 1. PU gets powered down, 2. PU aborts suspend,
|
||||
* 3. PU does not respond to the request (timeout).
|
||||
*/
|
||||
status = PmRememberSuspendRequest(master, proc->master, ack);
|
||||
if (REQUEST_ACK_NO != ack) {
|
||||
status = PmRememberSuspendRequest(master, target, ack);
|
||||
} else {
|
||||
status = XST_SUCCESS;
|
||||
}
|
||||
|
||||
if (XST_SUCCESS == status) {
|
||||
/* Request is ok and saved (remembered to acknowledge) */
|
||||
PmInitSuspendCb(target, node, SUSPEND_REASON_PU_REQ,
|
||||
latency, state, MAX_LATENCY);
|
||||
}
|
||||
|
||||
done:
|
||||
if (XST_SUCCESS != status) {
|
||||
|
@ -536,11 +558,27 @@ done:
|
|||
/**
|
||||
* PmSystemShutdown() - Request system shutdown or restart
|
||||
* @master Master requesting system shutdown
|
||||
* @restart Flag, 0 is for shutdown, 1 for restart
|
||||
* @restart Flag, 0 is for shutdown, 1 for restart (not-supported)
|
||||
*/
|
||||
static void PmSystemShutdown(const PmMaster *const master, const u32 restart)
|
||||
{
|
||||
PmDbg("(%d) not implemented\n", restart);
|
||||
u32 i;
|
||||
|
||||
PmDbg("(%d)\n", restart);
|
||||
|
||||
if (PM_SHUTDOWN == restart) {
|
||||
for (i = 0U; i < ARRAY_SIZE(pmAllMasters); i++) {
|
||||
/* Master requesting shutdown will suspend on its own */
|
||||
if ((master != pmAllMasters[i]) &&
|
||||
(PM_PROC_STATE_ACTIVE ==
|
||||
pmAllMasters[i]->procs->node.currState)) {
|
||||
PmInitSuspendCb(pmAllMasters[i],
|
||||
pmAllMasters[i]->nid,
|
||||
SUSPEND_REASON_SYS_SHUTDOWN,
|
||||
MAX_LATENCY, 0, MAX_LATENCY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -57,6 +57,10 @@
|
|||
#define MAX_LATENCY (~0U)
|
||||
#define MAX_QOS 100U
|
||||
|
||||
/* System shutdown macros */
|
||||
#define PM_SHUTDOWN 0U
|
||||
#define PM_RESTART 1U
|
||||
|
||||
/* PM API ids */
|
||||
#define PM_GET_API_VERSION 1U
|
||||
#define PM_SET_CONFIGURATION 2U
|
||||
|
|
|
@ -223,6 +223,7 @@ PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX] = {
|
|||
PmMaster pmMasterApu_g = {
|
||||
.procs = pmApuProcs_g,
|
||||
.procsCnt = PM_PROC_APU_MAX,
|
||||
.nid = NODE_APU,
|
||||
.ipiMask = IPI_PMU_0_IER_APU_MASK,
|
||||
.pmuBuffer = IPI_BUFFER_PMU_BASE + IPI_BUFFER_TARGET_APU_OFFSET,
|
||||
.buffer = IPI_BUFFER_APU_BASE + IPI_BUFFER_TARGET_PMU_OFFSET,
|
||||
|
@ -238,6 +239,7 @@ PmMaster pmMasterApu_g = {
|
|||
PmMaster pmMasterRpu0_g = {
|
||||
.procs = &pmRpuProcs_g[PM_PROC_RPU_0],
|
||||
.procsCnt = 1U,
|
||||
.nid = NODE_RPU,
|
||||
.ipiMask = IPI_PMU_0_IER_RPU_0_MASK,
|
||||
.pmuBuffer = IPI_BUFFER_PMU_BASE + IPI_BUFFER_TARGET_RPU_0_OFFSET,
|
||||
.buffer = IPI_BUFFER_RPU_0_BASE + IPI_BUFFER_TARGET_PMU_OFFSET,
|
||||
|
@ -253,6 +255,7 @@ PmMaster pmMasterRpu0_g = {
|
|||
PmMaster pmMasterRpu1_g = {
|
||||
.procs = &pmRpuProcs_g[PM_PROC_RPU_1],
|
||||
.procsCnt = 1U,
|
||||
.nid = NODE_RPU_0, /* placeholder for request suspend, not used */
|
||||
.ipiMask = IPI_PMU_0_IER_RPU_1_MASK,
|
||||
.pmuBuffer = IPI_BUFFER_PMU_BASE + IPI_BUFFER_TARGET_RPU_1_OFFSET,
|
||||
.buffer = IPI_BUFFER_RPU_1_BASE + IPI_BUFFER_TARGET_PMU_OFFSET,
|
||||
|
@ -260,7 +263,7 @@ PmMaster pmMasterRpu1_g = {
|
|||
.reqsCnt = 0U,
|
||||
};
|
||||
|
||||
static const PmMaster *const pmAllMasters[] = {
|
||||
PmMaster *const pmAllMasters[PM_MASTER_MAX] = {
|
||||
&pmMasterApu_g,
|
||||
&pmMasterRpu0_g,
|
||||
&pmMasterRpu1_g,
|
||||
|
@ -806,10 +809,12 @@ int PmRememberSuspendRequest(const PmMaster* const reqMaster,
|
|||
int status;
|
||||
|
||||
/*
|
||||
* Assume failure, which will be returned if reqMaster/respMaster pair
|
||||
* is not regular.
|
||||
* Assume that reqMaster/respMaster pair does not exist (reqMaster is
|
||||
* not allowed to request suspend of respMaster). If pair
|
||||
* reqMaster/respMaster is found, reqMaster is allowed to request
|
||||
* suspend and status will be changed
|
||||
*/
|
||||
status = XST_FAILURE;
|
||||
status = XST_PM_NO_ACCESS;
|
||||
|
||||
if (reqMaster == respMaster->pmSuspRequests.reqMst) {
|
||||
if ((REQUEST_ACK_CB_STANDARD == ack) ||
|
||||
|
@ -818,7 +823,7 @@ int PmRememberSuspendRequest(const PmMaster* const reqMaster,
|
|||
respMaster->pmSuspRequests.flags |= PM_REQUESTED_SUSPEND;
|
||||
status = XST_SUCCESS;
|
||||
} else {
|
||||
status = XST_PM_INTERNAL;
|
||||
status = XST_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -899,3 +904,25 @@ int PmMasterNotify(PmMaster* const master, const PmProcEvent event)
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* PmMasterGetPlaceholder() - Check whether there is a master which holds nodeId
|
||||
* @nodeId Id of the node whose placeholder should be found
|
||||
*
|
||||
* @return Pointer to the master if such exist, otherwise NULL
|
||||
*/
|
||||
PmMaster* PmMasterGetPlaceholder(const PmNodeId nodeId)
|
||||
{
|
||||
PmMaster* holder = NULL;
|
||||
u32 i;
|
||||
|
||||
/* Find the master with the node placeholder */
|
||||
for (i = 0U; i < ARRAY_SIZE(pmAllMasters); i++) {
|
||||
if (nodeId == pmAllMasters[i]->nid) {
|
||||
holder = pmAllMasters[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return holder;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,9 @@ typedef struct PmMaster PmMaster;
|
|||
/* Suspend request related */
|
||||
#define PM_REQUESTED_SUSPEND 0x1U
|
||||
|
||||
/* Maximum number of masters currently supported */
|
||||
#define PM_MASTER_MAX 3U
|
||||
|
||||
/*********************************************************************
|
||||
* Structure definitions
|
||||
********************************************************************/
|
||||
|
@ -135,6 +138,13 @@ typedef struct {
|
|||
* PmMaster - contains PM master related informations
|
||||
* @procs Pointer to the array of processors within the master
|
||||
* @procsCnt Number of processors within the master
|
||||
* @nid Placeholder nodeId - used to encode request suspend for group of
|
||||
* processors sharing the same communication channel. When PM
|
||||
* receives this nid as request suspend argument, it initiates
|
||||
* init suspend to the master. At the PU, in init_suspend_cb
|
||||
* implementation, the request is mappend to actual suspend of all
|
||||
* processors in the PU. In RPU case, this data could be
|
||||
* initialized from PCW, based on RPU configuration.
|
||||
* @ipiMask Mask dedicated to the master in IPI registers
|
||||
* @pmuBuffer IPI buffer address into which PMU can write (PMU's buffer)
|
||||
* @buffer IPI buffer address into which this master can write
|
||||
|
@ -148,6 +158,7 @@ typedef struct {
|
|||
typedef struct PmMaster {
|
||||
PmProc* const procs;
|
||||
const u8 procsCnt;
|
||||
PmNodeId nid;
|
||||
const u32 ipiMask;
|
||||
const u32 pmuBuffer;
|
||||
const u32 buffer;
|
||||
|
@ -163,6 +174,8 @@ extern PmMaster pmMasterApu_g;
|
|||
extern PmMaster pmMasterRpu0_g;
|
||||
extern PmMaster pmMasterRpu1_g;
|
||||
|
||||
extern PmMaster *const pmAllMasters[PM_MASTER_MAX];
|
||||
|
||||
extern PmRequirement pmApuReq_g[PM_MASTER_APU_SLAVE_MAX];
|
||||
extern PmRequirement pmRpu0Req_g[PM_MASTER_RPU_0_SLAVE_MAX];
|
||||
|
||||
|
@ -205,5 +218,6 @@ int PmRememberSuspendRequest(const PmMaster* const reqMaster,
|
|||
int PmMasterSuspendAck(PmMaster* const respMaster,
|
||||
const int response);
|
||||
|
||||
PmMaster* PmMasterGetPlaceholder(const PmNodeId nodeId);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef ZYNQMP_XPFW_VERSION__H_
|
||||
#define ZYNQMP_XPFW_VERSION__H_
|
||||
#define ZYNQMP_XPFW_VERSION "2015.1-swbeta2-34-gd56779b12d91"
|
||||
#define ZYNQMP_XPFW_VERSION "2015.1-swbeta2-35-g982c8e2201f1"
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue