lib/sw_apps/zynqmp_fsbl/src/xfsbl_ddr_init.c
static u32 XFsbl_PhyCalcLpddr4RegVal(XFsbl_DimmParams *PDimmPtr, u32 *PhyCfg)
{
	u32 Val;

	Val = (u32)(((3904U / ((PDimmPtr->PerBankRefresh != 0U) ? 8U : 1U)) / PDimmPtr->ClockPeriod));
	if (PDimmPtr->TRefRange) {
		Val /= 4U;
	}

	PhyCfg[PHY_TREFPRD] = (8U * Val) - 1000U;

	PhyCfg[PHY_NOSRA] = 0x0U;

	PhyCfg[PHY_DDRMD] = 0x5U;

	PhyCfg[PHY_TRRD] = (u32)XFSBL_MAX(XFsbl_Ceil(10.0 / PDimmPtr->ClockPeriod), 4U) + (1.875 * PDimmPtr->TRefRange);

	PhyCfg[PHY_TRAS] = (u32)XFsbl_Ceil(((PDimmPtr->TRasPs / 1000.0) / PDimmPtr->ClockPeriod / 2.0)) * 2U;

	PhyCfg[PHY_TRTP] = (PDimmPtr->BurstLength / 2U) + XFSBL_MAX((u32)XFsbl_Ceil(7.5 / PDimmPtr->ClockPeriod), 8U) - 8U;

	PhyCfg[PHY_TMOD] = 5U;

	PhyCfg[PHY_TMRD] = XFSBL_MIN(((u32)XFsbl_Ceil((XFSBL_MAX(14.0 / PDimmPtr->ClockPeriod, 10U)) / 2.0)) * 2U, 32U);

	PhyCfg[PHY_TXS] = (u32)XFsbl_Ceil(XFSBL_MAX(2.0, ((PDimmPtr->TRfcPs / 1000.0) + 7.5) / PDimmPtr->ClockPeriod));

	PhyCfg[PHY_TDQSCKMAX] = 0x5U;

	PhyCfg[PHY_TDQSCK] = (PDimmPtr->SpeedBin >= 1600U) ? ((u32)(1.5 / PDimmPtr->ClockPeriod)) : 1U;

	PhyCfg[PHY_TXP] = (u32)XFSBL_MIN(XFsbl_Ceil(PDimmPtr->TXp) + 3U, 31U);

	PhyCfg[PHY_TRCD] = XFSBL_MAX(((PDimmPtr->TRcdPs / 1000.0) - PDimmPtr->AdditiveLatency), (PhyCfg[PHY_TRAS] - 8U));

	PhyCfg[PHY_R061] = PDimmPtr->Mr;

	PhyCfg[PHY_R062] = PDimmPtr->Emr;

	PhyCfg[PHY_R063] = PDimmPtr->Emr2;

	PhyCfg[PHY_R064] = PDimmPtr->Emr3;

	if (PDimmPtr->DramCaOdt == 240U) {
		PhyCfg[PHY_CAODT] = 1U;
	} else if (PDimmPtr->DramCaOdt == 120U) {
		PhyCfg[PHY_CAODT] = 2U;
	} else if (PDimmPtr->DramCaOdt == 80U) {
		PhyCfg[PHY_CAODT] = 3U;
	} else if (PDimmPtr->DramCaOdt == 60U) {
		PhyCfg[PHY_CAODT] = 4U;
	} else if (PDimmPtr->DramCaOdt == 48U) {
		PhyCfg[PHY_CAODT] = 5U;
	} else if (PDimmPtr->DramCaOdt == 40U) {
		PhyCfg[PHY_CAODT] = 6U;
	} else {
		PhyCfg[PHY_CAODT] = 5U;
	}

	PhyCfg[PHY_DQODT] = PDimmPtr->DramOdt ? PhyCfg[PHY_CAODT] : 6U;

	PhyCfg[PHY_VREFCA_RANGE] = 0U;

	PhyCfg[PHY_VREFCA] = 0x21U;

	PhyCfg[PHY_VREFDQ_RANGE] = PDimmPtr->Lp4NoOdt;

	if (PDimmPtr->Zc1656 || PDimmPtr->HasEccComp) {
		PhyCfg[PHY_VREFDQ] = 0x2EU;
	} else {
		if (PDimmPtr->Lp4NoOdt) {
			PhyCfg[PHY_VREFDQ] = 0x2FU;
		} else {
			PhyCfg[PHY_VREFDQ] = 0x19U;
		}
	}

	PhyCfg[PHY_ODTD_CA] = 0U;

	PhyCfg[PHY_ODTE_CS] = 1U;

	PhyCfg[PHY_ODTE_CK] = 0U;

	PhyCfg[PHY_CODT] = 6U;

	if (PDimmPtr->RdDbi) {
		if (!PDimmPtr->RdbiWrkAround) {
			PhyCfg[PHY_DTRDBITR] = 0x3U;
		} else {
			PhyCfg[PHY_DTRDBITR] = 0x0U;
		}
	}
	if (!(PDimmPtr->DataMask || PDimmPtr->WrDbi)) {
		PhyCfg[PHY_DTWBDDM] = 0U;
	}

	PhyCfg[PHY_ODTOEMODE] = 0xAU;

	PhyCfg[PHY_CKNCLKGATE0] = 0x0U;

	PhyCfg[PHY_CKCLKGATE0] = 0x0U;

	PhyCfg[PHY_CKOEMODE] = 0x5U;

	PhyCfg[PHY_CKNCLKGATE1] = 0x0U;

	PhyCfg[PHY_CKCLKGATE1] = 0x0U;

	PhyCfg[PHY_ACREFSSEL] = 0x3DU;

	PhyCfg[PHY_ACVREFISEL]  = 0x19U;

	PhyCfg[PHY_PDAEN] = 0x0U;

	if (PDimmPtr->Zc1656 || PDimmPtr->HasEccComp) {
		PhyCfg[PHY_DVINIT] = 0x2EU;
	} else {
		if (PDimmPtr->Lp4NoOdt) {
			PhyCfg[PHY_DVINIT] = 0x2FU;
		} else {
			PhyCfg[PHY_DVINIT] = 0x19U;
		}
	}

	return XFSBL_SUCCESS;
}
/*****************************************************************************/
/**
 * This function calculates the PHY register values for LPDDR4
 *
 * @param	PDimmPtr is pointer to DIMM parameters Data Structure
 * @param	PhyCfg is the array to store register field values
 *
 * @return	XFSBL_SUCCESS or XFSBL_FAILURE
 *
 *****************************************************************************/
This function calculates the PHY register values for LPDDR4
@param       PDimmPtr is pointer to DIMM parameters Data Structure
@param       PhyCfg is the array to store register field values


This function calculates the PHY register values for LPDDR4 @param PDimmPtr is pointer to DIMM parameters Data Structure @param PhyCfg is the array to store register field values
static u32 XFsbl_PhyCalcLpddr4RegVal(XFsbl_DimmParams *PDimmPtr, u32 *PhyCfg)
{
	u32 Val;
	Val = (u32)(((3904U / ((PDimmPtr->PerBankRefresh != 0U) ? 8U : 1U)) / PDimmPtr->ClockPeriod));
	if (PDimmPtr->TRefRange) {
		Val /= 4U;
	}
	PhyCfg[PHY_TREFPRD] = (8U * Val) - 1000U;
	PhyCfg[PHY_NOSRA] = 0x0U;
	PhyCfg[PHY_DDRMD] = 0x5U;
	PhyCfg[PHY_TRRD] = (u32)XFSBL_MAX(XFsbl_Ceil(10.0 / PDimmPtr->ClockPeriod), 4U) + (1.875 * PDimmPtr->TRefRange);
	PhyCfg[PHY_TRAS] = (u32)XFsbl_Ceil(((PDimmPtr->TRasPs / 1000.0) / PDimmPtr->ClockPeriod / 2.0)) * 2U;
	PhyCfg[PHY_TRTP] = (PDimmPtr->BurstLength / 2U) + XFSBL_MAX((u32)XFsbl_Ceil(7.5 / PDimmPtr->ClockPeriod), 8U) - 8U;
	PhyCfg[PHY_TMOD] = 5U;
	PhyCfg[PHY_TMRD] = XFSBL_MIN(((u32)XFsbl_Ceil((XFSBL_MAX(14.0 / PDimmPtr->ClockPeriod, 10U)) / 2.0)) * 2U, 32U);
	PhyCfg[PHY_TXS] = (u32)XFsbl_Ceil(XFSBL_MAX(2.0, ((PDimmPtr->TRfcPs / 1000.0) + 7.5) / PDimmPtr->ClockPeriod));
	PhyCfg[PHY_TDQSCKMAX] = 0x5U;
	PhyCfg[PHY_TDQSCK] = (PDimmPtr->SpeedBin >= 1600U) ? ((u32)(1.5 / PDimmPtr->ClockPeriod)) : 1U;
	PhyCfg[PHY_TXP] = (u32)XFSBL_MIN(XFsbl_Ceil(PDimmPtr->TXp) + 3U, 31U);
	PhyCfg[PHY_TRCD] = XFSBL_MAX(((PDimmPtr->TRcdPs / 1000.0) - PDimmPtr->AdditiveLatency), (PhyCfg[PHY_TRAS] - 8U));
	PhyCfg[PHY_R061] = PDimmPtr->Mr;
	PhyCfg[PHY_R062] = PDimmPtr->Emr;
	PhyCfg[PHY_R063] = PDimmPtr->Emr2;
	PhyCfg[PHY_R064] = PDimmPtr->Emr3;
	if (PDimmPtr->DramCaOdt == 240U) {
		PhyCfg[PHY_CAODT] = 1U;
	} else if (PDimmPtr->DramCaOdt == 120U) {
		PhyCfg[PHY_CAODT] = 2U;
	} else if (PDimmPtr->DramCaOdt == 80U) {
		PhyCfg[PHY_CAODT] = 3U;
	} else if (PDimmPtr->DramCaOdt == 60U) {
		PhyCfg[PHY_CAODT] = 4U;
	} else if (PDimmPtr->DramCaOdt == 48U) {
		PhyCfg[PHY_CAODT] = 5U;
	} else if (PDimmPtr->DramCaOdt == 40U) {
		PhyCfg[PHY_CAODT] = 6U;
	} else {
		PhyCfg[PHY_CAODT] = 5U;
	}
	PhyCfg[PHY_DQODT] = PDimmPtr->DramOdt ? PhyCfg[PHY_CAODT] : 6U;
	PhyCfg[PHY_VREFCA_RANGE] = 0U;
	PhyCfg[PHY_VREFCA] = 0x21U;
	PhyCfg[PHY_VREFDQ_RANGE] = PDimmPtr->Lp4NoOdt;
	if (PDimmPtr->Zc1656 || PDimmPtr->HasEccComp) {
		PhyCfg[PHY_VREFDQ] = 0x2EU;
	} else {
		if (PDimmPtr->Lp4NoOdt) {
			PhyCfg[PHY_VREFDQ] = 0x2FU;
		} else {
			PhyCfg[PHY_VREFDQ] = 0x19U;
		}
	}
	PhyCfg[PHY_ODTD_CA] = 0U;
	PhyCfg[PHY_ODTE_CS] = 1U;
	PhyCfg[PHY_ODTE_CK] = 0U;
	PhyCfg[PHY_CODT] = 6U;
	if (PDimmPtr->RdDbi) {
		if (!PDimmPtr->RdbiWrkAround) {
			PhyCfg[PHY_DTRDBITR] = 0x3U;
		} else {
			PhyCfg[PHY_DTRDBITR] = 0x0U;
		}
	}
	if (!(PDimmPtr->DataMask || PDimmPtr->WrDbi)) {
		PhyCfg[PHY_DTWBDDM] = 0U;
	}
	PhyCfg[PHY_ODTOEMODE] = 0xAU;
	PhyCfg[PHY_CKNCLKGATE0] = 0x0U;
	PhyCfg[PHY_CKCLKGATE0] = 0x0U;
	PhyCfg[PHY_CKOEMODE] = 0x5U;
	PhyCfg[PHY_CKNCLKGATE1] = 0x0U;
	PhyCfg[PHY_CKCLKGATE1] = 0x0U;
	PhyCfg[PHY_ACREFSSEL] = 0x3DU;
	PhyCfg[PHY_ACVREFISEL]  = 0x19U;
	PhyCfg[PHY_PDAEN] = 0x0U;
	if (PDimmPtr->Zc1656 || PDimmPtr->HasEccComp) {
		PhyCfg[PHY_DVINIT] = 0x2EU;
	} else {
		if (PDimmPtr->Lp4NoOdt) {
			PhyCfg[PHY_DVINIT] = 0x2FU;
		} else {
			PhyCfg[PHY_DVINIT] = 0x19U;
		}
	}
	return XFSBL_SUCCESS;
}
static u32 XFsbl_PhyCalcLpddr4RegVal ( XFsbl_DimmParams * PDimmPtr , u32 * PhyCfg ) { u32 Val ; Val = ( u32 ) ( ( ( 3904U / ( ( PDimmPtr -> PerBankRefresh != 0U ) ? 8U : 1U ) ) / PDimmPtr -> ClockPeriod ) ) ; if ( PDimmPtr -> TRefRange ) { Val /= 4U ; } PhyCfg [ PHY_TREFPRD ] = ( 8U * Val ) - 1000U ; PhyCfg [ PHY_NOSRA ] = 0x0U ; PhyCfg [ PHY_DDRMD ] = 0x5U ; PhyCfg [ PHY_TRRD ] = ( u32 ) XFSBL_MAX ( XFsbl_Ceil ( 10.0 / PDimmPtr -> ClockPeriod ) , 4U ) + ( 1.875 * PDimmPtr -> TRefRange ) ; PhyCfg [ PHY_TRAS ] = ( u32 ) XFsbl_Ceil ( ( ( PDimmPtr -> TRasPs / 1000.0 ) / PDimmPtr -> ClockPeriod / 2.0 ) ) * 2U ; PhyCfg [ PHY_TRTP ] = ( PDimmPtr -> BurstLength / 2U ) + XFSBL_MAX ( ( u32 ) XFsbl_Ceil ( 7.5 / PDimmPtr -> ClockPeriod ) , 8U ) - 8U ; PhyCfg [ PHY_TMOD ] = 5U ; PhyCfg [ PHY_TMRD ] = XFSBL_MIN ( ( ( u32 ) XFsbl_Ceil ( ( XFSBL_MAX ( 14.0 / PDimmPtr -> ClockPeriod , 10U ) ) / 2.0 ) ) * 2U , 32U ) ; PhyCfg [ PHY_TXS ] = ( u32 ) XFsbl_Ceil ( XFSBL_MAX ( 2.0 , ( ( PDimmPtr -> TRfcPs / 1000.0 ) + 7.5 ) / PDimmPtr -> ClockPeriod ) ) ; PhyCfg [ PHY_TDQSCKMAX ] = 0x5U ; PhyCfg [ PHY_TDQSCK ] = ( PDimmPtr -> SpeedBin >= 1600U ) ? ( ( u32 ) ( 1.5 / PDimmPtr -> ClockPeriod ) ) : 1U ; PhyCfg [ PHY_TXP ] = ( u32 ) XFSBL_MIN ( XFsbl_Ceil ( PDimmPtr -> TXp ) + 3U , 31U ) ; PhyCfg [ PHY_TRCD ] = XFSBL_MAX ( ( ( PDimmPtr -> TRcdPs / 1000.0 ) - PDimmPtr -> AdditiveLatency ) , ( PhyCfg [ PHY_TRAS ] - 8U ) ) ; PhyCfg [ PHY_R061 ] = PDimmPtr -> Mr ; PhyCfg [ PHY_R062 ] = PDimmPtr -> Emr ; PhyCfg [ PHY_R063 ] = PDimmPtr -> Emr2 ; PhyCfg [ PHY_R064 ] = PDimmPtr -> Emr3 ; if ( PDimmPtr -> DramCaOdt == 240U ) { PhyCfg [ PHY_CAODT ] = 1U ; } else if ( PDimmPtr -> DramCaOdt == 120U ) { PhyCfg [ PHY_CAODT ] = 2U ; } else if ( PDimmPtr -> DramCaOdt == 80U ) { PhyCfg [ PHY_CAODT ] = 3U ; } else if ( PDimmPtr -> DramCaOdt == 60U ) { PhyCfg [ PHY_CAODT ] = 4U ; } else if ( PDimmPtr -> DramCaOdt == 48U ) { PhyCfg [ PHY_CAODT ] = 5U ; } else if ( PDimmPtr -> DramCaOdt == 40U ) { PhyCfg [ PHY_CAODT ] = 6U ; } else { PhyCfg [ PHY_CAODT ] = 5U ; } PhyCfg [ PHY_DQODT ] = PDimmPtr -> DramOdt ? PhyCfg [ PHY_CAODT ] : 6U ; PhyCfg [ PHY_VREFCA_RANGE ] = 0U ; PhyCfg [ PHY_VREFCA ] = 0x21U ; PhyCfg [ PHY_VREFDQ_RANGE ] = PDimmPtr -> Lp4NoOdt ; if ( PDimmPtr -> Zc1656 || PDimmPtr -> HasEccComp ) { PhyCfg [ PHY_VREFDQ ] = 0x2EU ; } else { if ( PDimmPtr -> Lp4NoOdt ) { PhyCfg [ PHY_VREFDQ ] = 0x2FU ; } else { PhyCfg [ PHY_VREFDQ ] = 0x19U ; } } PhyCfg [ PHY_ODTD_CA ] = 0U ; PhyCfg [ PHY_ODTE_CS ] = 1U ; PhyCfg [ PHY_ODTE_CK ] = 0U ; PhyCfg [ PHY_CODT ] = 6U ; if ( PDimmPtr -> RdDbi ) { if ( ! PDimmPtr -> RdbiWrkAround ) { PhyCfg [ PHY_DTRDBITR ] = 0x3U ; } else { PhyCfg [ PHY_DTRDBITR ] = 0x0U ; } } if ( ! ( PDimmPtr -> DataMask || PDimmPtr -> WrDbi ) ) { PhyCfg [ PHY_DTWBDDM ] = 0U ; } PhyCfg [ PHY_ODTOEMODE ] = 0xAU ; PhyCfg [ PHY_CKNCLKGATE0 ] = 0x0U ; PhyCfg [ PHY_CKCLKGATE0 ] = 0x0U ; PhyCfg [ PHY_CKOEMODE ] = 0x5U ; PhyCfg [ PHY_CKNCLKGATE1 ] = 0x0U ; PhyCfg [ PHY_CKCLKGATE1 ] = 0x0U ; PhyCfg [ PHY_ACREFSSEL ] = 0x3DU ; PhyCfg [ PHY_ACVREFISEL ] = 0x19U ; PhyCfg [ PHY_PDAEN ] = 0x0U ; if ( PDimmPtr -> Zc1656 || PDimmPtr -> HasEccComp ) { PhyCfg [ PHY_DVINIT ] = 0x2EU ; } else { if ( PDimmPtr -> Lp4NoOdt ) { PhyCfg [ PHY_DVINIT ] = 0x2FU ; } else { PhyCfg [ PHY_DVINIT ] = 0x19U ; } } return XFSBL_SUCCESS ; }
This function calculates the PHY register values for LPDDR4
 @param       PDimmPtr is pointer to DIMM parameters Data Structure
 @param       PhyCfg is the array to store register field values
This function calculates the PHY register values for LPDDR4 @param PDimmPtr is pointer to DIMM parameters Data Structure @param PhyCfg is the array to store register field values