lib/sw_apps/zynqmp_fsbl/src/xfsbl_ddr_init.c
u32 XFsbl_ComputeDdr4Params(u8 *SpdData, struct DdrcInitData *DdrDataPtr)
{
	struct Ddr4SpdEeprom *Ddr4SpdData = (struct Ddr4SpdEeprom *)SpdData;
	XFsbl_DimmParams *PDimmPtr = &DdrDataPtr->PDimm;
	u32 Status = XFSBL_FAILURE;

	memset(PDimmPtr->Mpart, 0U, sizeof(PDimmPtr->Mpart));
	if ((Ddr4SpdData->InfoSizeCrc & 0xFU) > 2U)
		memcpy(PDimmPtr->Mpart, Ddr4SpdData->Mpart, sizeof(PDimmPtr->Mpart) - 1U);

	PDimmPtr->MemType = Ddr4SpdData->MemType;

	PDimmPtr->NRanks = ((Ddr4SpdData->Organization >> 3U) & 0x7U) + 1U;
	PDimmPtr->RankDensity = XFsbl_ComputeDdr4RankSize(Ddr4SpdData);
	PDimmPtr->Capacity = (PDimmPtr->NRanks * PDimmPtr->RankDensity) / (1024U * 1024U);
	PDimmPtr->BusWidth = 1U << (3U + (Ddr4SpdData->BusWidth & 0x7U));
	if ((Ddr4SpdData->BusWidth >> 3U) & 0x3U)
		PDimmPtr->EccBusWidth = 8U;
	else
		PDimmPtr->EccBusWidth = 0U;
	PDimmPtr->DramWidth = 1U << ((Ddr4SpdData->Organization & 0x7U) + 2U);

	PDimmPtr->AddrMirror = 0U;
	PDimmPtr->RDimm = 0U;
	switch (Ddr4SpdData->ModuleType & DDR4_SPD_MODULETYPE_MASK) {
		case DDR4_SPD_MODULETYPE_RDIMM:
		case DDR4_SPD_MODULETYPE_72B_SO_RDIMM:
			PDimmPtr->RDimm = 1U;
			break;

		case DDR4_SPD_MODULETYPE_UDIMM:
		case DDR4_SPD_MODULETYPE_SO_DIMM:
		case DDR4_SPD_MODULETYPE_72B_SO_UDIMM:
			PDimmPtr->UDimm = 1U;
			if (Ddr4SpdData->ModSection.unbuffered.AddrMapping & 0x1U)
				PDimmPtr->AddrMirror = 1U;
			break;

		default:
			/* Do nothing as Status is initialized to XFSBL_FAILURE */
			goto END;
	}

	PDimmPtr->NumRowAddr = ((Ddr4SpdData->Addressing >> 3U) & 0x7U) + 12U;
	PDimmPtr->NumColAddr = (Ddr4SpdData->Addressing & 0x7U) + 9U;
	PDimmPtr->NumBankAddr = ((Ddr4SpdData->DensityBanks >> 4U) & 0x3U) + 2U;
	PDimmPtr->NumBgAddr = (Ddr4SpdData->DensityBanks >> 6U) & 0x3U;
	PDimmPtr->NumRankAddr = XFsbl_GetLog2(PDimmPtr->NRanks);

	PDimmPtr->BurstLength = 8U;
	PDimmPtr->RowDensity = XFsbl_GetLog2(PDimmPtr->RankDensity);

	if ((Ddr4SpdData->Timebases & 0xFU) == 0x0U) {
		PDimmPtr->MtbPs = 125U;
		PDimmPtr->Ftb10thPs = 10U;
	}

	PDimmPtr->TckminXPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TckMin, Ddr4SpdData->FineTckMin);

	PDimmPtr->SpeedBin = (u32)XFsbl_Ceil(2000000.0 / PDimmPtr->TckminXPs);

	PDimmPtr->FreqMhz = 1000000.0 / PDimmPtr->TckminXPs;

	PDimmPtr->ClockPeriod = PDimmPtr->TckminXPs / 1000.0;

	PDimmPtr->TckmaxPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TckMax, Ddr4SpdData->FineTckMax);

	PDimmPtr->CaslatX  = (Ddr4SpdData->CaslatB1 << 7U)	|
		(Ddr4SpdData->CaslatB2 << 15U)	|
		(Ddr4SpdData->CaslatB3 << 23U);

	PDimmPtr->TaaPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TaaMin, Ddr4SpdData->FineTaaMin);

	PDimmPtr->CasLatency = (u32)XFsbl_Ceil(PDimmPtr->TaaPs / 1000.0) + 1U;

	PDimmPtr->CasWriteLatency = XFsbl_Ceil(PDimmPtr->TaaPs / 1000.0);

	PDimmPtr->TRcdPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TrcdMin, Ddr4SpdData->FineTrcdMin);

	PDimmPtr->TRpPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TrpMin, Ddr4SpdData->FineTrpMin);

	PDimmPtr->TRasPs = (((Ddr4SpdData->TrasTrcExt & 0xFU) << 8U) +
			Ddr4SpdData->TrasMinLsb) * PDimmPtr->MtbPs;

	PDimmPtr->TRcPs = XFSBL_SPD_TO_PS((((Ddr4SpdData->TrasTrcExt & 0xF0U) << 4U) +
				Ddr4SpdData->TrcMinLsb), Ddr4SpdData->FineTrcMin);
	PDimmPtr->TRfc1Ps = ((Ddr4SpdData->Trfc1MinMsb << 8U) | (Ddr4SpdData->Trfc1MinLsb)) *
		PDimmPtr->MtbPs;
	PDimmPtr->TRfc2Ps = ((Ddr4SpdData->Trfc2MinMsb << 8U) | (Ddr4SpdData->Trfc2MinLsb)) *
		PDimmPtr->MtbPs;
	PDimmPtr->TRfc4Ps = ((Ddr4SpdData->Trfc4MinMsb << 8U) | (Ddr4SpdData->Trfc4MinLsb)) *
		PDimmPtr->MtbPs;
	PDimmPtr->TFawPs = (((Ddr4SpdData->TfawMsb & 0xFU) << 8U) | Ddr4SpdData->TfawMin) *
		PDimmPtr->MtbPs;

	PDimmPtr->TRrdsPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TrrdsMin, Ddr4SpdData->FineTrrdsMin);
	PDimmPtr->TRrdlPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TrrdlMin, Ddr4SpdData->FineTrrdlMin);
	PDimmPtr->TCcdlPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TccdlMin, Ddr4SpdData->FineTccdlMin);

	PDimmPtr->TRefi = 7800000U;
	Status = XFSBL_SUCCESS;

END:
	return Status;
}
/*****************************************************************************/
/**
 * This function computes DIMM parameters based upon the SPD information in
 * Ddr4SpdData. Writes the results to the XFsbl_DimmParams structure pointed
 * by PDimmPtr.
 *
 * @param	DdrDataPtr is pointer to DDR Initialization Data Structure
 * @param	SpdData is the array containing the SPD data from DIMM EEPROM
 *
 * @return	XFSBL_SUCCESS or XFSBL_FAILURE
 *
 *****************************************************************************/
This function computes DIMM parameters based upon the SPD information in
Ddr4SpdData. Writes the results to the XFsbl_DimmParams structure pointed
by PDimmPtr.

@param       DdrDataPtr is pointer to DDR Initialization Data Structure
@param       SpdData is the array containing the SPD data from DIMM EEPROM


This function computes DIMM parameters based upon the SPD information in Ddr4SpdData . Writes the results to the XFsbl_DimmParams structure pointed by PDimmPtr . @param DdrDataPtr is pointer to DDR Initialization Data Structure @param SpdData is the array containing the SPD data from DIMM EEPROM
u32 XFsbl_ComputeDdr4Params(u8 *SpdData, struct DdrcInitData *DdrDataPtr)
{
	struct Ddr4SpdEeprom *Ddr4SpdData = (struct Ddr4SpdEeprom *)SpdData;
	XFsbl_DimmParams *PDimmPtr = &DdrDataPtr->PDimm;
	u32 Status = XFSBL_FAILURE;
	memset(PDimmPtr->Mpart, 0U, sizeof(PDimmPtr->Mpart));
	if ((Ddr4SpdData->InfoSizeCrc & 0xFU) > 2U)
		memcpy(PDimmPtr->Mpart, Ddr4SpdData->Mpart, sizeof(PDimmPtr->Mpart) - 1U);
	PDimmPtr->MemType = Ddr4SpdData->MemType;
	PDimmPtr->NRanks = ((Ddr4SpdData->Organization >> 3U) & 0x7U) + 1U;
	PDimmPtr->RankDensity = XFsbl_ComputeDdr4RankSize(Ddr4SpdData);
	PDimmPtr->Capacity = (PDimmPtr->NRanks * PDimmPtr->RankDensity) / (1024U * 1024U);
	PDimmPtr->BusWidth = 1U << (3U + (Ddr4SpdData->BusWidth & 0x7U));
	if ((Ddr4SpdData->BusWidth >> 3U) & 0x3U)
		PDimmPtr->EccBusWidth = 8U;
	else
		PDimmPtr->EccBusWidth = 0U;
	PDimmPtr->DramWidth = 1U << ((Ddr4SpdData->Organization & 0x7U) + 2U);
	PDimmPtr->AddrMirror = 0U;
	PDimmPtr->RDimm = 0U;
	switch (Ddr4SpdData->ModuleType & DDR4_SPD_MODULETYPE_MASK) {
		case DDR4_SPD_MODULETYPE_RDIMM:
		case DDR4_SPD_MODULETYPE_72B_SO_RDIMM:
			PDimmPtr->RDimm = 1U;
			break;
		case DDR4_SPD_MODULETYPE_UDIMM:
		case DDR4_SPD_MODULETYPE_SO_DIMM:
		case DDR4_SPD_MODULETYPE_72B_SO_UDIMM:
			PDimmPtr->UDimm = 1U;
			if (Ddr4SpdData->ModSection.unbuffered.AddrMapping & 0x1U)
				PDimmPtr->AddrMirror = 1U;
			break;
		default:
			goto END;
	}
	PDimmPtr->NumRowAddr = ((Ddr4SpdData->Addressing >> 3U) & 0x7U) + 12U;
	PDimmPtr->NumColAddr = (Ddr4SpdData->Addressing & 0x7U) + 9U;
	PDimmPtr->NumBankAddr = ((Ddr4SpdData->DensityBanks >> 4U) & 0x3U) + 2U;
	PDimmPtr->NumBgAddr = (Ddr4SpdData->DensityBanks >> 6U) & 0x3U;
	PDimmPtr->NumRankAddr = XFsbl_GetLog2(PDimmPtr->NRanks);
	PDimmPtr->BurstLength = 8U;
	PDimmPtr->RowDensity = XFsbl_GetLog2(PDimmPtr->RankDensity);
	if ((Ddr4SpdData->Timebases & 0xFU) == 0x0U) {
		PDimmPtr->MtbPs = 125U;
		PDimmPtr->Ftb10thPs = 10U;
	}
	PDimmPtr->TckminXPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TckMin, Ddr4SpdData->FineTckMin);
	PDimmPtr->SpeedBin = (u32)XFsbl_Ceil(2000000.0 / PDimmPtr->TckminXPs);
	PDimmPtr->FreqMhz = 1000000.0 / PDimmPtr->TckminXPs;
	PDimmPtr->ClockPeriod = PDimmPtr->TckminXPs / 1000.0;
	PDimmPtr->TckmaxPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TckMax, Ddr4SpdData->FineTckMax);
	PDimmPtr->CaslatX  = (Ddr4SpdData->CaslatB1 << 7U)	|
		(Ddr4SpdData->CaslatB2 << 15U)	|
		(Ddr4SpdData->CaslatB3 << 23U);
	PDimmPtr->TaaPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TaaMin, Ddr4SpdData->FineTaaMin);
	PDimmPtr->CasLatency = (u32)XFsbl_Ceil(PDimmPtr->TaaPs / 1000.0) + 1U;
	PDimmPtr->CasWriteLatency = XFsbl_Ceil(PDimmPtr->TaaPs / 1000.0);
	PDimmPtr->TRcdPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TrcdMin, Ddr4SpdData->FineTrcdMin);
	PDimmPtr->TRpPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TrpMin, Ddr4SpdData->FineTrpMin);
	PDimmPtr->TRasPs = (((Ddr4SpdData->TrasTrcExt & 0xFU) << 8U) +
			Ddr4SpdData->TrasMinLsb) * PDimmPtr->MtbPs;
	PDimmPtr->TRcPs = XFSBL_SPD_TO_PS((((Ddr4SpdData->TrasTrcExt & 0xF0U) << 4U) +
				Ddr4SpdData->TrcMinLsb), Ddr4SpdData->FineTrcMin);
	PDimmPtr->TRfc1Ps = ((Ddr4SpdData->Trfc1MinMsb << 8U) | (Ddr4SpdData->Trfc1MinLsb)) *
		PDimmPtr->MtbPs;
	PDimmPtr->TRfc2Ps = ((Ddr4SpdData->Trfc2MinMsb << 8U) | (Ddr4SpdData->Trfc2MinLsb)) *
		PDimmPtr->MtbPs;
	PDimmPtr->TRfc4Ps = ((Ddr4SpdData->Trfc4MinMsb << 8U) | (Ddr4SpdData->Trfc4MinLsb)) *
		PDimmPtr->MtbPs;
	PDimmPtr->TFawPs = (((Ddr4SpdData->TfawMsb & 0xFU) << 8U) | Ddr4SpdData->TfawMin) *
		PDimmPtr->MtbPs;
	PDimmPtr->TRrdsPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TrrdsMin, Ddr4SpdData->FineTrrdsMin);
	PDimmPtr->TRrdlPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TrrdlMin, Ddr4SpdData->FineTrrdlMin);
	PDimmPtr->TCcdlPs = XFSBL_SPD_TO_PS(Ddr4SpdData->TccdlMin, Ddr4SpdData->FineTccdlMin);
	PDimmPtr->TRefi = 7800000U;
	Status = XFSBL_SUCCESS;
END:
	return Status;
}
u32 XFsbl_ComputeDdr4Params ( u8 * SpdData , struct DdrcInitData * DdrDataPtr ) { struct Ddr4SpdEeprom * Ddr4SpdData = ( struct Ddr4SpdEeprom * ) SpdData ; XFsbl_DimmParams * PDimmPtr = & DdrDataPtr -> PDimm ; u32 Status = XFSBL_FAILURE ; memset ( PDimmPtr -> Mpart , 0U , sizeof ( PDimmPtr -> Mpart ) ) ; if ( ( Ddr4SpdData -> InfoSizeCrc & 0xFU ) > 2U ) memcpy ( PDimmPtr -> Mpart , Ddr4SpdData -> Mpart , sizeof ( PDimmPtr -> Mpart ) - 1U ) ; PDimmPtr -> MemType = Ddr4SpdData -> MemType ; PDimmPtr -> NRanks = ( ( Ddr4SpdData -> Organization >> 3U ) & 0x7U ) + 1U ; PDimmPtr -> RankDensity = XFsbl_ComputeDdr4RankSize ( Ddr4SpdData ) ; PDimmPtr -> Capacity = ( PDimmPtr -> NRanks * PDimmPtr -> RankDensity ) / ( 1024U * 1024U ) ; PDimmPtr -> BusWidth = 1U << ( 3U + ( Ddr4SpdData -> BusWidth & 0x7U ) ) ; if ( ( Ddr4SpdData -> BusWidth >> 3U ) & 0x3U ) PDimmPtr -> EccBusWidth = 8U ; else PDimmPtr -> EccBusWidth = 0U ; PDimmPtr -> DramWidth = 1U << ( ( Ddr4SpdData -> Organization & 0x7U ) + 2U ) ; PDimmPtr -> AddrMirror = 0U ; PDimmPtr -> RDimm = 0U ; switch ( Ddr4SpdData -> ModuleType & DDR4_SPD_MODULETYPE_MASK ) { case DDR4_SPD_MODULETYPE_RDIMM : case DDR4_SPD_MODULETYPE_72B_SO_RDIMM : PDimmPtr -> RDimm = 1U ; break ; case DDR4_SPD_MODULETYPE_UDIMM : case DDR4_SPD_MODULETYPE_SO_DIMM : case DDR4_SPD_MODULETYPE_72B_SO_UDIMM : PDimmPtr -> UDimm = 1U ; if ( Ddr4SpdData -> ModSection . unbuffered . AddrMapping & 0x1U ) PDimmPtr -> AddrMirror = 1U ; break ; default : goto END ; } PDimmPtr -> NumRowAddr = ( ( Ddr4SpdData -> Addressing >> 3U ) & 0x7U ) + 12U ; PDimmPtr -> NumColAddr = ( Ddr4SpdData -> Addressing & 0x7U ) + 9U ; PDimmPtr -> NumBankAddr = ( ( Ddr4SpdData -> DensityBanks >> 4U ) & 0x3U ) + 2U ; PDimmPtr -> NumBgAddr = ( Ddr4SpdData -> DensityBanks >> 6U ) & 0x3U ; PDimmPtr -> NumRankAddr = XFsbl_GetLog2 ( PDimmPtr -> NRanks ) ; PDimmPtr -> BurstLength = 8U ; PDimmPtr -> RowDensity = XFsbl_GetLog2 ( PDimmPtr -> RankDensity ) ; if ( ( Ddr4SpdData -> Timebases & 0xFU ) == 0x0U ) { PDimmPtr -> MtbPs = 125U ; PDimmPtr -> Ftb10thPs = 10U ; } PDimmPtr -> TckminXPs = XFSBL_SPD_TO_PS ( Ddr4SpdData -> TckMin , Ddr4SpdData -> FineTckMin ) ; PDimmPtr -> SpeedBin = ( u32 ) XFsbl_Ceil ( 2000000.0 / PDimmPtr -> TckminXPs ) ; PDimmPtr -> FreqMhz = 1000000.0 / PDimmPtr -> TckminXPs ; PDimmPtr -> ClockPeriod = PDimmPtr -> TckminXPs / 1000.0 ; PDimmPtr -> TckmaxPs = XFSBL_SPD_TO_PS ( Ddr4SpdData -> TckMax , Ddr4SpdData -> FineTckMax ) ; PDimmPtr -> CaslatX = ( Ddr4SpdData -> CaslatB1 << 7U ) | ( Ddr4SpdData -> CaslatB2 << 15U ) | ( Ddr4SpdData -> CaslatB3 << 23U ) ; PDimmPtr -> TaaPs = XFSBL_SPD_TO_PS ( Ddr4SpdData -> TaaMin , Ddr4SpdData -> FineTaaMin ) ; PDimmPtr -> CasLatency = ( u32 ) XFsbl_Ceil ( PDimmPtr -> TaaPs / 1000.0 ) + 1U ; PDimmPtr -> CasWriteLatency = XFsbl_Ceil ( PDimmPtr -> TaaPs / 1000.0 ) ; PDimmPtr -> TRcdPs = XFSBL_SPD_TO_PS ( Ddr4SpdData -> TrcdMin , Ddr4SpdData -> FineTrcdMin ) ; PDimmPtr -> TRpPs = XFSBL_SPD_TO_PS ( Ddr4SpdData -> TrpMin , Ddr4SpdData -> FineTrpMin ) ; PDimmPtr -> TRasPs = ( ( ( Ddr4SpdData -> TrasTrcExt & 0xFU ) << 8U ) + Ddr4SpdData -> TrasMinLsb ) * PDimmPtr -> MtbPs ; PDimmPtr -> TRcPs = XFSBL_SPD_TO_PS ( ( ( ( Ddr4SpdData -> TrasTrcExt & 0xF0U ) << 4U ) + Ddr4SpdData -> TrcMinLsb ) , Ddr4SpdData -> FineTrcMin ) ; PDimmPtr -> TRfc1Ps = ( ( Ddr4SpdData -> Trfc1MinMsb << 8U ) | ( Ddr4SpdData -> Trfc1MinLsb ) ) * PDimmPtr -> MtbPs ; PDimmPtr -> TRfc2Ps = ( ( Ddr4SpdData -> Trfc2MinMsb << 8U ) | ( Ddr4SpdData -> Trfc2MinLsb ) ) * PDimmPtr -> MtbPs ; PDimmPtr -> TRfc4Ps = ( ( Ddr4SpdData -> Trfc4MinMsb << 8U ) | ( Ddr4SpdData -> Trfc4MinLsb ) ) * PDimmPtr -> MtbPs ; PDimmPtr -> TFawPs = ( ( ( Ddr4SpdData -> TfawMsb & 0xFU ) << 8U ) | Ddr4SpdData -> TfawMin ) * PDimmPtr -> MtbPs ; PDimmPtr -> TRrdsPs = XFSBL_SPD_TO_PS ( Ddr4SpdData -> TrrdsMin , Ddr4SpdData -> FineTrrdsMin ) ; PDimmPtr -> TRrdlPs = XFSBL_SPD_TO_PS ( Ddr4SpdData -> TrrdlMin , Ddr4SpdData -> FineTrrdlMin ) ; PDimmPtr -> TCcdlPs = XFSBL_SPD_TO_PS ( Ddr4SpdData -> TccdlMin , Ddr4SpdData -> FineTccdlMin ) ; PDimmPtr -> TRefi = 7800000U ; Status = XFSBL_SUCCESS ; END : return Status ; }
This function computes DIMM parameters based upon the SPD information in
 Ddr4SpdData.
This function computes DIMM parameters based upon the SPD information in Ddr4SpdData .
/* Do nothing as Status is initialized to XFSBL_FAILURE */