diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c index 0a43cc49..f9006e79 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c @@ -788,29 +788,6 @@ u32 XFsbl_Handoff (XFsblPs * FsblInstancePtr, u32 PartitionNum, u32 EarlyHandoff goto END; } - /* If PMU FW is present then handoff it to PMU MicroBlaze */ - NoOfPartitions = - FsblInstancePtr->ImageHeader.ImageHeaderTable.NoOfPartitions; - for (PartitionIndex = 0; - PartitionIndex < NoOfPartitions; PartitionIndex++) - { - PartitionAttributes = FsblInstancePtr->ImageHeader. - PartitionHeader[PartitionIndex].PartitionAttributes; - if ((PartitionAttributes & XIH_PH_ATTRB_DEST_DEVICE_MASK) - == XIH_PH_ATTRB_DEST_DEVICE_PMU) - { - /* Wakeup the processor */ - XFsbl_Out32(PMU_GLOBAL_GLOBAL_CNTRL, - XFsbl_In32(PMU_GLOBAL_GLOBAL_CNTRL) | 0x1); - - /* wait until done waking up */ - while((XFsbl_In32(PMU_GLOBAL_GLOBAL_CNTRL) & - PMU_GLOBAL_GLOBAL_CNTRL_MB_SLEEP_MASK) == - PMU_GLOBAL_GLOBAL_CNTRL_MB_SLEEP_MASK ) {;} - } - - } - /** * Disable Data Cache to have smooth data * transfer between the processors. diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c index 7608b243..48753786 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c @@ -84,6 +84,7 @@ static u32 XFsbl_ConfigureMemory(u32 RunningCpu, u32 DestinationCpu, u64 Address, u32 Length); void XFsbl_EccInitialize(u32 Address, u32 Length); u32 XFsbl_GetLoadAddress(u32 DestinationCpu, u64 * LoadAddressPtr, u32 Length); +static void XFsbl_CheckPmuFw(XFsblPs * FsblInstancePtr, u32 PartitionNum); /************************** Variable Definitions *****************************/ static int IsR50TcmEccInitialized = FALSE; @@ -155,6 +156,9 @@ u32 XFsbl_PartitionLoad(XFsblPs * FsblInstancePtr, u32 PartitionNum) goto END; } + /* Check if PMU FW load is done and handoff it to Microblaze */ + XFsbl_CheckPmuFw(FsblInstancePtr, PartitionNum); + END: return Status; } @@ -1224,7 +1228,8 @@ static u32 XFsbl_PartitionValidation(XFsblPs * FsblInstancePtr, /** * Update the handoff details */ - if(DestinationDevice != XIH_PH_ATTRB_DEST_DEVICE_PL) + if ((DestinationDevice != XIH_PH_ATTRB_DEST_DEVICE_PL) && + (DestinationDevice != XIH_PH_ATTRB_DEST_DEVICE_PMU)) { CpuNo = FsblInstancePtr->HandoffCpuNo; if (XFsbl_CheckHandoffCpu(FsblInstancePtr, @@ -1241,3 +1246,59 @@ static u32 XFsbl_PartitionValidation(XFsblPs * FsblInstancePtr, END: return Status; } + +/*****************************************************************************/ +/** + * This function checks if PMU FW is loaded and gives handoff to PMU Microblaze + * + * @param FsblInstancePtr is pointer to the XFsbl Instance + * + * @param PartitionNum is the partition number of the image + * + * @return None + * + *****************************************************************************/ +static void XFsbl_CheckPmuFw(XFsblPs * FsblInstancePtr, u32 PartitionNum) +{ + + u32 DestinationDev; + u32 DestinationDevNxt = 0; + u32 PmuFwLoadDone = FALSE; + + DestinationDev = XFsbl_GetDestinationDevice( + &FsblInstancePtr->ImageHeader.PartitionHeader[PartitionNum]); + + if (DestinationDev == XIH_PH_ATTRB_DEST_DEVICE_PMU) { + if ((PartitionNum + 1) < + (FsblInstancePtr-> + ImageHeader.ImageHeaderTable.NoOfPartitions-1U)) { + DestinationDevNxt = XFsbl_GetDestinationDevice( + &FsblInstancePtr-> + ImageHeader.PartitionHeader[PartitionNum + 1]); + if (DestinationDevNxt != XIH_PH_ATTRB_DEST_DEVICE_PMU) { + /* there is a partition after this but that is not PMU FW */ + PmuFwLoadDone = TRUE; + } + } + else + { + /* the current partition is last PMU FW partition */ + PmuFwLoadDone = TRUE; + } + } + + /* If all partitions of PMU FW loaded, handoff it to PMU MicroBlaze */ + if (TRUE == PmuFwLoadDone) + { + /* Wakeup the processor */ + XFsbl_Out32(PMU_GLOBAL_GLOBAL_CNTRL, + XFsbl_In32(PMU_GLOBAL_GLOBAL_CNTRL) | 0x1); + + /* wait until done waking up */ + while((XFsbl_In32(PMU_GLOBAL_GLOBAL_CNTRL) & + PMU_GLOBAL_GLOBAL_CNTRL_FW_IS_PRESENT_MASK) != + PMU_GLOBAL_GLOBAL_CNTRL_FW_IS_PRESENT_MASK ) {;} + + } + +}