diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_bs.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_bs.c index e171451f..0456e5ae 100755 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_bs.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_bs.c @@ -87,32 +87,12 @@ u32 XFsbl_PcapInit(void) { XFsbl_Out32(CSU_PCAP_CTRL, RegVal); XFsbl_Out32(CSU_PCAP_RDWR, 0x0); - /* If PL not powered up yet, do it now */ - RegVal = XFsbl_In32(PMU_GLOBAL_PWR_STATE); - if ((RegVal & PMU_GLOBAL_PWR_STATE_PL_MASK) != - PMU_GLOBAL_PWR_STATE_PL_MASK) { - /* Power up request enable */ - RegVal = XFsbl_In32(PMU_GLOBAL_REQ_PWRUP_INT_EN); - RegVal |= PMU_GLOBAL_REQ_PWRUP_INT_EN_PL_MASK; - XFsbl_Out32(PMU_GLOBAL_REQ_PWRUP_INT_EN, RegVal); + Status = XFsbl_PowerUpIsland(PMU_GLOBAL_PWR_STATE_PL_MASK); - /* Trigger power up request */ - RegVal = XFsbl_In32(PMU_GLOBAL_REQ_PWRUP_TRIG); - RegVal |= PMU_GLOBAL_REQ_PWRUP_TRIG_PL_MASK; - XFsbl_Out32(PMU_GLOBAL_REQ_PWRUP_TRIG, RegVal); - - /* Poll for Power up complete */ - do { - RegVal = XFsbl_In32(PMU_GLOBAL_REQ_PWRUP_STATUS) & - PMU_GLOBAL_REQ_PWRUP_STATUS_PL_MASK; - } while (RegVal != PMU_GLOBAL_REQ_PWRUP_STATUS_PL_MASK); - - if ((RegVal & PMU_GLOBAL_PWR_STATE_PL_MASK) != - PMU_GLOBAL_PWR_STATE_PL_MASK) { - Status = XFSBL_ERROR_PL_POWER_ISOLATION; - XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_PL_POWER_ISOLATION\r\n"); + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_PL_POWER_UP; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_PL_POWER_UP\r\n"); goto END; - } } /* Reset PL */ diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_error.h b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_error.h index 2d45901d..97514bc4 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_error.h +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_error.h @@ -155,7 +155,17 @@ extern "C" { #define XFSBL_ERROR_RSA_NOT_ENABLED (0x3BU) #define XFSBL_ERROR_AES_NOT_ENABLED (0x3CU) #define XFSBL_ERROR_PL_NOT_ENABLED (0x3DU) -#define XFSBL_ERROR_PL_POWER_ISOLATION (0x3EU) +#define XFSBL_ERROR_PL_POWER_UP (0x3EU) +#define XFSBL_ERROR_A53_0_POWER_UP (0x3FU) +#define XFSBL_ERROR_A53_1_POWER_UP (0x40U) +#define XFSBL_ERROR_A53_2_POWER_UP (0x41U) +#define XFSBL_ERROR_A53_3_POWER_UP (0x42U) +#define XFSBL_ERROR_R5_0_POWER_UP (0x43U) +#define XFSBL_ERROR_R5_1_POWER_UP (0x44U) +#define XFSBL_ERROR_R5_L_POWER_UP (0x45U) +#define XFSBL_ERROR_R5_0_TCM_POWER_UP (0x46U) +#define XFSBL_ERROR_R5_1_TCM_POWER_UP (0x47U) +#define XFSBL_ERROR_R5_L_TCM_POWER_UP (0x48U) #define XFSBL_FAILURE (0x3FFU) diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c index 362b68d2..8797c884 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_handoff.c @@ -143,6 +143,7 @@ static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags) u32 Status=XFSBL_SUCCESS; u32 CpuId=0U; u32 ExecState=0U; + u32 PwrStateMask = 0; CpuId = CpuSettings & XIH_PH_ATTRB_DEST_CPU_MASK; ExecState = CpuSettings & XIH_PH_ATTRB_A53_EXEC_ST_MASK; @@ -157,6 +158,17 @@ static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags) case XIH_PH_ATTRB_DEST_CPU_A53_0: + PwrStateMask = PMU_GLOBAL_PWR_STATE_ACPU0_MASK | + PMU_GLOBAL_PWR_STATE_FP_MASK | + PMU_GLOBAL_PWR_STATE_L2_BANK0_MASK; + + Status = XFsbl_PowerUpIsland(PwrStateMask); + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_A53_0_POWER_UP; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_A53_0_POWER_UP\r\n"); + goto END; + } + /** * Set to Aarch32 if enabled */ @@ -187,6 +199,18 @@ static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags) break; case XIH_PH_ATTRB_DEST_CPU_A53_1: + + PwrStateMask = PMU_GLOBAL_PWR_STATE_ACPU1_MASK | + PMU_GLOBAL_PWR_STATE_FP_MASK | + PMU_GLOBAL_PWR_STATE_L2_BANK0_MASK; + + Status = XFsbl_PowerUpIsland(PwrStateMask); + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_A53_1_POWER_UP; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_A53_1_POWER_UP\r\n"); + goto END; + } + /** * Set to Aarch32 if enabled */ @@ -217,6 +241,18 @@ static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags) break; case XIH_PH_ATTRB_DEST_CPU_A53_2: + + PwrStateMask = PMU_GLOBAL_PWR_STATE_ACPU2_MASK | + PMU_GLOBAL_PWR_STATE_FP_MASK | + PMU_GLOBAL_PWR_STATE_L2_BANK0_MASK; + + Status = XFsbl_PowerUpIsland(PwrStateMask); + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_A53_2_POWER_UP; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_A53_2_POWER_UP\r\n"); + goto END; + } + /** * Set to Aarch32 if enabled */ @@ -248,6 +284,19 @@ static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags) break; case XIH_PH_ATTRB_DEST_CPU_A53_3: + + PwrStateMask = PMU_GLOBAL_PWR_STATE_ACPU3_MASK | + PMU_GLOBAL_PWR_STATE_FP_MASK | + PMU_GLOBAL_PWR_STATE_L2_BANK0_MASK; + + Status = XFsbl_PowerUpIsland(PwrStateMask); + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_A53_3_POWER_UP; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_A53_3_POWER_UP\r\n"); + goto END; + } + + /** * Set to Aarch32 if enabled */ @@ -279,6 +328,14 @@ static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags) break; case XIH_PH_ATTRB_DEST_CPU_R5_0: + + Status = XFsbl_PowerUpIsland(PMU_GLOBAL_PWR_STATE_R5_0_MASK); + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_R5_0_POWER_UP; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_R5_0_POWER_UP\r\n"); + goto END; + } + /** * Place R5, TCM's in split mode */ @@ -328,6 +385,14 @@ static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags) break; case XIH_PH_ATTRB_DEST_CPU_R5_1: + + Status = XFsbl_PowerUpIsland(PMU_GLOBAL_PWR_STATE_R5_1_MASK); + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_R5_1_POWER_UP; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_R5_1_POWER_UP\r\n"); + goto END; + } + /** * Place R5, TCM's in split mode */ @@ -375,6 +440,14 @@ static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags) XFsbl_Out32(RPU_RPU_1_CFG, RegValue); break; case XIH_PH_ATTRB_DEST_CPU_R5_L: + + Status = XFsbl_PowerUpIsland(PMU_GLOBAL_PWR_STATE_R5_0_MASK); + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_R5_L_POWER_UP; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_R5_L_POWER_UP\r\n"); + goto END; + } + /** * Place R5, TCM's in safe mode */ @@ -445,7 +518,7 @@ static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags) } } - +END: return Status; } diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h index cc25b6ea..71542c51 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h @@ -320,6 +320,27 @@ extern "C" { /* Register: PMU_GLOBAL_PWR_STATE */ #define PMU_GLOBAL_PWR_STATE ( ( PMU_GLOBAL_BASEADDR ) + 0X00000100U ) #define PMU_GLOBAL_PWR_STATE_PL_MASK 0X00800000U +#define PMU_GLOBAL_PWR_STATE_FP_MASK 0X00400000U +#define PMU_GLOBAL_PWR_STATE_USB1_MASK 0X00200000U +#define PMU_GLOBAL_PWR_STATE_USB0_MASK 0X00100000U +#define PMU_GLOBAL_PWR_STATE_OCM_BANK3_MASK 0X00080000U +#define PMU_GLOBAL_PWR_STATE_OCM_BANK2_MASK 0X00040000U +#define PMU_GLOBAL_PWR_STATE_OCM_BANK1_MASK 0X00020000U +#define PMU_GLOBAL_PWR_STATE_OCM_BANK0_MASK 0X00010000U +#define PMU_GLOBAL_PWR_STATE_TCM1B_MASK 0X00008000U +#define PMU_GLOBAL_PWR_STATE_TCM1A_MASK 0X00004000U +#define PMU_GLOBAL_PWR_STATE_TCM0B_MASK 0X00002000U +#define PMU_GLOBAL_PWR_STATE_TCM0A_MASK 0X00001000U +#define PMU_GLOBAL_PWR_STATE_R5_1_MASK 0X00000800U +#define PMU_GLOBAL_PWR_STATE_R5_0_MASK 0X00000400U +#define PMU_GLOBAL_PWR_STATE_L2_BANK0_MASK 0X00000080U +#define PMU_GLOBAL_PWR_STATE_PP1_MASK 0X00000020U +#define PMU_GLOBAL_PWR_STATE_PP0_MASK 0X00000010U +#define PMU_GLOBAL_PWR_STATE_ACPU3_MASK 0X00000008U +#define PMU_GLOBAL_PWR_STATE_ACPU2_MASK 0X00000004U +#define PMU_GLOBAL_PWR_STATE_ACPU1_MASK 0X00000002U +#define PMU_GLOBAL_PWR_STATE_ACPU0_MASK 0X00000001U + /* rpu */ diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc.c index bb953456..05645295 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc.c @@ -481,3 +481,55 @@ void XFsbl_RegisterHandlers(void) (Xil_ExceptionHandler)XFsbl_FiqHandler,(void *) 0); #endif } + +/*****************************************************************************/ +/** +* +* This function checks the power state of one or more power islands and +* powers them up if required. +* +* @param Mask of Island(s) that need to be powered up +* +* @return XFSBL_SUCCESS for successful power up or +* XFSBL_FAILURE otherwise. +* +* @note None. +* +****************************************************************************/ +u32 XFsbl_PowerUpIsland(u32 PwrIslandMask) +{ + + u32 RegVal; + u32 Status = XFSBL_SUCCESS; + + /* If Island not powered up yet, do it now */ + RegVal = XFsbl_In32(PMU_GLOBAL_PWR_STATE); + if ((RegVal & PwrIslandMask) != + PwrIslandMask) { + + /* There is a single island for both R5_0 and R5_1 */ + if ((PwrIslandMask & PMU_GLOBAL_PWR_STATE_R5_1_MASK) == + PMU_GLOBAL_PWR_STATE_R5_1_MASK) { + PwrIslandMask &= ~(PMU_GLOBAL_PWR_STATE_R5_1_MASK); + PwrIslandMask |= PMU_GLOBAL_PWR_STATE_R5_0_MASK; + } + + /* Power up request enable */ + XFsbl_Out32(PMU_GLOBAL_REQ_PWRUP_INT_EN, PwrIslandMask); + + /* Trigger power up request */ + XFsbl_Out32(PMU_GLOBAL_REQ_PWRUP_TRIG, PwrIslandMask); + + /* Poll for Power up complete */ + do { + RegVal = XFsbl_In32(PMU_GLOBAL_REQ_PWRUP_STATUS) & PwrIslandMask; + } while (RegVal != 0x0U); + + RegVal = XFsbl_In32(PMU_GLOBAL_PWR_STATE); + if (RegVal != PwrIslandMask) { + Status = XFSBL_FAILURE; + } + } + + return Status; +} diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc.h b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc.h index 35657256..bc72cecf 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc.h +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc.h @@ -76,6 +76,8 @@ char *XFsbl_Strcpy(char *DestPtr, const char *SrcPtr); char * XFsbl_Strcat(char* Str1Ptr, const char* Str2Ptr); void XFsbl_MakeSdFileName(char *XFsbl_SdEmmcFileName, u32 MultibootReg); u32 XFsbl_Htonl(u32 Value1); +u32 XFsbl_PowerUpIsland(u32 PwrIslandMask); + #ifndef XFSBL_A53 void XFsbl_RegisterHandlers(void); #endif 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 d9fa1f4a..7608b243 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c @@ -80,7 +80,7 @@ static u32 XFsbl_PartitionValidation(XFsblPs * FsblInstancePtr, u32 PartitionNum); static u32 XFsbl_CheckHandoffCpu (XFsblPs * FsblInstancePtr, u32 DestinationCpu); -static void XFsbl_ConfigureMemory(u32 RunningCpu, u32 DestinationCpu, +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); @@ -280,9 +280,12 @@ static u32 XFsbl_CheckHandoffCpu (XFsblPs * FsblInstancePtr, * * @return none *****************************************************************************/ -static void XFsbl_PowerUpMemory(u32 MemoryType) +static u32 XFsbl_PowerUpMemory(u32 MemoryType) { u32 RegValue; + u32 Status = XFSBL_SUCCESS; + u32 PwrStateMask; + /** * Check the power status of the memory * Power up if required @@ -293,6 +296,19 @@ static void XFsbl_PowerUpMemory(u32 MemoryType) { case XFSBL_R5_0_TCM: { + + PwrStateMask = PMU_GLOBAL_PWR_STATE_R5_0_MASK | + PMU_GLOBAL_PWR_STATE_TCM0A_MASK | + PMU_GLOBAL_PWR_STATE_TCM0B_MASK; + + Status = XFsbl_PowerUpIsland(PwrStateMask); + + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_R5_0_TCM_POWER_UP; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_R5_0_TCM_POWER_UP\r\n"); + goto END; + } + /** * To access TCM, * Release reset to R5 and enable the clk @@ -343,6 +359,18 @@ static void XFsbl_PowerUpMemory(u32 MemoryType) case XFSBL_R5_1_TCM: { + PwrStateMask = PMU_GLOBAL_PWR_STATE_R5_1_MASK | + PMU_GLOBAL_PWR_STATE_TCM1A_MASK | + PMU_GLOBAL_PWR_STATE_TCM1B_MASK; + + Status = XFsbl_PowerUpIsland(PwrStateMask); + + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_R5_1_TCM_POWER_UP; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_R5_1_TCM_POWER_UP\r\n"); + goto END; + } + /** * Place R5 in split mode */ @@ -383,6 +411,22 @@ static void XFsbl_PowerUpMemory(u32 MemoryType) case XFSBL_R5_L_TCM: { + + + PwrStateMask = PMU_GLOBAL_PWR_STATE_R5_0_MASK | + PMU_GLOBAL_PWR_STATE_TCM0A_MASK | + PMU_GLOBAL_PWR_STATE_TCM0B_MASK | + PMU_GLOBAL_PWR_STATE_TCM1A_MASK | + PMU_GLOBAL_PWR_STATE_TCM1B_MASK; + + Status = XFsbl_PowerUpIsland(PwrStateMask); + + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_R5_L_TCM_POWER_UP; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_R5_L_TCM_POWER_UP\r\n"); + goto END; + } + /** * Place R5 in lock step mode * Combine TCM's @@ -435,7 +479,8 @@ static void XFsbl_PowerUpMemory(u32 MemoryType) break; } - return ; +END: + return Status; } void XFsbl_EccInitialize(u32 Address, u32 Length) @@ -564,10 +609,11 @@ END: * @return returns the error codes described in xfsbl_error.h on any error * returns XFSBL_SUCCESS on success *****************************************************************************/ -static void XFsbl_ConfigureMemory(u32 RunningCpu, u32 DestinationCpu, +static u32 XFsbl_ConfigureMemory(u32 RunningCpu, u32 DestinationCpu, u64 Address, u32 Length) { + u32 Status = XFSBL_SUCCESS; /** * Configure R50 TCM Memory */ @@ -582,7 +628,10 @@ static void XFsbl_ConfigureMemory(u32 RunningCpu, u32 DestinationCpu, */ if (RunningCpu != DestinationCpu) { - XFsbl_PowerUpMemory(XFSBL_R5_0_TCM); + Status = XFsbl_PowerUpMemory(XFSBL_R5_0_TCM); + if (Status != XFSBL_SUCCESS) { + goto END; + } } /** @@ -609,7 +658,10 @@ static void XFsbl_ConfigureMemory(u32 RunningCpu, u32 DestinationCpu, */ if (RunningCpu != DestinationCpu) { - XFsbl_PowerUpMemory(XFSBL_R5_1_TCM); + Status = XFsbl_PowerUpMemory(XFSBL_R5_1_TCM); + if (Status != XFSBL_SUCCESS) { + goto END; + } } /** @@ -635,7 +687,11 @@ static void XFsbl_ConfigureMemory(u32 RunningCpu, u32 DestinationCpu, */ if (RunningCpu != DestinationCpu) { - XFsbl_PowerUpMemory(XFSBL_R5_L_TCM); + Status = XFsbl_PowerUpMemory(XFSBL_R5_L_TCM); + if (Status != XFSBL_SUCCESS) { + goto END; + } + } /** @@ -654,7 +710,8 @@ static void XFsbl_ConfigureMemory(u32 RunningCpu, u32 DestinationCpu, */ } - return; +END: + return Status; }