diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_binding.c b/lib/sw_apps/zynqmp_pmufw/src/pm_binding.c index 5e49ba03..5597e65c 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_binding.c +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_binding.c @@ -67,6 +67,13 @@ void XPfw_PmInit(void) * @apiId PM API id that was read from master's IPI buffer and validated as * existing * + * @return Status of the processing IPI + * - XST_INVALID_PARAM if isrMask parameter has invalid value + * - XST_SUCCESS otherwise + * - Note that if request is processed, firmware is not receiving any + * status of processing information. Processing status is returned to + * the master which initiated communication through IPI. + * * @note Call from IPI#0 interrupt routine. IPI's #0 interrupt can be used * for some other purposes, not only for PM, and in #0 interrupt * routine must : @@ -79,9 +86,10 @@ void XPfw_PmInit(void) * be cleared after this function returns to make PM API call * atomic. */ -void XPfw_PmIpiHandler(const u32 isrMask, - const u32 apiId) +int XPfw_PmIpiHandler(const u32 isrMask, + const u32 apiId) { + int status = XST_SUCCESS; u32 i; u32 payload[PAYLOAD_ELEM_CNT]; u32 bufferBase; @@ -91,6 +99,7 @@ void XPfw_PmIpiHandler(const u32 isrMask, if (NULL == master) { /* Never happens if IPI interrupt routine is implemented correctly */ PmDbg("ERROR: IPI source not supported %d\n", isrMask); + status = XST_INVALID_PARAM; goto done; } @@ -105,7 +114,7 @@ void XPfw_PmIpiHandler(const u32 isrMask, PmProcessRequest(master, payload); done: - return; + return status; } /** @@ -115,17 +124,20 @@ done: * @note Call from GPI2 interrupt routine to process sleep request. Must not * clear GPI2 interrupt before this function returns. */ -void XPfw_PmWfiHandler(const u32 srcMask) +int XPfw_PmWfiHandler(const u32 srcMask) { + int status; PmProc *proc = PmGetProcByWfiStatus(srcMask); if (NULL == proc) { PmDbg("ERROR: Unknown processor %d\n", srcMask); + status = XST_INVALID_PARAM; goto done; } - PmProcFsm(proc, PM_PROC_EVENT_SLEEP); - if ((true == proc->isPrimary) && (true == IS_OFF(&proc->node))) { + status = PmProcFsm(proc, PM_PROC_EVENT_SLEEP); + if ((XST_SUCCESS == status) && (true == proc->isPrimary) && + (true == IS_OFF(&proc->node))) { /* * We've just powered down a primary processor, now use opportunistic * suspend to power down its parent(s) @@ -134,7 +146,7 @@ void XPfw_PmWfiHandler(const u32 srcMask) } done: - return; + return status; } /** @@ -153,21 +165,21 @@ done: * slave it is determined which processor should be woken-up (always * wake the primary processor, owner of the master channel). */ -u32 XPfw_PmWakeHandler(const u32 srcMask) +int XPfw_PmWakeHandler(const u32 srcMask) { - u32 status = PM_RET_SUCCESS; + int status = XST_SUCCESS; if (PMU_IOMODULE_GPI1_GIC_WAKES_ALL_MASK & srcMask) { /* Processor GIC wake */ PmProc* proc = PmGetProcByWakeStatus(srcMask); if (NULL != proc) { - PmProcFsm(proc, PM_PROC_EVENT_WAKE); + status = PmProcFsm(proc, PM_PROC_EVENT_WAKE); } else { - status = PM_RET_ERROR_PROC; + status = XST_INVALID_PARAM; } } else { /* Slave wake */ - PmSlaveProcessWake(srcMask); + status = PmSlaveProcessWake(srcMask); } return status; @@ -188,7 +200,7 @@ u32 XPfw_PmWakeHandler(const u32 srcMask) XPfw_PmIpiStatus XPfw_PmCheckIpiRequest(const u32 isrVal, u32* const apiId) { - u32 status; + XPfw_PmIpiStatus status; bool isValid; const PmMaster *master = PmGetMasterByIpiMask(isrVal); diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_binding.h b/lib/sw_apps/zynqmp_pmufw/src/pm_binding.h index 8042cad5..b2811fa4 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_binding.h +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_binding.h @@ -36,6 +36,7 @@ #define PM_BINDING_H_ #include "xil_types.h" +#include "xstatus.h" /********************************************************************* * Enum definitions @@ -57,12 +58,12 @@ void XPfw_PmInit(void); XPfw_PmIpiStatus XPfw_PmCheckIpiRequest(const u32 isrVal, u32* const apiId); /* Call from IPI interrupt routine to handle PM API request */ -void XPfw_PmIpiHandler(const u32 isrMask, const u32 apiId); +int XPfw_PmIpiHandler(const u32 isrMask, const u32 apiId); /* Call from GPI2 interrupt routine to handle processor sleep request */ -void XPfw_PmWfiHandler(const u32 srcMask); +int XPfw_PmWfiHandler(const u32 srcMask); /* Call from GPI1 interrupt routine to handle wake request */ -u32 XPfw_PmWakeHandler(const u32 srcMask); +int XPfw_PmWakeHandler(const u32 srcMask); #endif diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_core.c b/lib/sw_apps/zynqmp_pmufw/src/pm_core.c index f10045d5..5d28ab00 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_core.c +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_core.c @@ -55,15 +55,16 @@ static void PmProcessAckRequest(const u32 ack, const u32 status, const u32 oppoint) { - if (status != PM_RET_SUCCESS) { +#ifdef DEBUG_PM + if (status != XST_SUCCESS) { PmDbg("ERROR PM operation failed - code %d\n", status); } - +#endif if (REQUEST_ACK_BLOCKING == ack) { /* Return status immediately */ XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET, status); } else if ((REQUEST_ACK_CB_STANDARD == ack) || - ((REQUEST_ACK_CB_ERROR == ack) && (PM_RET_SUCCESS != status))) { + ((REQUEST_ACK_CB_ERROR == ack) && (XST_SUCCESS != status))) { /* Return acknowledge through callback */ PmAcknowledgeCb(master, nodeId, status, oppoint); } else { @@ -87,6 +88,7 @@ static void PmSelfSuspend(const PmMaster *const master, const u32 latency, const u32 state) { + int status; /* the node ID must refer to a processor belonging to this master */ PmProc* proc = PmGetProcOfThisMaster(master, node); @@ -95,13 +97,14 @@ static void PmSelfSuspend(const PmMaster *const master, if (NULL == proc) { PmDbg("ERROR node ID %s(=%d) does not refer to a processor of " "this master channel\n", PmStrNode(node), node); + status = XST_INVALID_PARAM; goto done; } - PmProcFsm(proc, PM_PROC_EVENT_SELF_SUSPEND); + status = PmProcFsm(proc, PM_PROC_EVENT_SELF_SUSPEND); done: - return; + XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET, status); } /** @@ -125,7 +128,7 @@ static void PmRequestSuspend(const PmMaster *const master, if (NULL == proc) { PmDbg("ERROR processor not found by node %d\n", node); - PmProcessAckRequest(ack, master, node, PM_RET_ERROR_ARGS, 0); + PmProcessAckRequest(ack, master, node, XST_INVALID_PARAM, 0); goto done; } @@ -151,27 +154,28 @@ static void PmForcePowerdown(const PmMaster *const master, const u32 node, const u32 ack) { - u32 status; + int status; u32 oppoint = 0U; PmNode* nodePtr = PmGetNodeById(node); PmDbg("(%s, %s)\n", PmStrNode(node), PmStrAck(ack)); if (NULL == nodePtr) { - status = PM_RET_ERROR_ARGS; + status = XST_INVALID_PARAM; goto done; } switch (nodePtr->typeId) { case PM_TYPE_PROC: - status = PmProcFsm((PmProc*)nodePtr->derived, PM_PROC_EVENT_FORCE_PWRDN); + status = PmProcFsm((PmProc*)nodePtr->derived, + PM_PROC_EVENT_FORCE_PWRDN); break; case PM_TYPE_PWR_ISLAND: case PM_TYPE_PWR_DOMAIN: status = PmForceDownTree((PmPower*)nodePtr->derived); break; default: - status = PM_RET_ERROR_OTHER; + status = XST_INVALID_PARAM; break; } @@ -181,7 +185,7 @@ static void PmForcePowerdown(const PmMaster *const master, * Successfully powered down a node, now trigger opportunistic * suspend to power down its parent(s) if possible */ - if (PM_RET_SUCCESS == status && NULL != nodePtr->parent) { + if ((XST_SUCCESS == status) && (NULL != nodePtr->parent)) { PmOpportunisticSuspend(nodePtr->parent); } @@ -202,6 +206,7 @@ static void PmAbortSuspend(const PmMaster *const master, const u32 reason, const u32 node) { + int status; PmProc* proc = PmGetProcOfThisMaster(master, node); PmDbg("(%s, %s)\n", PmStrNode(node), PmStrReason(reason)); @@ -209,13 +214,14 @@ static void PmAbortSuspend(const PmMaster *const master, if (NULL == proc) { PmDbg("ERROR processor access for node %s not allowed\n", PmStrNode(node)); + status = XST_PM_INVALID_NODE; goto done; } - PmProcFsm(proc, PM_PROC_EVENT_ABORT_SUSPEND); + status = PmProcFsm(proc, PM_PROC_EVENT_ABORT_SUSPEND); done: - return; + XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET, status); } /** @@ -227,14 +233,14 @@ done: static void PmRequestWakeup(const PmMaster *const master, const u32 node, const u32 ack) { - u32 status; + int status; u32 oppoint = 0U; PmProc* proc = PmGetProcByNodeId(node); PmDbg("(%s, %s)\n", PmStrNode(node), PmStrAck(ack)); if (NULL == proc) { - status = PM_RET_ERROR_PROC; + status = XST_PM_INVALID_NODE; goto done; } @@ -256,21 +262,30 @@ static void PmReleaseNode(const PmMaster *master, const u32 node, const u32 latency) { - u32 status; + int status; /* Get static requirements structure for this master/slave pair */ PmRequirement* masterReq = PmGetRequirementForSlave(master, node); if (NULL == masterReq) { + status = XST_PM_NO_ACCESS; PmDbg("ERROR Can't find requirement for slave %s of master %s\n", PmStrNode(node), PmStrNode(master->procs[0].node.nodeId)); goto done; } + if (0U == (masterReq->info & PM_MASTER_USING_SLAVE_MASK)) { + status = XST_FAILURE; + PmDbg("WARNING %s attempt to release %s without previous " + "request\n", PmStrNode(master->procs[0].node.nodeId), + PmStrNode(node)); + goto done; + } + /* Release requirements */ status = PmRequirementUpdate(masterReq, 0U); masterReq->info &= ~PM_MASTER_USING_SLAVE_MASK; - if (PM_RET_SUCCESS != status) { + if (XST_SUCCESS != status) { PmDbg("ERROR PmRequirementUpdate status = %d\n", status); goto done; } @@ -283,7 +298,7 @@ static void PmReleaseNode(const PmMaster *master, done: PmDbg("(%s, %d)\n", PmStrNode(node), latency); - return; + XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET, status); } /** @@ -300,7 +315,7 @@ static void PmRequestNode(const PmMaster *master, const u32 qos, const u32 ack) { - u32 status; + int status; u32 oppoint = 0U; /* * Each legal master/slave pair will have one static PmRequirement data @@ -315,12 +330,12 @@ static void PmRequestNode(const PmMaster *master, if (NULL == masterReq) { /* Master is not allowed to use the slave with given node */ PmDbg("ERROR Master can't use the slave\n"); - status = PM_RET_ERROR_ACCESS; + status = XST_PM_NO_ACCESS; goto done; } if (PM_MASTER_USING_SLAVE_MASK & masterReq->info) { - status = PM_RET_ERROR_DOUBLEREQ; + status = XST_PM_DOUBLE_REQ; goto done; } @@ -351,7 +366,7 @@ static void PmSetRequirement(const PmMaster *master, const u32 qos, const u32 ack) { - u32 status; + int status; u32 oppoint = 0U; PmRequirement* masterReq = PmGetRequirementForSlave(master, node); @@ -360,13 +375,13 @@ static void PmSetRequirement(const PmMaster *master, /* Is there a provision for the master to use the given slave node */ if (NULL == masterReq) { - status = PM_RET_ERROR_ACCESS; + status = XST_PM_NO_ACCESS; goto done; } - /* Does master have the privilege to request settings for the node? */ + /* Check if master has previously requested the node */ if (0U == (PM_MASTER_USING_SLAVE_MASK & masterReq->info)) { - status = PM_RET_ERROR_ACCESS; + status = XST_PM_NO_ACCESS; goto done; } @@ -381,8 +396,11 @@ static void PmSetRequirement(const PmMaster *master, status = PmRequirementUpdate(masterReq, capabilities); break; default: - /* Should never happen */ - status = PM_RET_ERROR_COMMUNIC; + /* + * Should never happen as processor cannot call this API while + * powered down. + */ + status = XST_FAILURE; break; } oppoint = masterReq->slave->node.currState; @@ -401,7 +419,7 @@ static void PmGetApiVersion(const PmMaster *const master) PmDbg("version %d.%d\n", PM_VERSION_MAJOR, PM_VERSION_MINOR); - XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET, PM_RET_SUCCESS); + XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET, XST_SUCCESS); XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET + PAYLOAD_ELEM_SIZE, version); } @@ -422,7 +440,7 @@ static void PmMmioWrite(const PmMaster *const master, const u32 address, PmDbg("(0x%x, 0x%x, 0x%x)\n", address, mask, value); XPfw_Write32(address, mask & value); - XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET, PM_RET_SUCCESS); + XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET, XST_SUCCESS); } /** @@ -442,7 +460,7 @@ static void PmMmioRead(const PmMaster *const master, const u32 address, PmDbg("addr=0x%x, mask=0x%x\n", address, mask); value = XPfw_Read32(address) & mask; - XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET, PM_RET_SUCCESS); + XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET, XST_SUCCESS); XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET + PAYLOAD_ELEM_SIZE, value); } @@ -462,9 +480,16 @@ static void PmSetWakeupSource(const PmMaster *const master, const u32 sourceNode, const u32 enable) { + int status = XST_SUCCESS; PmRequirement* req = PmGetRequirementForSlave(master, sourceNode); - if ((NULL == req) || (NULL == req->slave->wake)) { + if (NULL == req) { + status = XST_PM_NO_ACCESS; + goto done; + } + + if (NULL == req->slave->wake) { + status = XST_NO_FEATURE; goto done; } @@ -477,6 +502,8 @@ static void PmSetWakeupSource(const PmMaster *const master, done: PmDbg("(%s, %s, %d)\n", PmStrNode(master->procs->node.nodeId), PmStrNode(sourceNode), enable); + + XPfw_Write32(master->buffer + IPI_BUFFER_RESP_OFFSET, status); } /** @@ -647,7 +674,7 @@ void PmProcessApiCall(const PmMaster *const master, default: PmDbg("ERROR unsupported PM API #%d\n", pload[0]); PmProcessAckRequest(PmRequestAcknowledge(pload), master, - NODE_UNKNOWN, PM_RET_ERROR_NOTSUPPORTED, 0); + NODE_UNKNOWN, XST_INVALID_VERSION, 0); break; } } @@ -675,7 +702,7 @@ void PmProcessRequest(const PmMaster *const master, u32 ack = PmRequestAcknowledge(pload); if (REQUEST_ACK_NO != ack) { PmAcknowledgeCb(master, NODE_UNKNOWN, - PM_RET_ERROR_API_ID, 0); + XST_INVALID_PARAM, 0); } } } diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_defs.h b/lib/sw_apps/zynqmp_pmufw/src/pm_defs.h index c589435d..76b40256 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_defs.h +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_defs.h @@ -151,18 +151,11 @@ #define PM_OPCHAR_TYPE_ENERGY 2U #define PM_OPCHAR_TYPE_TEMP 3U -/* PM API call return status */ -#define PM_RET_SUCCESS 0U -#define PM_RET_ERROR_ARGS 1U -#define PM_RET_ERROR_ACCESS 2U -#define PM_RET_ERROR_TIMEOUT 3U -#define PM_RET_ERROR_NOTSUPPORTED 4U -#define PM_RET_ERROR_PROC 5U -#define PM_RET_ERROR_API_ID 6U -#define PM_RET_ERROR_FAILURE 7U -#define PM_RET_ERROR_COMMUNIC 8U -#define PM_RET_ERROR_DOUBLEREQ 9U -#define PM_RET_ERROR_INTERNAL 24U -#define PM_RET_ERROR_OTHER 25U +/* Power management specific return error statuses */ +#define XST_PM_INTERNAL 2000L +#define XST_PM_CONFLICT 2001L +#define XST_PM_NO_ACCESS 2002L +#define XST_PM_INVALID_NODE 2003L +#define XST_PM_DOUBLE_REQ 2004L #endif diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_master.c b/lib/sw_apps/zynqmp_pmufw/src/pm_master.c index 8de7be83..f7c679e2 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_master.c +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_master.c @@ -267,15 +267,17 @@ static const PmMaster *const pmAllMasters[] = { * goes to sleep. * * @return Status of the operation + * - XST_SUCCESS if requirement is successfully scheduled + * - XST_NO_FEATURE if there is no state with requested + * capabilities */ -u32 PmRequirementSchedule(PmRequirement* const masterReq, const u32 caps) +int PmRequirementSchedule(PmRequirement* const masterReq, const u32 caps) { - u32 status; + int status; /* Check if slave has a state with requested capabilities */ status = PmCheckCapabilities(masterReq->slave, caps); - if (PM_RET_SUCCESS != status) { - status = PM_RET_ERROR_NOTSUPPORTED; + if (XST_SUCCESS != status) { goto done; } @@ -295,15 +297,15 @@ done: * * @return Status of the operation */ -u32 PmRequirementUpdate(PmRequirement* const masterReq, const u32 caps) +int PmRequirementUpdate(PmRequirement* const masterReq, const u32 caps) { - u32 status; + int status; u32 tmpCaps; /* Check if slave has a state with requested capabilities */ status = PmCheckCapabilities(masterReq->slave, caps); - if (PM_RET_SUCCESS != status) { + if (XST_SUCCESS != status) { goto done; } @@ -312,7 +314,7 @@ u32 PmRequirementUpdate(PmRequirement* const masterReq, const u32 caps) masterReq->currReq = caps; status = PmUpdateSlave(masterReq->slave); - if (PM_RET_SUCCESS == status) { + if (XST_SUCCESS == status) { /* All capabilities requested in active state are constant */ masterReq->nextReq = masterReq->currReq; } else { @@ -344,10 +346,10 @@ done: * current requirements. Default requirements has priority over current * requirements. */ -static void PmRequirementUpdateScheduled(const PmMaster* const master, - const bool swap) +static int PmRequirementUpdateScheduled(const PmMaster* const master, + const bool swap) { - u32 status; + int status; PmRequirementId i; PmDbg("%s\n", PmStrNode(master->procs[0].node.nodeId)); @@ -376,12 +378,15 @@ static void PmRequirementUpdateScheduled(const PmMaster* const master, /* Update slave setting */ status = PmUpdateSlave(master->reqs[i].slave); /* if rom works correctly, status should be always ok */ - if (PM_RET_SUCCESS != status) { + if (XST_SUCCESS != status) { PmDbg("ERROR setting slave node %s\n", PmStrNode(master->reqs[i].slave->node.nodeId)); + break; } } } + + return status; } /** @@ -431,10 +436,13 @@ static void PmRequirementRequestDefault(const PmMaster* const master) * power down, so all requirements of the processor * are automatically released. * @master Master whose primary processor was forced to power down + * + * @return Status of the operation of releasing all slaves used by the master + * and changing their state to the lowest possible. */ -static void PmRequirementReleaseAll(const PmMaster* const master) +static int PmRequirementReleaseAll(const PmMaster* const master) { - u32 status; + int status; PmRequirementId i; for (i = 0; i < master->reqsCnt; i++) { @@ -447,12 +455,15 @@ static void PmRequirementReleaseAll(const PmMaster* const master) /* Update slave setting */ status = PmUpdateSlave(master->reqs[i].slave); /* if pmu rom works correctly, status should be always ok */ - if (PM_RET_SUCCESS != status) { + if (XST_SUCCESS != status) { PmDbg("ERROR setting slave node %s\n", PmStrNode(master->reqs[i].slave->node.nodeId)); + break; } } } + + return status; } /** @@ -746,14 +757,18 @@ static void PmWakeUpDisableAll(PmMaster* const master) * @master Pointer to master object which needs to be notified * @event Processor Event to notify the master about * + * @return Status of potential changing of slave states or success. + * * Primary processor has changed its state, notify master to update its requirements * accordingly. */ -void PmMasterNotify(PmMaster* const master, const PmProcEvent event) +int PmMasterNotify(PmMaster* const master, const PmProcEvent event) { + int status = XST_SUCCESS; + switch (event) { case PM_PROC_EVENT_SLEEP: - PmRequirementUpdateScheduled(master, true); + status = PmRequirementUpdateScheduled(master, true); break; case PM_PROC_EVENT_ABORT_SUSPEND: PmRequirementCancelScheduled(master); @@ -767,14 +782,17 @@ void PmMasterNotify(PmMaster* const master, const PmProcEvent event) PmRequirementRequestDefault(master); } else { } - PmRequirementUpdateScheduled(master, false); + status = PmRequirementUpdateScheduled(master, false); break; case PM_PROC_EVENT_FORCE_PWRDN: - PmRequirementReleaseAll(master); + status = PmRequirementReleaseAll(master); PmWakeUpCancelScheduled(master); break; default: + status = XST_PM_INTERNAL; PmDbg("ERROR: undefined event #%d\n", event); break; } + + return status; } diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_master.h b/lib/sw_apps/zynqmp_pmufw/src/pm_master.h index deb787e3..1c067ee0 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_master.h +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_master.h @@ -168,15 +168,14 @@ PmRequirement* PmGetRequirementForSlave(const PmMaster* const master, const PmNodeId nodeId); /* Requirements related functions */ -u32 PmRequirementSchedule(PmRequirement* const masterReq, const u32 caps); -u32 PmRequirementUpdate(PmRequirement* const masterReq, const u32 caps); +int PmRequirementSchedule(PmRequirement* const masterReq, const u32 caps); +int PmRequirementUpdate(PmRequirement* const masterReq, const u32 caps); +/* Notify master by a primary core when changing state */ +int PmMasterNotify(PmMaster* const master, const PmProcEvent event); /* Call at initialization to enable all masters' IPI interrupts */ void PmEnableAllMasterIpis(void); -/* Notify master by a primary core when changing state */ -void PmMasterNotify(PmMaster* const master, const PmProcEvent event); - /* Call when FPD goes down to enable GIC Proxy interrupts */ void PmEnableProxyWake(PmMaster* const master); diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_node.h b/lib/sw_apps/zynqmp_pmufw/src/pm_node.h index 4f7fdfef..3ea0be3f 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_node.h +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_node.h @@ -38,6 +38,7 @@ #include "pm_defs.h" #include "pm_common.h" #include "xil_types.h" +#include "xstatus.h" typedef u8 PmNodeId; typedef u8 PmStateId; @@ -49,7 +50,7 @@ typedef struct PmPower PmPower; typedef struct PmNode PmNode; /* Function pointer for wake/sleep transition functions */ -typedef u32 (*const PmNodeTranHandler)(PmNode* const nodePtr); +typedef int (*const PmNodeTranHandler)(PmNode* const nodePtr); /********************************************************************* * Macros diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_power.c b/lib/sw_apps/zynqmp_pmufw/src/pm_power.c index e826b933..2ef3d601 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_power.c +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_power.c @@ -41,42 +41,52 @@ #include "pm_periph.h" #include "xpfw_rom_interface.h" +/** + * PmPowerDownFpd() - Power down FPD domain + * + * @return Status of the pmu-rom operations + */ +static int PmPowerDownFpd(void) +{ + int status = XpbrRstFpdHandler(); + + if (XST_SUCCESS == status) { + status = XpbrPwrDnFpdHandler(); + /* + * When FPD is powered off, the APU-GIC will be affected too. + * GIC Proxy has to take over for all wake-up sources for + * the APU. + */ + PmEnableProxyWake(&pmMasterApu_g); + } + + return status; +} + /** * PmPwrDnHandler() - Power down island/domain * @nodePtr Pointer to node-structure of power island/dom to be powered off * - * @return Operation status - * - PM_RET_SUCCESS if transition succeeded - * - PM_RET_ERROR_FAILURE if pmu rom failed to set the state + * @return Operation status of power down procedure (done by pmu-rom) */ -static u32 PmPwrDnHandler(PmNode* const nodePtr) +static int PmPwrDnHandler(PmNode* const nodePtr) { - u32 ret = PM_RET_ERROR_FAILURE; + int status = XST_PM_INTERNAL; if (NULL == nodePtr) { - ret = PM_RET_ERROR_FAILURE; goto done; } /* Call proper PMU-ROM handler as needed */ switch (nodePtr->nodeId) { case NODE_FPD: - ret = XpbrRstFpdHandler(); - if (ret == XST_SUCCESS) { - ret = XpbrPwrDnFpdHandler(); - /* - * When FPD is powered off, the APU-GIC will be affected too. - * GIC Proxy has to take over for all wake-up sources for - * the APU. - */ - PmEnableProxyWake(&pmMasterApu_g); - } + status = PmPowerDownFpd(); break; case NODE_APU: - ret = XST_SUCCESS; + status = XST_SUCCESS; break; case NODE_RPU: - ret = XpbrPwrDnRpuHandler(); + status = XpbrPwrDnRpuHandler(); break; default: PmDbg("unsupported node %s(%d)\n", @@ -84,30 +94,24 @@ static u32 PmPwrDnHandler(PmNode* const nodePtr) break; } - if (XST_SUCCESS != ret) { - ret = PM_RET_ERROR_FAILURE; - goto done; + if (XST_SUCCESS == status) { + nodePtr->currState = PM_PWR_STATE_OFF; } - nodePtr->currState = PM_PWR_STATE_OFF; - ret = PM_RET_SUCCESS; - done: PmDbg("%s\n", PmStrNode(nodePtr->nodeId)); - return ret; + return status; } /** * PmPwrUpHandler() - Power up island/domain * @nodePtr Pointer to node-structure of power island/dom to be powered on * - * @return Operation status - * - PM_RET_SUCCESS if transition succeeded - * - PM_RET_ERROR_FAILURE if pmu rom failed to set the state + * @return Operation status of power up procedure (done by pmu-rom) */ -static u32 PmPwrUpHandler(PmNode* const nodePtr) +static int PmPwrUpHandler(PmNode* const nodePtr) { - u32 ret = PM_RET_ERROR_FAILURE; + int status = XST_PM_INTERNAL; PmDbg("%s\n", PmStrNode(nodePtr->nodeId)); @@ -118,20 +122,24 @@ static u32 PmPwrUpHandler(PmNode* const nodePtr) /* Call proper PMU-ROM handler as needed */ switch (nodePtr->nodeId) { case NODE_FPD: - ret = XpbrPwrUpFpdHandler(); - PmDbg("XpbrPwrUpFpdHandler return code #%d\n", ret); + status = XpbrPwrUpFpdHandler(); +#ifdef DEBUG_PM /* FIXME workaround for old version of pmu-rom */ - PmDbg("ignoring error\n"); - ret = XST_SUCCESS; + if (XST_SUCCESS != status) { + PmDbg("XpbrPwrUpFpdHandler returned #%d." + "Ignoring error\n", status); + status = XST_SUCCESS; + } +#endif break; case NODE_APU: - ret = XST_SUCCESS; + status = XST_SUCCESS; break; case NODE_RPU: { u32 reg; - ret = XpbrPwrUpRpuHandler(); + status = XpbrPwrUpRpuHandler(); /* release RPU island reset */ reg = Xil_In32(CRL_APB_RST_LPD_TOP); @@ -144,19 +152,12 @@ static u32 PmPwrUpHandler(PmNode* const nodePtr) PmStrNode(nodePtr->nodeId), nodePtr->nodeId); break; } - - if (XST_SUCCESS != ret) { - PmDbg("failed to power up %s PBR ERROR #%d\n", - PmStrNode(nodePtr->nodeId), ret); - ret = PM_RET_ERROR_FAILURE; - goto done; + if (XST_SUCCESS == status) { + nodePtr->currState = PM_PWR_STATE_ON; } - nodePtr->currState = PM_PWR_STATE_ON; - ret = PM_RET_SUCCESS; - done: - return ret; + return status; } /* Children array definitions */ @@ -334,8 +335,8 @@ done: * PmPowerUpTopParent() - Power up top parent in hierarchy that's currently off * @powerChild Power child whose power parent has to be powered up * - * @return Status of the power up operation (always PM_RET_SUCCESS if all - * power parents are already powered on) + * @return Status of the power up operation (XST_SUCCESS if all power + * parents are already powered on) * * This function turns on exactly one power parent, starting with the highest * level parent that's currently off. If all power parents are on, it will @@ -345,13 +346,13 @@ done: * PmTriggerPowerUp that calls this function iteratively until all power * nodes in the hierarchy are powered up. */ -static u32 PmPowerUpTopParent(PmPower* const powerChild) +static int PmPowerUpTopParent(PmPower* const powerChild) { - u32 status = PM_RET_SUCCESS; + int status = XST_SUCCESS; PmPower* powerParent = powerChild; if (NULL == powerParent) { - status = PM_RET_ERROR_INTERNAL; + status = XST_PM_INTERNAL; goto done; } @@ -377,9 +378,9 @@ done: * * @return Status of the power up operation. */ -u32 PmTriggerPowerUp(PmPower* const power) +int PmTriggerPowerUp(PmPower* const power) { - u32 status = PM_RET_SUCCESS; + int status = XST_SUCCESS; if (NULL == power) { goto done; @@ -390,14 +391,16 @@ u32 PmTriggerPowerUp(PmPower* const power) * turned on (always top-down). * Use iterative approach for MISRA-C compliance */ - while ((true == IS_OFF(&power->node)) && (PM_RET_SUCCESS == status)) { + while ((true == IS_OFF(&power->node)) && (XST_SUCCESS == status)) { status = PmPowerUpTopParent(power); } done: - if (PM_RET_SUCCESS != status) { - PmDbg("failed to power up: ERROR #%d\n", status); +#ifdef DEBUG_PM + if (XST_SUCCESS != status) { + PmDbg("ERROR #%d failed to power up\n", status); } +#endif return status; } @@ -485,16 +488,18 @@ static void PmForcePowerDownChildren(const PmPower* const parent) * PmForceDownTree() - Force power down node and all its children * @root power node (island/domain) to turn off * + * @return Operation status of power down procedure + * * This is a power island or power domain, power it off from the bottom up: * find out if this parent has children which themselves have children. * Note: using iterative algorithm for MISRA-C compliance * (instead of recursion) * */ -u32 PmForceDownTree(PmPower* const root) +int PmForceDownTree(PmPower* const root) { + int status = XST_PM_INTERNAL; PmPower* lowestParent; - u32 status = PM_RET_SUCCESS; if (NULL == root) { goto done; @@ -506,7 +511,7 @@ u32 PmForceDownTree(PmPower* const root) if (true == HAS_SLEEP(lowestParent->node.ops)) { status = lowestParent->node.ops->sleep(&lowestParent->node); } - } while ((lowestParent != root) && (status == PM_RET_SUCCESS)); + } while ((lowestParent != root) && (XST_SUCCESS == status)); done: return status; diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_power.h b/lib/sw_apps/zynqmp_pmufw/src/pm_power.h index e7d1e45b..f46986f3 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_power.h +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_power.h @@ -77,7 +77,7 @@ extern PmPower pmPowerDomainFpd_g; * Function declarations ********************************************************************/ void PmOpportunisticSuspend(PmPower* const power); -u32 PmTriggerPowerUp(PmPower* const power); -u32 PmForceDownTree(PmPower* const root); +int PmTriggerPowerUp(PmPower* const power); +int PmForceDownTree(PmPower* const root); #endif diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_proc.c b/lib/sw_apps/zynqmp_pmufw/src/pm_proc.c index 54cec06d..698d8321 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_proc.c +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_proc.c @@ -58,59 +58,54 @@ * @nodePtr Pointer to node-structure of processor to be put to sleep * * @return Operation status - * - PM_RET_SUCCESS if transition succeeded - * - PM_RET_ERROR_FAILURE if pmu rom failed to set the state + * - XST_PM_INTERNAL if processor cannot be identified + * - XST_SUCCESS if processor has no sleep handler (example Rpu0) + * - Returned status by pmu-rom if processor sleep handler is called */ -u32 PmProcSleep(PmNode* const nodePtr) +int PmProcSleep(PmNode* const nodePtr) { - u32 ret; + int status = XST_PM_INTERNAL; if (NULL == nodePtr) { - ret = PM_RET_ERROR_FAILURE; goto done; } /* Call proper PMU-ROM handler as needed */ switch (nodePtr->nodeId) { case NODE_APU_0: - ret = XpbrACPU0SleepHandler(); + status = XpbrACPU0SleepHandler(); break; case NODE_APU_1: - ret = XpbrACPU1SleepHandler(); + status = XpbrACPU1SleepHandler(); break; case NODE_APU_2: - ret = XpbrACPU2SleepHandler(); + status = XpbrACPU2SleepHandler(); break; case NODE_APU_3: - ret = XpbrACPU3SleepHandler(); + status = XpbrACPU3SleepHandler(); break; case NODE_RPU_0: XPfw_RMW32(CRL_APB_RST_LPD_TOP, CRL_APB_RST_LPD_TOP_RPU_R50_RESET_MASK, CRL_APB_RST_LPD_TOP_RPU_R50_RESET_MASK); - ret = PM_RET_SUCCESS; + status = XST_SUCCESS; break; case NODE_RPU_1: XPfw_RMW32(CRL_APB_RST_LPD_TOP, CRL_APB_RST_LPD_TOP_RPU_R51_RESET_MASK, CRL_APB_RST_LPD_TOP_RPU_R51_RESET_MASK); - ret = PM_RET_SUCCESS; + status = XST_SUCCESS; break; default: - ret = PM_RET_ERROR_INTERNAL; break; } - if (XST_SUCCESS != ret) { - ret = PM_RET_ERROR_FAILURE; - goto done; + if (XST_SUCCESS == status) { + nodePtr->currState = PM_PROC_STATE_SLEEP; } - nodePtr->currState = PM_PROC_STATE_SLEEP; - ret = PM_RET_SUCCESS; - done: - return ret; + return status; } /** @@ -118,62 +113,59 @@ done: * @nodePtr Pointer to node-structure of processor to be woken-up * * @return Operation status - * - PM_RET_SUCCESS if transition succeeded - * - PM_RET_ERROR_FAILURE if pmu rom failed to set the state + * - XST_PM_INTERNAL if processor cannot be identified + * - Returned status of power up function if something goes wrong + * - Returned status by pmu-rom if processor wake handler is called */ -u32 PmProcWake(PmNode* const nodePtr) +int PmProcWake(PmNode* const nodePtr) { - u32 ret = PM_RET_SUCCESS; + int status = XST_SUCCESS; if (NULL == nodePtr) { - ret = PM_RET_ERROR_INTERNAL; + status = XST_PM_INTERNAL; goto done; } if (PM_PWR_STATE_OFF == nodePtr->parent->node.currState) { /* Power parent is down, trigger its powering up */ - ret = PmTriggerPowerUp(nodePtr->parent); + status = PmTriggerPowerUp(nodePtr->parent); } - if (PM_RET_SUCCESS != ret) { + if (XST_SUCCESS != status) { goto done; } /* Call proper PMU-ROM handler as needed */ switch (nodePtr->nodeId) { case NODE_APU_0: - ret = XpbrACPU0WakeHandler(); + status = XpbrACPU0WakeHandler(); break; case NODE_APU_1: - ret = XpbrACPU1WakeHandler(); + status = XpbrACPU1WakeHandler(); break; case NODE_APU_2: - ret = XpbrACPU2WakeHandler(); + status = XpbrACPU2WakeHandler(); break; case NODE_APU_3: - ret = XpbrACPU3WakeHandler(); + status = XpbrACPU3WakeHandler(); break; case NODE_RPU_0: - ret = XpbrRstR50Handler(); + status = XpbrRstR50Handler(); break; case NODE_RPU_1: - ret = XpbrRstR51Handler(); + status = XpbrRstR51Handler(); break; default: - ret = XST_SUCCESS; + status = XST_PM_INTERNAL; break; } - if (XST_SUCCESS != ret) { - ret = PM_RET_ERROR_FAILURE; - goto done; + if (XST_SUCCESS == status) { + nodePtr->currState = PM_PROC_STATE_ACTIVE; } - nodePtr->currState = PM_PROC_STATE_ACTIVE; - ret = PM_RET_SUCCESS; - done: - return ret; + return status; } /** @@ -181,18 +173,18 @@ done: * @proc Pointer to processor whose FSM is changing state * * @return Operation status - * - PM_RET_SUCCESS is always returned as this transition cannot fail + * - XST_SUCCESS is always returned as this transition cannot fail * * @note Executes when processor's request for self suspend gets processed. */ -static u32 PmProcTrActiveToSuspend(PmProc* const proc) +static int PmProcTrActiveToSuspend(PmProc* const proc) { PmDbg("ACTIVE->SUSPENDING %s\n", PmStrNode(proc->node.nodeId)); ENABLE_WFI(proc->wfiEnableMask); proc->node.currState = PM_PROC_STATE_SUSPENDING; - return PM_RET_SUCCESS; + return XST_SUCCESS; } /** @@ -201,10 +193,6 @@ static u32 PmProcTrActiveToSuspend(PmProc* const proc) * @proc Pointer to processor whose FSM is changing state * * @return Operation status - * - PM_RET_SUCCESS if transition succeeded - * - PM_RET_ERROR_FAILURE if pmu rom failed to set the state - * - PM_RET_ERROR_INTERNAL if processor structures are incorrectly - * initialized * * @note Executes when some other processor authorized to do so requests * through PM API the PMU to powered down this processor. This @@ -213,7 +201,7 @@ static u32 PmProcTrActiveToSuspend(PmProc* const proc) * no implemented sleep function it will continue executing * instructions. */ -static u32 PmProcTrToForcedOff(PmProc* const proc) +static int PmProcTrToForcedOff(PmProc* const proc) { u32 status; @@ -222,9 +210,9 @@ static u32 PmProcTrToForcedOff(PmProc* const proc) status = PmProcSleep(&proc->node); /* Override the state set in PmProcSleep to indicate FORCED OFF */ proc->node.currState = PM_PROC_STATE_FORCEDOFF; - if (true == proc->isPrimary) { + if ((true == proc->isPrimary) && (XST_SUCCESS == status)) { /* Notify master to release all requirements of this processor */ - PmMasterNotify(proc->master, PM_PROC_EVENT_FORCE_PWRDN); + status = PmMasterNotify(proc->master, PM_PROC_EVENT_FORCE_PWRDN); } return status; @@ -234,23 +222,24 @@ static u32 PmProcTrToForcedOff(PmProc* const proc) * PmProcTrSuspendToActive() - FSM transition from suspend to active state * @proc Pointer to processor whose FSM is changing state * - * @return Operation status - * - PM_RET_SUCCESS is always returned as this transition cannot fail + * @return Operation status (should be always success) * * @note Executes when processor requests abort suspend through PM API. */ -static u32 PmProcTrSuspendToActive(PmProc* const proc) +static int PmProcTrSuspendToActive(PmProc* const proc) { + int status; + PmDbg("SUSPENDING->ACTIVE %s\n", PmStrNode(proc->node.nodeId)); DISABLE_WFI(proc->wfiEnableMask); DISABLE_WAKE(proc->wakeEnableMask); /* Notify master to cancel scheduled requests */ - PmMasterNotify(proc->master, PM_PROC_EVENT_ABORT_SUSPEND); + status = PmMasterNotify(proc->master, PM_PROC_EVENT_ABORT_SUSPEND); proc->node.currState = PM_PROC_STATE_ACTIVE; - return PM_RET_SUCCESS; + return status; } /** @@ -258,27 +247,23 @@ static u32 PmProcTrSuspendToActive(PmProc* const proc) * @proc Pointer to processor whose FSM is changing state * * @return Operation status - * - PM_RET_SUCCESS if transition succeeded - * - PM_RET_ERROR_FAILURE if pmu rom failed to set the state - * - PM_RET_ERROR_INTERNAL if processor structures are incorrectly - * initialized * * @note Processor had previously called self suspend and now PMU has * received processor's wfi interrupt. */ -static u32 PmProcTrSuspendToSleep(PmProc* const proc) +static int PmProcTrSuspendToSleep(PmProc* const proc) { - u32 status; + int status; PmDbg("SUSPENDING->SLEEP %s\n", PmStrNode(proc->node.nodeId)); status = PmProcSleep(&proc->node); - if (true == proc->isPrimary) { + if ((true == proc->isPrimary) && (XST_SUCCESS == status)) { /* * Notify master to update slave capabilities according to the * scheduled requests for after primary processor goes to sleep. */ - PmMasterNotify(proc->master, PM_PROC_EVENT_SLEEP); + status = PmMasterNotify(proc->master, PM_PROC_EVENT_SLEEP); } DISABLE_WFI(proc->wfiEnableMask); ENABLE_WAKE(proc->wakeEnableMask); @@ -291,36 +276,31 @@ static u32 PmProcTrSuspendToSleep(PmProc* const proc) * @proc Pointer to processor whose FSM is changing state * * @return Operation status - * - PM_RET_SUCCESS if transition succeeded - * - PM_RET_ERROR_FAILURE if pmu rom failed to set the state - * - PM_RET_ERROR_INTERNAL if processor structures are incorrectly - * initialized * * @note Processor had previously called self suspend and before it had * executed wfi PMU has received PM API request to force power down * of this processor. Therefore, PMU does not wait for wfi interrupt * from this processor to come, but puts it to sleep. */ -static u32 PmProcTrSleepToActive(PmProc* const proc) +static int PmProcTrSleepToActive(PmProc* const proc) { - u32 status; + int status = XST_SUCCESS; if (true == proc->isPrimary) { /* * Notify master to update slave capabilities according to the - * scheduled requests for before the primary processor - * gets woken-up. + * scheduled requests for before the primary processor gets + * woken-up. */ - PmMasterNotify(proc->master, PM_PROC_EVENT_WAKE); + status = PmMasterNotify(proc->master, PM_PROC_EVENT_WAKE); + } + if (XST_SUCCESS == status) { + PmDbg("SLEEP->ACTIVE %s\n", PmStrNode(proc->node.nodeId)); + status = PmProcWake(&proc->node); + /* Keep wfi interrupt disabled while processor is active */ + DISABLE_WFI(proc->wfiEnableMask); + DISABLE_WAKE(proc->wakeEnableMask); } - - PmDbg("SLEEP->ACTIVE %s\n", PmStrNode(proc->node.nodeId)); - - status = PmProcWake(&proc->node); - - /* Keep wfi interrupt disabled while processor is active */ - DISABLE_WFI(proc->wfiEnableMask); - DISABLE_WAKE(proc->wakeEnableMask); return status; } @@ -331,17 +311,15 @@ static u32 PmProcTrSleepToActive(PmProc* const proc) * @proc Pointer to processor whose FSM is changing state * * @return Operation status - * - PM_RET_SUCCESS if transition succeeded - * - PM_RET_ERROR_FAILURE if pmu rom failed to set the state - * - PM_RET_ERROR_INTERNAL if processor does not have wake function * * @note Processor had previously called self suspend and before it had * executed wfi PMU has received PM API request to force power down * of this processor. Therefore, PMU does not wait for wfi interrupt * from this processor to come, but puts it to sleep. */ -static u32 PmProcTrForcePwrdnToActive(PmProc* const proc) +static int PmProcTrForcePwrdnToActive(PmProc* const proc) { + int status = XST_SUCCESS; PmDbg("FORCED_PWRDN->ACTIVE %s\n", PmStrNode(proc->node.nodeId)); if (true == proc->isPrimary) { @@ -350,10 +328,13 @@ static u32 PmProcTrForcePwrdnToActive(PmProc* const proc) * scheduled requests. For waking-up from forced powerdown, * these requirements are always only default requirements. */ - PmMasterNotify(proc->master, PM_PROC_EVENT_WAKE); + status = PmMasterNotify(proc->master, PM_PROC_EVENT_WAKE); + } + if (XST_SUCCESS == status) { + status = PmProcWake(&proc->node); } - return PmProcWake(&proc->node); + return status; } /** @@ -361,22 +342,20 @@ static u32 PmProcTrForcePwrdnToActive(PmProc* const proc) * @proc Pointer to the processor the event is for * @event Processor-specific event to act upon * + * @return Status of the processor state change operation + * * @note This FSM coordinates the state transitions for an individual * processor. */ -u32 PmProcFsm(PmProc* const proc, const PmProcEvent event) +int PmProcFsm(PmProc* const proc, const PmProcEvent event) { - u32 status = PM_RET_SUCCESS; - u32 currState = proc->node.currState; + int status = XST_PM_INTERNAL; + PmStateId currState = proc->node.currState; switch (event) { case PM_PROC_EVENT_SELF_SUSPEND: if (PM_PROC_STATE_ACTIVE == currState) { status = PmProcTrActiveToSuspend(proc); - } else { - PmDbg("ERROR: illegal state %d for SUSPEND event\n", - currState); - status = PM_RET_ERROR_INTERNAL; } break; case PM_PROC_EVENT_FORCE_PWRDN: @@ -388,19 +367,11 @@ u32 PmProcFsm(PmProc* const proc, const PmProcEvent event) case PM_PROC_EVENT_ABORT_SUSPEND: if (PM_PROC_STATE_SUSPENDING == currState) { status = PmProcTrSuspendToActive(proc); - } else { - PmDbg("ERROR: illegal state %d for ABORT event\n", - currState); - status = PM_RET_ERROR_INTERNAL; } break; case PM_PROC_EVENT_SLEEP: if (PM_PROC_STATE_SUSPENDING == currState) { status = PmProcTrSuspendToSleep(proc); - } else { - PmDbg("ERROR: illegal state %d for SLEEP event\n", - currState); - status = PM_RET_ERROR_INTERNAL; } break; case PM_PROC_EVENT_WAKE: @@ -409,16 +380,17 @@ u32 PmProcFsm(PmProc* const proc, const PmProcEvent event) } else if (PM_PROC_STATE_FORCEDOFF == currState) { status = PmProcTrForcePwrdnToActive(proc); } else { - PmDbg("ERROR: illegal state %d for WAKE event\n", - currState); - status = PM_RET_ERROR_INTERNAL; } break; default: PmDbg("ERROR: unrecognized event %d\n", event); - status = PM_RET_ERROR_INTERNAL; break; } +#ifdef DEBUG_PM + if (status == XST_PM_INTERNAL) { + PmDbg("ERROR: state #%d event #%d\n", currState, event); + } +#endif return status; } diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_proc.h b/lib/sw_apps/zynqmp_pmufw/src/pm_proc.h index 9003fa4f..255abaa0 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_proc.h +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_proc.h @@ -135,6 +135,6 @@ extern PmProc pmRpuProcs_g[PM_PROC_RPU_MAX]; /********************************************************************* * Function declarations ********************************************************************/ -u32 PmProcFsm(PmProc* const proc, const PmProcEvent event); +int PmProcFsm(PmProc* const proc, const PmProcEvent event); #endif diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_slave.c b/lib/sw_apps/zynqmp_pmufw/src/pm_slave.c index bbc08722..1fca2be3 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_slave.c +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_slave.c @@ -130,23 +130,24 @@ static u32 PmGetMaxCapabilities(const PmSlave* const slave) } /** - * PmCheckCapabilities() - Check whether the slave has given capabilities + * PmCheckCapabilities() - Check whether the slave has state with specified + * capabilities * @slave Slave pointer whose capabilities/states should be checked * @cap Check for these capabilities * - * @return Status does slave have a state with given capabilities. - * - PM_RET_SUCCESS - slave has state with given capabilities - * - PM_RET_ERROR_NOTSUPPORTED - slave does not have such state + * @return Status wheter slave has a state with given capabilities + * - XST_SUCCESS if slave has state with given capabilities + * - XST_NO_FEATURE if slave does not have such state */ -u32 PmCheckCapabilities(PmSlave* const slave, const u32 cap) +int PmCheckCapabilities(PmSlave* const slave, const u32 cap) { PmStateId i; - u32 status = PM_RET_ERROR_NOTSUPPORTED; + int status = XST_NO_FEATURE; for (i = 0; i < slave->slvFsm->statesCnt; i++) { /* Find the first state that contains all capabilities */ if ((cap & slave->slvFsm->states[i]) == cap) { - status = PM_RET_SUCCESS; + status = XST_SUCCESS; break; } } @@ -159,13 +160,13 @@ u32 PmCheckCapabilities(PmSlave* const slave, const u32 cap) * @slave Slave pointer whose state should be changed * @state New state * - * @return PM_RET_SUCCESS if transition was performed successfully - * error otherwise + * @return XST_SUCCESS if transition was performed successfully. + * Error otherwise. */ -static u32 PmSlaveChangeState(PmSlave* const slave, const PmStateId state) +static int PmSlaveChangeState(PmSlave* const slave, const PmStateId state) { u32 t; - u32 status; + int status; const PmSlaveFsm* fsm = slave->slvFsm; #ifdef DEBUG_PM PmStateId oldState = slave->node.currState; @@ -173,13 +174,13 @@ static u32 PmSlaveChangeState(PmSlave* const slave, const PmStateId state) if (0U == fsm->transCnt) { /* Slave's FSM has no transitions when it has only one state */ - status = PM_RET_SUCCESS; + status = XST_SUCCESS; } else { /* * Slave has transitions to change the state. Assume the failure * and change status if state is changed correctly. */ - status = PM_RET_ERROR_FAILURE; + status = XST_FAILURE; } for (t = 0U; t < fsm->transCnt; t++) { @@ -197,13 +198,13 @@ static u32 PmSlaveChangeState(PmSlave* const slave, const PmStateId state) * Slave's FSM has no actions, because it has no private * properties to be controlled here. */ - status = PM_RET_SUCCESS; + status = XST_SUCCESS; } break; } #ifdef DEBUG_PM - if (PM_RET_SUCCESS == status) { + if (XST_SUCCESS == status) { PmDbg("%s %d->%d\n", PmStrNode(slave->node.nodeId), oldState, slave->node.currState); } else { @@ -221,11 +222,11 @@ static u32 PmSlaveChangeState(PmSlave* const slave, const PmStateId state) * * @return Status of operation */ -u32 PmUpdateSlave(PmSlave* const slave) +int PmUpdateSlave(PmSlave* const slave) { PmStateId s; const PmSlaveFsm* fsm = slave->slvFsm; - u32 status = PM_RET_ERROR_NOTSUPPORTED; + int status = XST_FAILURE; u32 capsToSet = PmGetMaxCapabilities(slave); if (0U != capsToSet) { @@ -234,7 +235,7 @@ u32 PmUpdateSlave(PmSlave* const slave) if ((capsToSet & fsm->states[s]) == capsToSet) { if (s == slave->node.currState) { /* Slave is already in right state */ - status = PM_RET_SUCCESS; + status = XST_SUCCESS; } else { status = PmSlaveChangeState(slave, s); } @@ -259,22 +260,37 @@ u32 PmUpdateSlave(PmSlave* const slave) * @slave Pointer to a slave whose masters has to be woken-up (if master has * requested this slave as wake-up source before going to sleep) * + * @return Return status of waking up processors + * * @note: Wake event of this slave is disabled together with all other slaves * as part of the wake-up sequence. */ -static void PmSlaveWakeMasters(PmSlave* const slave) +static int PmSlaveWakeMasters(PmSlave* const slave) { PmMasterId i; + int status; + int totalSt = XST_SUCCESS; for (i = 0U; i < slave->reqsCnt; i++) { if (slave->reqs[i]->info & PM_MASTER_WAKEUP_REQ_MASK) { - slave->reqs[i]->info &= ~PM_MASTER_WAKEUP_REQ_MASK; PmDbg("%s->%s\n", PmStrNode(slave->node.nodeId), PmStrNode(slave->reqs[i]->requestor->procs->node.nodeId)); - PmProcFsm(slave->reqs[i]->requestor->procs, PM_PROC_EVENT_WAKE); + + slave->reqs[i]->info &= ~PM_MASTER_WAKEUP_REQ_MASK; + status = PmProcFsm(slave->reqs[i]->requestor->procs, + PM_PROC_EVENT_WAKE); + if (XST_SUCCESS != status) { + /* + * Failed waking up processor, remember + * failure and try to wake-up others + */ + totalSt = status; + } } } PmSlaveWakeDisable(slave); + + return totalSt; } /** @@ -290,9 +306,10 @@ static void PmSlaveWakeMasters(PmSlave* const slave) * clears the interrupt, meaning that there could be up to 31 irqs * that would be lost if not handled immediately. */ -void PmSlaveProcessWake(const u32 wakeMask) +int PmSlaveProcessWake(const u32 wakeMask) { - u32 g; + int status = XST_SUCCESS; + u32 g, s, irqStatus; if (!(PMU_LOCAL_GPI1_ENABLE_FPD_WAKE_GIC_PROX_MASK & wakeMask)) { goto done; @@ -300,21 +317,21 @@ void PmSlaveProcessWake(const u32 wakeMask) for (g = 0U; g < ARRAY_SIZE(gicProxyGroups_g); g++) { /* Reading status register clears interrupts */ - u32 s; - u32 irqStatus = XPfw_Read32(gicProxyGroups_g[g].baseAddr + - FPD_GICP_STATUS_OFFSET); + irqStatus = XPfw_Read32(gicProxyGroups_g[g].baseAddr + + FPD_GICP_STATUS_OFFSET); for (s = 0U; (0U != irqStatus) && (s < ARRAY_SIZE(pmSlaves)); s++) { if ((NULL != pmSlaves[s]->wake) && (pmSlaves[s]->wake->proxyIrqMask & irqStatus)) { - PmSlaveWakeMasters(pmSlaves[s]); + status = PmSlaveWakeMasters(pmSlaves[s]); irqStatus &= ~pmSlaves[s]->wake->proxyIrqMask; + } } } done: - return; + return status; } /** diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_slave.h b/lib/sw_apps/zynqmp_pmufw/src/pm_slave.h index a2e85885..915b3067 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_slave.h +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_slave.h @@ -45,8 +45,8 @@ typedef struct PmMaster PmMaster; typedef struct PmRequirement PmRequirement; typedef struct PmSlave PmSlave; -typedef u32 (*const PmSlaveFsmHandler)(PmSlave* const slave, - const PmStateId nextState); +typedef int (*const PmSlaveFsmHandler)(PmSlave* const slave, + const PmStateId nextState); /********************************************************************* * Macros @@ -165,12 +165,12 @@ extern PmGicProxyProperties gicProxyGroups_g[FPD_GICP_GROUP_MAX]; /********************************************************************* * Function declarations ********************************************************************/ -u32 PmUpdateSlave(PmSlave* const slave); -u32 PmCheckCapabilities(PmSlave* const slave, const u32 capabilities); +int PmUpdateSlave(PmSlave* const slave); +int PmCheckCapabilities(PmSlave* const slave, const u32 capabilities); bool PmSlaveHasCapRequests(const PmSlave* const slave); -void PmSlaveProcessWake(const u32 wakeMask); +int PmSlaveProcessWake(const u32 wakeMask); void PmSlaveWakeEnable(PmSlave* const slave); void PmSlaveWakeDisable(PmSlave* const slave); diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_sram.c b/lib/sw_apps/zynqmp_pmufw/src/pm_sram.c index 4049a8a6..131d2044 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_sram.c +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_sram.c @@ -68,9 +68,9 @@ static const PmStateTran pmSramTransitions[] = { * * @return Status of performing transition action */ -static u32 PmSramFsmHandler(PmSlave* const slave, const PmStateId nextState) +static int PmSramFsmHandler(PmSlave* const slave, const PmStateId nextState) { - u32 status = PM_RET_ERROR_INTERNAL; + int status = XST_PM_INTERNAL; PmSlaveSram* sram = (PmSlaveSram*)slave->node.derived; switch (slave->node.currState) { @@ -84,6 +84,7 @@ static u32 PmSramFsmHandler(PmSlave* const slave, const PmStateId nextState) /* ON -> OFF*/ status = sram->PwrDn(); } else { + status = XST_NO_FEATURE; } break; case PM_SRAM_STATE_RET: @@ -96,24 +97,27 @@ static u32 PmSramFsmHandler(PmSlave* const slave, const PmStateId nextState) /* RET -> OFF */ status = sram->PwrDn(); } else { + status = XST_NO_FEATURE; } break; case PM_SRAM_STATE_OFF: if (PM_SRAM_STATE_ON == nextState) { /* OFF -> ON */ status = sram->PwrUp(); + } else { + status = XST_NO_FEATURE; } break; default: + status = XST_PM_INTERNAL; + PmDbg("ERROR: Unknown SRAM state #%d\n", slave->node.currState); break; } - if (status == XST_SUCCESS) { + if (XST_SUCCESS == status) { slave->node.currState = nextState; - status = PM_RET_SUCCESS; - } else { - status = PM_RET_ERROR_FAILURE; } + return status; } diff --git a/lib/sw_apps/zynqmp_pmufw/src/pm_usb.c b/lib/sw_apps/zynqmp_pmufw/src/pm_usb.c index e3ea4c64..7c20f9a7 100644 --- a/lib/sw_apps/zynqmp_pmufw/src/pm_usb.c +++ b/lib/sw_apps/zynqmp_pmufw/src/pm_usb.c @@ -61,32 +61,37 @@ static const PmStateTran pmUsbTransitions[] = { * * @return Status of performing transition action */ -static u32 PmUsbFsmHandler(PmSlave* const slave, const PmStateId nextState) +static int PmUsbFsmHandler(PmSlave* const slave, const PmStateId nextState) { - u32 status = PM_RET_ERROR_INTERNAL; + int status = XST_PM_INTERNAL; PmSlaveUsb* usb = (PmSlaveUsb*)slave->node.derived; + switch (slave->node.currState) { case PM_USB_STATE_ON: if (PM_USB_STATE_OFF == nextState) { /* ON -> OFF*/ status = usb->PwrDn(); + } else { + status = XST_NO_FEATURE; } break; case PM_USB_STATE_OFF: if (PM_USB_STATE_ON == nextState) { /* OFF -> ON */ status = usb->PwrUp(); + } else { + status = XST_NO_FEATURE; } break; default: + status = XST_PM_INTERNAL; + PmDbg("ERROR: Unknown USB state #%d\n", slave->node.currState); break; } - if (status == XST_SUCCESS) { + if (XST_SUCCESS == status) { slave->node.currState = nextState; - status = PM_RET_SUCCESS; - } else { - status = PM_RET_ERROR_FAILURE; } + return status; } diff --git a/lib/sw_apps/zynqmp_pmufw/src/xpfw_version.h b/lib/sw_apps/zynqmp_pmufw/src/xpfw_version.h index c8135276..71fb110a 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-29-g7f18eaf0130e" + #define ZYNQMP_XPFW_VERSION "2015.1-swbeta2-30-g61a804cc37eb" #endif