diff --git a/sdbuild/packages/xrfclk/package/README.md b/sdbuild/packages/xrfclk/package/README.md index 897776f16c..cdfd333083 100644 --- a/sdbuild/packages/xrfclk/package/README.md +++ b/sdbuild/packages/xrfclk/package/README.md @@ -3,22 +3,13 @@ This is a package implementing the drivers to configure RF reference clocks for the Xilinx Zynq RFSoC boards (e.g., ZCU111). -## Boards and Chips -For simple (safe) use, refer to `set_ref_clks()`. - -For RFSoC experts, you can specify custom clock frequencies, assuming you -know what you're doing. In that case, you can leverage the following methods: - -1. `set_lmk04208_clks()` for boards with LMK04208. -2. `set_lmk04832_clks()` for boards with LMK04832. -3. `set_lmx2594_clks()` for boards with LMX2594. - -For example, checking ZCU111 schematic, you should be able to find that the -ZCU111 board has LMK04208 and LMX2594 chips. - -For other boards you may also need to adjust the I2C and SPI addresses -specified in `src/xrfdc_clk.h`. +## Instructions +The LMKxxxxx and LMXxxxx clocking configurations are set via the `set_ref_clks()` command: +```python +from xrfclk import set_ref_clks +set_ref_clks(lmk_freq=122.88, lmx_freq=409.6) +``` ## Register Values diff --git a/sdbuild/packages/xrfclk/package/xrfclk/LMK04208_128.00.txt b/sdbuild/packages/xrfclk/package/xrfclk/LMK04208_128.00.txt new file mode 100644 index 0000000000..e19cd61500 --- /dev/null +++ b/sdbuild/packages/xrfclk/package/xrfclk/LMK04208_128.00.txt @@ -0,0 +1,26 @@ +R0 (INIT) 0x00160040 +R0 0x00143000 #PL: SYSREF_FPGA --> 8MHz +R1 0x00143001 #DAC: SYSREF_RFSOC --> 8MHz +R2 0x00140302 #PL: FPGA_REFCLK_OUT --> 128MHz +R3 0xC0140023 #SYNC --> 122.88MHz +R4 0x40140024 #REFIN_2594 --> 122.88MHz +R5 0x80141E05 #SMA: REF_OUT --> 12.8MHz +R6 0x01100006 +R7 0x01100007 +R8 0x06010008 +R9 0x55555549 +R10 0x9102410A +R11 0x0401100B +R12 0x1B0C006C +R13 0x2302886D +R14 0x0200000E +R15 0x8000800F +R16 0xC1550410 +R24 0x00000058 +R25 0x02C9C419 +R26 0x8FA8001A +R27 0x10001E1B +R28 0x0021201C +R29 0x0180033D +R30 0x0200033E +R31 0x003F001F diff --git a/sdbuild/packages/xrfclk/package/xrfclk/LMK04208_256.00.txt b/sdbuild/packages/xrfclk/package/xrfclk/LMK04208_256.00.txt new file mode 100644 index 0000000000..036f6bf401 --- /dev/null +++ b/sdbuild/packages/xrfclk/package/xrfclk/LMK04208_256.00.txt @@ -0,0 +1,26 @@ +R0 (INIT) 0x00160040 +R0 0x00143000 #PL: SYSREF_FPGA --> 8MHz +R1 0x00143001 #DAC: SYSREF_RFSOC --> 8MHz +R2 0x00140182 #PL: FPGA_REFCLK_OUT --> 256MHz +R3 0xC0140023 #SYNC --> 122.88MHz +R4 0x40140024 #REFIN_2594 --> 122.88MHz +R5 0x80141E05 #SMA: REF_OUT --> 12.8MHz +R6 0x01100006 +R7 0x01100007 +R8 0x06010008 +R9 0x55555549 +R10 0x9102410A +R11 0x0401100B +R12 0x1B0C006C +R13 0x2302886D +R14 0x0200000E +R15 0x8000800F +R16 0xC1550410 +R24 0x00000058 +R25 0x02C9C419 +R26 0x8FA8001A +R27 0x10001E1B +R28 0x0021201C +R29 0x0180033D +R30 0x0200033E +R31 0x003F001F diff --git a/sdbuild/packages/xrfdc/package/README.md b/sdbuild/packages/xrfdc/package/README.md index 6424fd1f62..8562876af0 100644 --- a/sdbuild/packages/xrfdc/package/README.md +++ b/sdbuild/packages/xrfdc/package/README.md @@ -119,6 +119,10 @@ u32 XRFdc_GetLinkCoupling(XRFdc *InstancePtr, u32 Tile_Id, u32 Block_Id, u32 *ModePtr); u32 XRFdc_GetFabClkOutDiv(XRFdc *InstancePtr, u32 Type, u32 Tile_Id, u16 *FabClkDivPtr); +u32 XRFdc_MultiConverter_Sync(XRFdc *InstancePtr, u32 Type, + XRFdc_MultiConverter_Sync_Config *ConfigPtr); +void XRFdc_MultiConverter_Init(XRFdc_MultiConverter_Sync_Config *ConfigPtr, + int *PLL_CodesPtr, int *T1_CodesPtr); ``` This list can also be found at the `Function Prototypes` section of @@ -139,6 +143,31 @@ If attempting to use one of these functions on a Gen 1 board, the user will see metal: error: Requested functionality not available for this IP + +## Multi-Tile Synchronization (MTS) +The underlying implementation is based on the [xrfdc_mts_example.c](https://github.com/Xilinx/embeddedsw/blob/master/XilinxProcessorIPLib/drivers/rfdc/examples/xrfdc_mts_example.c), which first defines the MTS configuration object and thereafter performs the actual MTS function call. + +The following code snippet achieves MTS on all ADC (4) and DAC (2) tiles in flow: + +```python +import pynq +import xrfclk +import xrfdc + +#Config RF clocks (optional, lmk_freq and lmx_freq may differ depending on your application) +xrfclk.set_ref_clks(lmk_freq=122.88, lmx_freq=409.6) + +#Load bitstream +ol = pynq.Overlay("bitstream_name.bit") + +#MTS +ol.usp_rf_data_converter_0.mts_adc_config.Tiles = 0xf +ol.usp_rf_data_converter_0.mts_dac_config.Tiles = 0x3 +ol.usp_rf_data_converter_0.mts_adc() +ol.usp_rf_data_converter_0.mts_dac() +``` + + Copyright (C) 2021 Xilinx, Inc SPDX-License-Identifier: BSD-3-Clause diff --git a/sdbuild/packages/xrfdc/package/xrfdc/__init__.py b/sdbuild/packages/xrfdc/package/xrfdc/__init__.py index 3c51faf744..0877242b61 100644 --- a/sdbuild/packages/xrfdc/package/xrfdc/__init__.py +++ b/sdbuild/packages/xrfdc/package/xrfdc/__init__.py @@ -397,10 +397,22 @@ def __init__(self, description): _lib.XRFdc_CfgInitialize(self._instance, self._config) self.adc_tiles = [RFdcAdcTile(self, i) for i in range(4)] self.dac_tiles = [RFdcDacTile(self, i) for i in range(4)] + self.mts_adc_config = _ffi.new('XRFdc_MultiConverter_Sync_Config*') + self.mts_dac_config = _ffi.new('XRFdc_MultiConverter_Sync_Config*') + _safe_wrapper("XRFdc_MultiConverter_Init", self.mts_adc_config, cffi.FFI.NULL, cffi.FFI.NULL) + _safe_wrapper("XRFdc_MultiConverter_Init", self.mts_dac_config, cffi.FFI.NULL, cffi.FFI.NULL) + def _call_function(self, name, *args): _safe_wrapper(f"XRFdc_{name}", self._instance, *args) + def mts_adc(self): + return _safe_wrapper("XRFdc_MultiConverter_Sync", self._instance, 0, self.mts_adc_config) + + def mts_dac(self): + return _safe_wrapper("XRFdc_MultiConverter_Sync", self._instance, 1, self.mts_dac_config) + + # Finally we can add our data-driven properties to each class in the hierarchy diff --git a/sdbuild/packages/xrfdc/package/xrfdc/xrfdc_functions.c b/sdbuild/packages/xrfdc/package/xrfdc/xrfdc_functions.c index ef80b9ff86..8761e9361b 100644 --- a/sdbuild/packages/xrfdc/package/xrfdc/xrfdc_functions.c +++ b/sdbuild/packages/xrfdc/package/xrfdc/xrfdc_functions.c @@ -80,6 +80,44 @@ typedef struct { XRFdc_Distribution DistributionStatus[8]; } XRFdc_Distribution_Settings; +/** + * MTS DTC Settings. + */ +typedef struct { + u32 RefTile; + u32 IsPLL; + int Target[4]; + int Scan_Mode; + int DTC_Code[4]; + int Num_Windows[4]; + int Max_Gap[4]; + int Min_Gap[4]; + int Max_Overlap[4]; +} XRFdc_MTS_DTC_Settings; + +/** + * MTS Sync Settings. + */ +typedef struct { + u32 RefTile; + u32 Tiles; + int Target_Latency; + int Offset[4]; + int Latency[4]; + int Marker_Delay; + int SysRef_Enable; + XRFdc_MTS_DTC_Settings DTC_Set_PLL; + XRFdc_MTS_DTC_Settings DTC_Set_T1; +} XRFdc_MultiConverter_Sync_Config; + +/** + * MTS Marker Struct. + */ +typedef struct { + u32 Count[4]; + u32 Loc[4]; +} XRFdc_MTS_Marker; + /** * ADC Signal Detect Settings. */ @@ -412,6 +450,8 @@ typedef struct { } XRFdc; + + /***************** Macros (Inline Functions) Definitions *********************/ #define XRFDC_ADC_TILE 0U #define XRFDC_DAC_TILE 1U @@ -517,4 +557,6 @@ u32 XRFdc_GetDSA(XRFdc *InstancePtr, u32 Tile_Id, u32 Block_Id, XRFdc_DSA_Settin u32 XRFdc_SetPwrMode(XRFdc *InstancePtr, u32 Type, u32 Tile_Id, u32 Block_Id, XRFdc_Pwr_Mode_Settings *SettingsPtr); u32 XRFdc_GetPwrMode(XRFdc *InstancePtr, u32 Type, u32 Tile_Id, u32 Block_Id, XRFdc_Pwr_Mode_Settings *SettingsPtr); u32 XRFdc_ResetInternalFIFOWidth(XRFdc *InstancePtr, u32 Type, u32 Tile_Id, u32 Block_Id); -u32 XRFdc_ResetInternalFIFOWidthObs(XRFdc *InstancePtr, u32 Tile_Id, u32 Block_Id); \ No newline at end of file +u32 XRFdc_ResetInternalFIFOWidthObs(XRFdc *InstancePtr, u32 Tile_Id, u32 Block_Id); +u32 XRFdc_MultiConverter_Sync(XRFdc *InstancePtr, u32 Type, XRFdc_MultiConverter_Sync_Config *ConfigPtr); +void XRFdc_MultiConverter_Init(XRFdc_MultiConverter_Sync_Config *ConfigPtr, int *PLL_CodesPtr, int *T1_CodesPtr); \ No newline at end of file