XilinxProcessorIPLib/drivers/rfdc/src/xrfdc_clock.c
u32 XRFdc_GetPLLConfig(XRFdc *InstancePtr, u32 Type, u32 Tile_Id, XRFdc_PLL_Settings *PLLSettings)
{
	u32 Status;
	u32 BaseAddr;
	u16 ReadReg;
	double RefClkFreq;
	double SampleRate;
	u32 FeedbackDivider;
	u8 OutputDivider;
	u32 RefClkDivider;
	u32 Enabled;
	u8 DivideMode;
	u32 PLLFreq;
	u32 PLLFS;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XRFDC_COMPONENT_IS_READY);
	Xil_AssertNonvoid(PLLSettings != NULL);

	Status = XRFdc_CheckTileEnabled(InstancePtr, Type, Tile_Id);
	if (Status != XRFDC_SUCCESS) {
		metal_log(METAL_LOG_ERROR, "\n Requested tile (%s %u) not available in %s\r\n",
			  (Type == XRFDC_ADC_TILE) ? "ADC" : "DAC", Tile_Id, __func__);
		goto RETURN_PATH;
	}

	BaseAddr = XRFDC_CTRL_STS_BASE(Type, Tile_Id);
	PLLFreq = XRFdc_ReadReg(InstancePtr, BaseAddr, XRFDC_PLL_FREQ);

	RefClkFreq = ((double)PLLFreq) / XRFDC_MILLI;
	PLLFS = XRFdc_ReadReg(InstancePtr, BaseAddr, XRFDC_PLL_FS);
	SampleRate = ((double)PLLFS) / XRFDC_MICRO;
	if (PLLFS == 0) {
		/*This code is here to support the old IPs.*/
		if (Type == XRFDC_ADC_TILE) {
			PLLSettings->Enabled = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.Enabled;
			PLLSettings->FeedbackDivider = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.FeedbackDivider;
			PLLSettings->OutputDivider = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.OutputDivider;
			PLLSettings->RefClkDivider = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.RefClkDivider;
			PLLSettings->RefClkFreq = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.RefClkFreq;
			PLLSettings->SampleRate = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.SampleRate;
			Status = XRFDC_SUCCESS;
			goto RETURN_PATH;
		} else {
			PLLSettings->Enabled = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.Enabled;
			PLLSettings->FeedbackDivider = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.FeedbackDivider;
			PLLSettings->OutputDivider = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.OutputDivider;
			PLLSettings->RefClkDivider = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.RefClkDivider;
			PLLSettings->RefClkFreq = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.RefClkFreq;
			PLLSettings->SampleRate = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.SampleRate;
			Status = XRFDC_SUCCESS;
			goto RETURN_PATH;
		}
	} else {
		if (Type == XRFDC_ADC_TILE) {
			BaseAddr = XRFDC_ADC_TILE_DRP_ADDR(Tile_Id);
		} else {
			BaseAddr = XRFDC_DAC_TILE_DRP_ADDR(Tile_Id);
		}

		BaseAddr += XRFDC_HSCOM_ADDR;

		FeedbackDivider = XRFdc_RDReg(InstancePtr, BaseAddr, XRFDC_PLL_FPDIV, 0x00FF) + 2;

		ReadReg = XRFdc_ReadReg16(InstancePtr, BaseAddr, XRFDC_PLL_REFDIV);
		if (ReadReg & XRFDC_REFCLK_DIV_1_MASK) {
			RefClkDivider = XRFDC_REF_CLK_DIV_1;
		} else {
			switch (ReadReg & XRFDC_REFCLK_DIV_MASK) {
			case XRFDC_REFCLK_DIV_2_MASK:
				RefClkDivider = XRFDC_REF_CLK_DIV_2;
				break;
			case XRFDC_REFCLK_DIV_3_MASK:
				RefClkDivider = XRFDC_REF_CLK_DIV_3;
				break;
			case XRFDC_REFCLK_DIV_4_MASK:
				RefClkDivider = XRFDC_REF_CLK_DIV_4;
				break;
			default:
				/*
					 * IP currently supporting 1 to 4 divider values. This
					 * error condition might change in future based on IP update.
					 */
				metal_log(METAL_LOG_ERROR,
					  "\n Unsupported Reference clock Divider value (%u) for %s %u in %s\r\n",
					  (ReadReg & XRFDC_REFCLK_DIV_MASK), (Type == XRFDC_ADC_TILE) ? "ADC" : "DAC",
					  Tile_Id, __func__);
				Status = XRFDC_FAILURE;
				goto RETURN_PATH;
			}
		}
		if (XRFdc_GetClockSource(InstancePtr, Type, Tile_Id, &Enabled) != XRFDC_SUCCESS) {
			Status = XRFDC_FAILURE;
			goto RETURN_PATH;
		}

		ReadReg = XRFdc_ReadReg16(InstancePtr, BaseAddr, XRFDC_PLL_DIVIDER0);
		DivideMode = (ReadReg & XRFDC_PLL_DIVIDER0_MODE_MASK) >> XRFDC_PLL_DIVIDER0_SHIFT;

		switch (DivideMode) {
		case XRFDC_PLL_OUTDIV_MODE_1:
			OutputDivider = 1;
			break;
		case XRFDC_PLL_OUTDIV_MODE_2:
			OutputDivider = 2;
			break;
		case XRFDC_PLL_OUTDIV_MODE_3:
			OutputDivider = 3;
			break;
		case XRFDC_PLL_OUTDIV_MODE_N:
			OutputDivider = ((ReadReg & XRFDC_PLL_DIVIDER0_VALUE_MASK) + 2) << 1;
			break;
		default:
			metal_log(METAL_LOG_ERROR, "\n Unsupported Output clock Divider value (%u) for %s %u in %s\r\n",
				  DivideMode, (Type == XRFDC_ADC_TILE) ? "ADC" : "DAC", Tile_Id, __func__);
			Status = XRFDC_FAILURE;
			goto RETURN_PATH;
			break;
		}
		PLLSettings->Enabled = Enabled;
		PLLSettings->FeedbackDivider = FeedbackDivider;
		PLLSettings->OutputDivider = OutputDivider;
		PLLSettings->RefClkDivider = RefClkDivider;
		PLLSettings->RefClkFreq = RefClkFreq;
		PLLSettings->SampleRate = SampleRate;
	}

	Status = XRFDC_SUCCESS;
RETURN_PATH:

	return Status;
}
/*****************************************************************************/
/**
*
* This API is used to get the PLL Configurations.
*
* @param    InstancePtr is a pointer to the XRfdc instance.
* @param    Type represents ADC or DAC.
* @param    Tile_Id Valid values are 0-3.
* @param    PLLSettings pointer to the XRFdc_PLL_Settings structure to get
*           the PLL configurations
*
* @note     None.
*
******************************************************************************/
This API is used to get the PLL Configurations.
This API is used to get the PLL Configurations .
u32 XRFdc_GetPLLConfig(XRFdc *InstancePtr, u32 Type, u32 Tile_Id, XRFdc_PLL_Settings *PLLSettings)
{
	u32 Status;
	u32 BaseAddr;
	u16 ReadReg;
	double RefClkFreq;
	double SampleRate;
	u32 FeedbackDivider;
	u8 OutputDivider;
	u32 RefClkDivider;
	u32 Enabled;
	u8 DivideMode;
	u32 PLLFreq;
	u32 PLLFS;
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XRFDC_COMPONENT_IS_READY);
	Xil_AssertNonvoid(PLLSettings != NULL);
	Status = XRFdc_CheckTileEnabled(InstancePtr, Type, Tile_Id);
	if (Status != XRFDC_SUCCESS) {
		metal_log(METAL_LOG_ERROR, "\n Requested tile (%s %u) not available in %s\r\n",
			  (Type == XRFDC_ADC_TILE) ? "ADC" : "DAC", Tile_Id, __func__);
		goto RETURN_PATH;
	}
	BaseAddr = XRFDC_CTRL_STS_BASE(Type, Tile_Id);
	PLLFreq = XRFdc_ReadReg(InstancePtr, BaseAddr, XRFDC_PLL_FREQ);
	RefClkFreq = ((double)PLLFreq) / XRFDC_MILLI;
	PLLFS = XRFdc_ReadReg(InstancePtr, BaseAddr, XRFDC_PLL_FS);
	SampleRate = ((double)PLLFS) / XRFDC_MICRO;
	if (PLLFS == 0) {
		if (Type == XRFDC_ADC_TILE) {
			PLLSettings->Enabled = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.Enabled;
			PLLSettings->FeedbackDivider = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.FeedbackDivider;
			PLLSettings->OutputDivider = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.OutputDivider;
			PLLSettings->RefClkDivider = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.RefClkDivider;
			PLLSettings->RefClkFreq = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.RefClkFreq;
			PLLSettings->SampleRate = InstancePtr->ADC_Tile[Tile_Id].PLL_Settings.SampleRate;
			Status = XRFDC_SUCCESS;
			goto RETURN_PATH;
		} else {
			PLLSettings->Enabled = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.Enabled;
			PLLSettings->FeedbackDivider = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.FeedbackDivider;
			PLLSettings->OutputDivider = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.OutputDivider;
			PLLSettings->RefClkDivider = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.RefClkDivider;
			PLLSettings->RefClkFreq = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.RefClkFreq;
			PLLSettings->SampleRate = InstancePtr->DAC_Tile[Tile_Id].PLL_Settings.SampleRate;
			Status = XRFDC_SUCCESS;
			goto RETURN_PATH;
		}
	} else {
		if (Type == XRFDC_ADC_TILE) {
			BaseAddr = XRFDC_ADC_TILE_DRP_ADDR(Tile_Id);
		} else {
			BaseAddr = XRFDC_DAC_TILE_DRP_ADDR(Tile_Id);
		}
		BaseAddr += XRFDC_HSCOM_ADDR;
		FeedbackDivider = XRFdc_RDReg(InstancePtr, BaseAddr, XRFDC_PLL_FPDIV, 0x00FF) + 2;
		ReadReg = XRFdc_ReadReg16(InstancePtr, BaseAddr, XRFDC_PLL_REFDIV);
		if (ReadReg & XRFDC_REFCLK_DIV_1_MASK) {
			RefClkDivider = XRFDC_REF_CLK_DIV_1;
		} else {
			switch (ReadReg & XRFDC_REFCLK_DIV_MASK) {
			case XRFDC_REFCLK_DIV_2_MASK:
				RefClkDivider = XRFDC_REF_CLK_DIV_2;
				break;
			case XRFDC_REFCLK_DIV_3_MASK:
				RefClkDivider = XRFDC_REF_CLK_DIV_3;
				break;
			case XRFDC_REFCLK_DIV_4_MASK:
				RefClkDivider = XRFDC_REF_CLK_DIV_4;
				break;
			default:
				metal_log(METAL_LOG_ERROR,
					  "\n Unsupported Reference clock Divider value (%u) for %s %u in %s\r\n",
					  (ReadReg & XRFDC_REFCLK_DIV_MASK), (Type == XRFDC_ADC_TILE) ? "ADC" : "DAC",
					  Tile_Id, __func__);
				Status = XRFDC_FAILURE;
				goto RETURN_PATH;
			}
		}
		if (XRFdc_GetClockSource(InstancePtr, Type, Tile_Id, &Enabled) != XRFDC_SUCCESS) {
			Status = XRFDC_FAILURE;
			goto RETURN_PATH;
		}
		ReadReg = XRFdc_ReadReg16(InstancePtr, BaseAddr, XRFDC_PLL_DIVIDER0);
		DivideMode = (ReadReg & XRFDC_PLL_DIVIDER0_MODE_MASK) >> XRFDC_PLL_DIVIDER0_SHIFT;
		switch (DivideMode) {
		case XRFDC_PLL_OUTDIV_MODE_1:
			OutputDivider = 1;
			break;
		case XRFDC_PLL_OUTDIV_MODE_2:
			OutputDivider = 2;
			break;
		case XRFDC_PLL_OUTDIV_MODE_3:
			OutputDivider = 3;
			break;
		case XRFDC_PLL_OUTDIV_MODE_N:
			OutputDivider = ((ReadReg & XRFDC_PLL_DIVIDER0_VALUE_MASK) + 2) << 1;
			break;
		default:
			metal_log(METAL_LOG_ERROR, "\n Unsupported Output clock Divider value (%u) for %s %u in %s\r\n",
				  DivideMode, (Type == XRFDC_ADC_TILE) ? "ADC" : "DAC", Tile_Id, __func__);
			Status = XRFDC_FAILURE;
			goto RETURN_PATH;
			break;
		}
		PLLSettings->Enabled = Enabled;
		PLLSettings->FeedbackDivider = FeedbackDivider;
		PLLSettings->OutputDivider = OutputDivider;
		PLLSettings->RefClkDivider = RefClkDivider;
		PLLSettings->RefClkFreq = RefClkFreq;
		PLLSettings->SampleRate = SampleRate;
	}
	Status = XRFDC_SUCCESS;
RETURN_PATH:
	return Status;
}
u32 XRFdc_GetPLLConfig ( XRFdc * InstancePtr , u32 Type , u32 Tile_Id , XRFdc_PLL_Settings * PLLSettings ) { u32 Status ; u32 BaseAddr ; u16 ReadReg ; double RefClkFreq ; double SampleRate ; u32 FeedbackDivider ; u8 OutputDivider ; u32 RefClkDivider ; u32 Enabled ; u8 DivideMode ; u32 PLLFreq ; u32 PLLFS ; Xil_AssertNonvoid ( InstancePtr != NULL ) ; Xil_AssertNonvoid ( InstancePtr -> IsReady == XRFDC_COMPONENT_IS_READY ) ; Xil_AssertNonvoid ( PLLSettings != NULL ) ; Status = XRFdc_CheckTileEnabled ( InstancePtr , Type , Tile_Id ) ; if ( Status != XRFDC_SUCCESS ) { metal_log ( METAL_LOG_ERROR , " \n \r \n " , ( Type == XRFDC_ADC_TILE ) ? " " : " " , Tile_Id , __func__ ) ; goto RETURN_PATH ; } BaseAddr = XRFDC_CTRL_STS_BASE ( Type , Tile_Id ) ; PLLFreq = XRFdc_ReadReg ( InstancePtr , BaseAddr , XRFDC_PLL_FREQ ) ; RefClkFreq = ( ( double ) PLLFreq ) / XRFDC_MILLI ; PLLFS = XRFdc_ReadReg ( InstancePtr , BaseAddr , XRFDC_PLL_FS ) ; SampleRate = ( ( double ) PLLFS ) / XRFDC_MICRO ; if ( PLLFS == 0 ) { if ( Type == XRFDC_ADC_TILE ) { PLLSettings -> Enabled = InstancePtr -> ADC_Tile [ Tile_Id ] . PLL_Settings . Enabled ; PLLSettings -> FeedbackDivider = InstancePtr -> ADC_Tile [ Tile_Id ] . PLL_Settings . FeedbackDivider ; PLLSettings -> OutputDivider = InstancePtr -> ADC_Tile [ Tile_Id ] . PLL_Settings . OutputDivider ; PLLSettings -> RefClkDivider = InstancePtr -> ADC_Tile [ Tile_Id ] . PLL_Settings . RefClkDivider ; PLLSettings -> RefClkFreq = InstancePtr -> ADC_Tile [ Tile_Id ] . PLL_Settings . RefClkFreq ; PLLSettings -> SampleRate = InstancePtr -> ADC_Tile [ Tile_Id ] . PLL_Settings . SampleRate ; Status = XRFDC_SUCCESS ; goto RETURN_PATH ; } else { PLLSettings -> Enabled = InstancePtr -> DAC_Tile [ Tile_Id ] . PLL_Settings . Enabled ; PLLSettings -> FeedbackDivider = InstancePtr -> DAC_Tile [ Tile_Id ] . PLL_Settings . FeedbackDivider ; PLLSettings -> OutputDivider = InstancePtr -> DAC_Tile [ Tile_Id ] . PLL_Settings . OutputDivider ; PLLSettings -> RefClkDivider = InstancePtr -> DAC_Tile [ Tile_Id ] . PLL_Settings . RefClkDivider ; PLLSettings -> RefClkFreq = InstancePtr -> DAC_Tile [ Tile_Id ] . PLL_Settings . RefClkFreq ; PLLSettings -> SampleRate = InstancePtr -> DAC_Tile [ Tile_Id ] . PLL_Settings . SampleRate ; Status = XRFDC_SUCCESS ; goto RETURN_PATH ; } } else { if ( Type == XRFDC_ADC_TILE ) { BaseAddr = XRFDC_ADC_TILE_DRP_ADDR ( Tile_Id ) ; } else { BaseAddr = XRFDC_DAC_TILE_DRP_ADDR ( Tile_Id ) ; } BaseAddr += XRFDC_HSCOM_ADDR ; FeedbackDivider = XRFdc_RDReg ( InstancePtr , BaseAddr , XRFDC_PLL_FPDIV , 0x00FF ) + 2 ; ReadReg = XRFdc_ReadReg16 ( InstancePtr , BaseAddr , XRFDC_PLL_REFDIV ) ; if ( ReadReg & XRFDC_REFCLK_DIV_1_MASK ) { RefClkDivider = XRFDC_REF_CLK_DIV_1 ; } else { switch ( ReadReg & XRFDC_REFCLK_DIV_MASK ) { case XRFDC_REFCLK_DIV_2_MASK : RefClkDivider = XRFDC_REF_CLK_DIV_2 ; break ; case XRFDC_REFCLK_DIV_3_MASK : RefClkDivider = XRFDC_REF_CLK_DIV_3 ; break ; case XRFDC_REFCLK_DIV_4_MASK : RefClkDivider = XRFDC_REF_CLK_DIV_4 ; break ; default : metal_log ( METAL_LOG_ERROR , " \n \r \n " , ( ReadReg & XRFDC_REFCLK_DIV_MASK ) , ( Type == XRFDC_ADC_TILE ) ? " " : " " , Tile_Id , __func__ ) ; Status = XRFDC_FAILURE ; goto RETURN_PATH ; } } if ( XRFdc_GetClockSource ( InstancePtr , Type , Tile_Id , & Enabled ) != XRFDC_SUCCESS ) { Status = XRFDC_FAILURE ; goto RETURN_PATH ; } ReadReg = XRFdc_ReadReg16 ( InstancePtr , BaseAddr , XRFDC_PLL_DIVIDER0 ) ; DivideMode = ( ReadReg & XRFDC_PLL_DIVIDER0_MODE_MASK ) >> XRFDC_PLL_DIVIDER0_SHIFT ; switch ( DivideMode ) { case XRFDC_PLL_OUTDIV_MODE_1 : OutputDivider = 1 ; break ; case XRFDC_PLL_OUTDIV_MODE_2 : OutputDivider = 2 ; break ; case XRFDC_PLL_OUTDIV_MODE_3 : OutputDivider = 3 ; break ; case XRFDC_PLL_OUTDIV_MODE_N : OutputDivider = ( ( ReadReg & XRFDC_PLL_DIVIDER0_VALUE_MASK ) + 2 ) << 1 ; break ; default : metal_log ( METAL_LOG_ERROR , " \n \r \n " , DivideMode , ( Type == XRFDC_ADC_TILE ) ? " " : " " , Tile_Id , __func__ ) ; Status = XRFDC_FAILURE ; goto RETURN_PATH ; break ; } PLLSettings -> Enabled = Enabled ; PLLSettings -> FeedbackDivider = FeedbackDivider ; PLLSettings -> OutputDivider = OutputDivider ; PLLSettings -> RefClkDivider = RefClkDivider ; PLLSettings -> RefClkFreq = RefClkFreq ; PLLSettings -> SampleRate = SampleRate ; } Status = XRFDC_SUCCESS ; RETURN_PATH : return Status ; }
This API is used to get the PLL Configurations.
This API is used to get the PLL Configurations .
/*This code is here to support the old IPs.*/ /*
					 * IP currently supporting 1 to 4 divider values. This
					 * error condition might change in future based on IP update.
					 */