mpm/fpga: x4xx: Major updates in preparation for future devices
FPGA: - Split up MB registers that control daughterboard specific settings so that daughterboards 0 and 1 could have different setings, in preparation for future devices that require different settings. This requires a compat number bump to 8.0. - Add registers for additional RFDC information, including the block/tile mapping of the individual channels, and information about resampling capabilities - Identify sections of code that would be specific to X410/ZBX and move them to their own headers, so it's trivial to add device-specific sections of code instead for other devices in the future. - This includes constraints for clocks and I/O pins. - Remove ability to do timed ctrlport transactions to the MB CPLD, this was unused and possibly broken. - Move daughterboard-specific code into its own code location (dboards/zbx) - Move X410-specific register documentation to its own location (doc/X410) - Refactor Makefiles to split out X410/ZBX specific components and allow switching between device types - Add 512-bit AXI interconnects - Make number of timekeepers configurable (X410 keeps the single timekeeper) MPM: - Required compat is bumped to 8.0 - Now supports new registers for detecting DSP capabilities and multi-rate settings for the daughterboards - Adds MMCM controls (currently unused) Co-authored-by: Wade Fife <wade.fife@ni.com> Co-authored-by: Ryan Marlow <ryan@lmarlow.com> Co-authored-by: Martin Braun <martin.braun@ettus.com> Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com> Original-commit: c1d268917ea65dd9c5a42366014cb96d3c025223
This commit is contained in:
committed by
Martin Braun
co-authored by
Wade Fife
Ryan Marlow
Martin Braun
Humberto Jimenez
parent
ffdcc016cc
commit
adf6f576c6
@@ -0,0 +1,509 @@
|
||||
//
|
||||
// Copyright 2021 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: common_regs
|
||||
// Description:
|
||||
// Common registers definition within the x4xx_ps_rfdc_bd between
|
||||
// different x4xx variants.
|
||||
|
||||
//XmlParse xml_on
|
||||
//<regmap name="AXI_HPM0_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
|
||||
// <info>
|
||||
// This is the map for the register space that the Processing System's
|
||||
// M_AXI_HPM0_FPD port (AXI4 master interface) has access to.
|
||||
// This port has a 40-bit address bus.
|
||||
// </info>
|
||||
// <group name="COMMON">
|
||||
// <window name="RPU" offset="0x0080000000" size="0x00010000">
|
||||
// <info>Space reserved for RPU access</info>
|
||||
// </window>
|
||||
// <window name="JTAG_ENGINE" offset="0x1000000000" size="0x1000">
|
||||
// <info>Register space for the JTAG engine for MB CPLD programming.</info>
|
||||
// </window>
|
||||
// <window name="RESERVED" offset="0x100003F000" size="0x1000">
|
||||
// <info>Register space reserved for future use.</info>
|
||||
// </window>
|
||||
// <window name="MPM_ENDPOINT" offset="0x1000080000" size="0x20000"
|
||||
// targetregmap="PL_CPLD_REGMAP">
|
||||
// <info>MPM endpoint fro MB/DB communication.</info>
|
||||
// </window>
|
||||
// <window name="CORE_REGS" offset="0x10000A0000" size="0x4000"
|
||||
// targetregmap="CORE_REGS_REGMAP">
|
||||
// <info>Register space reserved for mboard-regs (Core).</info>
|
||||
// </window>
|
||||
// <window name="INT_ETH_DMA" offset="0x10000A4000" size="0x6000"
|
||||
// targetregmap="ETH_DMA_CTRL_REGMAP">
|
||||
// <info>AXI DMA engine for internal Ethernet interface.</info>
|
||||
// </window>
|
||||
// <window name="INT_ETH_REGS" offset="0x10000AA000" size="0x2000">
|
||||
// <info>Misc. registers for internal Ethernet.</info>
|
||||
// </window>
|
||||
// <window name="RFDC" offset="0x1000100000" size="0x40000">
|
||||
// <info>Register space occupied by the Xilinx RFDC IP block.</info>
|
||||
// </window>
|
||||
// <window name="RFDC_REGS" offset="0x1000140000" size="0x20000"
|
||||
// targetregmap="RFDC_REGS_REGMAP">
|
||||
// <info>Register space for RFDC control/status registers.</info>
|
||||
// </window>
|
||||
// </group>
|
||||
//</regmap>
|
||||
//
|
||||
//<regmap name="ETH_DMA_CTRL_REGMAP" readablestrobes="false" generatevhdl="true" generateverilog="false" ettusguidelines="true">
|
||||
// <info>
|
||||
// This is the map that the nixge driver uses in Ethernet DMA to
|
||||
// move data between the Processing System's architecture and the fabric.
|
||||
// This map is a combination of two main components: a Xilix AXI DMA engine
|
||||
// and some registers for MAC/PHY control.
|
||||
// </info>
|
||||
// <group name="ETH_DMA_CTRL">
|
||||
// <window name="AXI_DMA_CTRL" offset="0x0" size="0x4000">
|
||||
// <info>
|
||||
// Refer to Xilinx' AXI DMA v7.1 IP product guide for further
|
||||
// information on this register map:
|
||||
// https://www.xilinx.com/support/documentation/ip_documentation/axi_dma/v7_1/pg021_axi_dma.pdf
|
||||
// </info>
|
||||
// </window>
|
||||
// <window name="ETH_IO_CTRL" offset="0x4000" size="0x2000">
|
||||
// <info>MAC/PHY control for the Ethernet interface.</info>
|
||||
// </window>
|
||||
// </group>
|
||||
//</regmap>
|
||||
//<regmap name="PL_DMA_MASTER_REGMAP" readablestrobes="false" generatevhdl="true" generateverilog="false" ettusguidelines="true">
|
||||
// <info>
|
||||
// This is a regmap to document the different ports that have access to the PS system memory.
|
||||
// Each port may have different restrictions on system memory. See the corresponding window
|
||||
// for details
|
||||
// </info>
|
||||
// <group name="HPC0_DMA">
|
||||
// <window name="AXI_HPC0_WINDOW" offset="0x0" size="0x10000000000">
|
||||
// <info>
|
||||
// The HPC0 port of the PS is used for general purpose cache-coherent accesses
|
||||
// to the PS system memory. Different applications may use it for different
|
||||
// purposes. Its access is configured as follows: {br}
|
||||
// {table border="1"}
|
||||
// {tr}{th}Offset{/th} {th}Size{/th} {th}Description{/th}{tr}
|
||||
// {tr}{td}0x000800000000{/td}{td}0x000800000000{/td}{td}DDR_HIGH{/td}{tr}
|
||||
// {tr}{td}0x00000000{/td} {td}0x80000000{/td} {td}DDR_LOW{/td}{tr}
|
||||
// {tr}{td}0xFF000000{/td} {td}0x01000000{/td} {td}LPS_OCM{/td}{tr}
|
||||
// {tr}{td}0xC0000000{/td} {td}0x20000000{/td} {td}QSPI{/td}{tr}
|
||||
// {/table}
|
||||
// </info>
|
||||
// </window>
|
||||
// </group>
|
||||
// <group name="HPC1_DMA">
|
||||
// <window name="AXI_HPC1_WINDOW" offset="0x0" size="0x1000000000">
|
||||
// <info>
|
||||
// The HPC1 port of the PS is connected to the Ethernet DMA module. Three slave
|
||||
// interfaces are lumped together in this window: scatter-gather, dma-rx, and dma-tx.
|
||||
// Its access is configured as follows: {br}
|
||||
// {table border="1"}
|
||||
// {tr}{th}Offset{/th} {th}Size{/th} {th}Description{/th}{tr}
|
||||
// {tr}{td}0x000800000000{/td}{td}0x000800000000{/td}{td}DDR_HIGH{/td}{tr}
|
||||
// {tr}{td}0x00000000{/td} {td}0x80000000{/td} {td}DDR_LOW{/td}{tr}
|
||||
// {tr}{td}0xC0000000{/td} {td}0x20000000{/td} {td}QSPI{/td}{tr}
|
||||
// {/table}
|
||||
// </info>
|
||||
// </window>
|
||||
// </group>
|
||||
//</regmap>
|
||||
//<regmap name="RFDC_REGS_REGMAP" readablestrobes="false" generatevhdl="true" generateverilog="true" ettusguidelines="true">
|
||||
// <group name="RFDC_REGS">
|
||||
// <regtype name="RF_RESET_CONTROL_REGTYPE" size="32">
|
||||
// <info>
|
||||
// Control register for the RF reset controller.
|
||||
// Verify the FSM ID before polling starting any reset sequence.
|
||||
// To use the SW reset triggers: Wait until DB*_DONE is de-asserted.
|
||||
// Assert either the *_RESET or *_ENABLE bitfields.
|
||||
// Wait until DB*_DONE is asserted to release the trigger.
|
||||
// The DB*_DONE signal should then de-assert.{BR/}
|
||||
// {b}Note: The *_DB1 constants are not used in the HDL, their purpose is
|
||||
// merely for documentation.{/b}
|
||||
// </info>
|
||||
// <bitfield name="FSM_RESET" range="0">
|
||||
// <info>
|
||||
// Write a '1' to this bit to reset the RF reset controller.
|
||||
// Write a '0' once db0_fsm_reset_done asserts.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_RESET" range="4">
|
||||
// <info>
|
||||
// Write a '1' to this bit to trigger a reset for the
|
||||
// daughterboard 0 ADC chain. Write a '0' once db0_adc_seq_done
|
||||
// is asserted.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_ENABLE" range="5">
|
||||
// <info>
|
||||
// Write a '1' to this bit to trigger the enable sequence for
|
||||
// the daughterboard 0 ADC chain. Write a '0' once
|
||||
// db0_adc_seq_done is asserted.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_RESET" range="8">
|
||||
// <info>
|
||||
// Write a '1' to this bit to trigger a reset for the
|
||||
// daughterboard 0 DAC chain. Write a '0' once db0_dac_seq_done
|
||||
// is asserted.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_ENABLE" range="9">
|
||||
// <info>
|
||||
// Write a '1' to this bit to trigger the enable sequence for
|
||||
// the daughterboard 0 DAC chain. Write a '0' once
|
||||
// db0_dac_seq_done is asserted.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// </regtype>
|
||||
//
|
||||
// <regtype name="RF_RESET_STATUS_REGTYPE" size="32" writable="false">
|
||||
// <info>
|
||||
// Status register for the RF reset controller.
|
||||
// Verify the FSM ID before polling starting any reset sequence.
|
||||
// Refer to RF*_RESET_CONTROL_REG for instructions on how to use
|
||||
// the status bits in this register.{BR/}
|
||||
// {b}Note: The *_DB1 constants are not used in the HDL, their purpose is
|
||||
// merely for documentation.{/b}
|
||||
// </info>
|
||||
// <bitfield name="FSM_RESET_DONE" range="3">
|
||||
// <info>
|
||||
// This bit asserts ('1') when the DB0 RF reset controller FSM
|
||||
// reset sequence is completed. The bitfield deasserts ('0')
|
||||
// after deasserting db0_fsm_reset.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_SEQ_DONE" range="7">
|
||||
// <info>
|
||||
// This bit asserts ('1') when the DB0 ADC chain reset sequence
|
||||
// is completed. The bitfield deasserts ('0') after
|
||||
// deasserting the issued triggered (enable or reset).
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_SEQ_DONE" range="11">
|
||||
// <info>
|
||||
// This bit asserts ('1') when the DB0 DAC chain reset sequence
|
||||
// is completed. The bitfield deasserts ('0') after
|
||||
// deasserting the issued triggered (enable or reset).
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// </regtype>
|
||||
//
|
||||
// <regtype name="RF_AXI_STATUS_REGTYPE" size="32" writable="false">
|
||||
// <info>
|
||||
// Status register for the RF AXI-Stream interfaces.{BR/}
|
||||
// {b}Note: The *_DB1 constants are not used in the HDL, their purpose is
|
||||
// merely for documentation.{/b}
|
||||
// </info>
|
||||
// <bitfield name="RFDC_DAC_TREADY" range="1..0">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's DAC (DB0) AXI-Stream
|
||||
// TReady handshake signals. The LSB is channel 0 and the MSB
|
||||
// is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_DAC_TVALID" range="3..2">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's DAC (DB0) AXI-Stream
|
||||
// TValid handshake signals. The LSB is channel 0 and the MSB
|
||||
// is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_ADC_Q_TREADY" range="5..4">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's ADC (DB0) AXI-Stream
|
||||
// TReady handshake signals (Q portion). The LSB is channel 0
|
||||
// and the MSB is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_ADC_I_TREADY" range="7..6">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's ADC (DB0) AXI-Stream
|
||||
// TReady handshake signals (I portion). The LSB is channel 0
|
||||
// and the MSB is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_ADC_Q_TVALID" range="9..8">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's ADC (DB0) AXI-Stream
|
||||
// TValid handshake signals (Q portion). The LSB is channel 0
|
||||
// and the MSB is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_ADC_I_TVALID" range="11..10">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's ADC (DB0) AXI-Stream
|
||||
// TValid handshake signals (I portion). The LSB is channel 0
|
||||
// and the MSB is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="USER_ADC_TVALID" range="13..12">
|
||||
// <info>
|
||||
// This bitfield is wired to the user's ADC (DB0) AXI-Stream
|
||||
// TValid handshake signals. The LSB is channel 0 and the MSB
|
||||
// is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="USER_ADC_TREADY" range="15..14">
|
||||
// <info>
|
||||
// This bitfield is wired to the user's ADC (DB0) AXI-Stream
|
||||
// TReady handshake signals. The LSB is channel 0 and the MSB
|
||||
// is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_DAC_TREADY_DB1" range="17..16">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's DAC (DB1) AXI-Stream
|
||||
// TReady handshake signals. The LSB is channel 0 and the MSB
|
||||
// is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_DAC_TVALID_DB1" range="19..18">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's DAC (DB1) AXI-Stream
|
||||
// TValid handshake signals. The LSB is channel 0 and the MSB
|
||||
// is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_ADC_Q_TREADY_DB1" range="21..20">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's ADC (DB1) AXI-Stream
|
||||
// TReady handshake signals (Q portion). The LSB is channel 0
|
||||
// and the MSB is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_ADC_I_TREADY_DB1" range="23..22">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's ADC (DB1) AXI-Stream
|
||||
// TReady handshake signals (I portion). The LSB is channel 0
|
||||
// and the MSB is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_ADC_Q_TVALID_DB1" range="25..24">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's ADC (DB1) AXI-Stream
|
||||
// TValid handshake signals (Q portion). The LSB is channel 0
|
||||
// and the MSB is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_ADC_I_TVALID_DB1" range="27..26">
|
||||
// <info>
|
||||
// This bitfield is wired to the RFDC's ADC (DB1) AXI-Stream
|
||||
// TValid handshake signals (I portion). The LSB is channel 0
|
||||
// and the MSB is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="USER_ADC_TVALID_DB1" range="29..28">
|
||||
// <info>
|
||||
// This bitfield is wired to the user's ADC (DB1) AXI-Stream
|
||||
// TValid handshake signals. The LSB is channel 0 and the MSB
|
||||
// is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="USER_ADC_TREADY_DB1" range="31..30">
|
||||
// <info>
|
||||
// This bitfield is wired to the user's ADC (DB1) AXI-Stream
|
||||
// TReady handshake signals. The LSB is channel 0 and the MSB
|
||||
// is channel 1.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// </regtype>
|
||||
//
|
||||
// <enumeratedtype name="FABRIC_DSP_BW_ENUM" showhex="true">
|
||||
// <value name="FABRIC_DSP_BW_NONE" integer="0"/>
|
||||
// <value name="FABRIC_DSP_BW_100M" integer="100"/>
|
||||
// <value name="FABRIC_DSP_BW_200M" integer="200"/>
|
||||
// <value name="FABRIC_DSP_BW_400M" integer="400"/>
|
||||
// <value name="FABRIC_DSP_BW_FULL" integer="1000"/>
|
||||
// </enumeratedtype>
|
||||
//
|
||||
// <regtype name="FABRIC_DSP_REGTYPE" size="32" writable="false">
|
||||
// <info>
|
||||
// This register provides information to the driver on the type
|
||||
// of DSP that is instantiated in the fabric.{BR/}
|
||||
// The X410 platform supports multiple RF daughterboards, each requiring
|
||||
// a different fabric RF DSP chain that works with specific RFDC settings.
|
||||
// Each bandwidth DSP chain has a unique identifier (BW in MHz), this
|
||||
// information is conveyed in this register to let the driver
|
||||
// configure the RFDC with the proper settings.
|
||||
// Also, channel count for the DSP module is included.{BR/}
|
||||
// {b}Note: The *_DB1 constants are not used in the HDL, their purpose is
|
||||
// merely for documentation.{/b}
|
||||
// </info>
|
||||
// <bitfield name="FABRIC_DSP_RX_CNT" range="3..0" initialvalue="0">
|
||||
// <info>Fabric DSP RX channel count for daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="FABRIC_DSP_TX_CNT" range="7..4" initialvalue="0">
|
||||
// <info>Fabric DSP TX channel count for daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="FABRIC_DSP_RESERVED" range="9..8" initialvalue="0">
|
||||
// <info>Reserved for future use.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="FABRIC_DSP_RX_CNT_DB1" range="13..10" initialvalue="0">
|
||||
// <info>Fabric DSP RX channel count for daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="FABRIC_DSP_TX_CNT_DB1" range="17..14" initialvalue="0">
|
||||
// <info>Fabric DSP TX channel count for daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="FABRIC_DSP_RESERVED_DB1" range="19..18" initialvalue="0">
|
||||
// <info>Reserved for future use.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="FABRIC_DSP_BW" range="31..20" type="FABRIC_DSP_BW_ENUM" initialvalue="FABRIC_DSP_BW_NONE">
|
||||
// <info>Fabric DSP BW in MHz for both daughterboards.</info>
|
||||
// </bitfield>
|
||||
// </regtype>
|
||||
//
|
||||
// <regtype name="RFDC_INFO_REGTYPE" size="32" writable="false">
|
||||
// <info>
|
||||
// This register provides information about how the RFDC is connected to
|
||||
// the rest of the fabric.{BR/}
|
||||
// Specifically, between the actual RFDC and the RFNoC infrastructure,
|
||||
// there may be additional resampling (if the RFDC resampler cannot handle
|
||||
// all the resampling itself) and it is important to know how wide the
|
||||
// connection from the RFDC gearbox FIFO to the rest of the design is.
|
||||
// {b}Note: The *_DB1 constants are not used in the HDL, their purpose is
|
||||
// merely for documentation.{/b}
|
||||
// </info>
|
||||
// <bitfield name="RFDC_INFO_XTRA_RESAMP" range="3..0" initialvalue="1">
|
||||
// <info>Additional resampling happening outside the RFDC for daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_INFO_SPC_RX" range="6..4" initialvalue="1">
|
||||
// <info>Log2 of SPC value for RX connection (RFDC into fabric) for daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_INFO_SPC_TX" range="9..7" initialvalue="1">
|
||||
// <info>Log2 of SPC value for TX connection (fabric into RFDC) for daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_INFO_XTRA_RESAMP_DB1" range="19..16" initialvalue="1">
|
||||
// <info>Additional resampling happening outside the RFDC for daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_INFO_SPC_RX_DB1" range="22..20" initialvalue="1">
|
||||
// <info>Log2 of SPC value for RX connection (RFDC into fabric) for daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="RFDC_INFO_SPC_TX_DB1" range="25..23" initialvalue="1">
|
||||
// <info>Log2 of SPC value for TX connection (fabric into RFDC) for daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// </regtype>
|
||||
//
|
||||
// <regtype name="ADC_TILEMAP_REGTYPE" size="32" writable="false">
|
||||
// <info>
|
||||
// This register describes how the ADCs map to the respective tiles. It
|
||||
// lets us designate an ADC as channel 0, channel 1, etc. depending on
|
||||
// how those channels are externally connected to the RFSoC.{BR/}
|
||||
//
|
||||
// For every channel, this register stores the tile number and the block
|
||||
// number of the converter. This can be used to then address the correct
|
||||
// converter in the various Xilinx interfaces/APIs.
|
||||
// </info>
|
||||
// <bitfield name="ADC_TILEMAP_DB0_CHAN0_TILE" range="1..0" initialvalue="0">
|
||||
// <info>Tile number of the ADC for channel 0, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB0_CHAN0_BLOCK" range="3..2" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the ADC for channel 0, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB0_CHAN1_TILE" range="5..4" initialvalue="0">
|
||||
// <info>Tile number of the ADC for channel 1, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB0_CHAN1_BLOCK" range="7..6" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the ADC for channel 1, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB0_CHAN2_TILE" range="9..8" initialvalue="0">
|
||||
// <info>Tile number of the ADC for channel 2, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB0_CHAN2_BLOCK" range="11..10" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the ADC for channel 2, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB0_CHAN3_TILE" range="13..12" initialvalue="0">
|
||||
// <info>Tile number of the ADC for channel 3, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB0_CHAN3_BLOCK" range="15..14" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the ADC for channel 3, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB1_CHAN0_TILE" range="17..16" initialvalue="0">
|
||||
// <info>Tile number of the ADC for channel 0, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB1_CHAN0_BLOCK" range="19..18" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the ADC for channel 0, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB1_CHAN1_TILE" range="21..20" initialvalue="0">
|
||||
// <info>Tile number of the ADC for channel 1, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB1_CHAN1_BLOCK" range="23..22" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the ADC for channel 1, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB1_CHAN2_TILE" range="25..24" initialvalue="0">
|
||||
// <info>Tile number of the ADC for channel 2, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB1_CHAN2_BLOCK" range="27..26" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the ADC for channel 2, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB1_CHAN3_TILE" range="29..28" initialvalue="0">
|
||||
// <info>Tile number of the ADC for channel 3, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ADC_TILEMAP_DB1_CHAN3_BLOCK" range="31..30" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the ADC for channel 3, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// </regtype>
|
||||
// <regtype name="DAC_TILEMAP_REGTYPE" size="32" writable="false">
|
||||
// <info>
|
||||
// This register describes how the DACs map to the respective tiles. It
|
||||
// lets us designate an DAC as channel 0, channel 1, etc. depending on
|
||||
// how those channels are externally connected to the RFSoC.{BR/}
|
||||
//
|
||||
// For every channel, this register stores the tile number and the block
|
||||
// number of the converter. This can be used to then address the correct
|
||||
// converter in the various Xilinx interfaces/APIs.
|
||||
// </info>
|
||||
// <bitfield name="DAC_TILEMAP_DB0_CHAN0_TILE" range="1..0" initialvalue="0">
|
||||
// <info>Tile number of the DAC for channel 0, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB0_CHAN0_BLOCK" range="3..2" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the DAC for channel 0, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB0_CHAN1_TILE" range="5..4" initialvalue="0">
|
||||
// <info>Tile number of the DAC for channel 1, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB0_CHAN1_BLOCK" range="7..6" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the DAC for channel 1, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB0_CHAN2_TILE" range="9..8" initialvalue="0">
|
||||
// <info>Tile number of the DAC for channel 2, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB0_CHAN2_BLOCK" range="11..10" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the DAC for channel 2, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB0_CHAN3_TILE" range="13..12" initialvalue="0">
|
||||
// <info>Tile number of the DAC for channel 3, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB0_CHAN3_BLOCK" range="15..14" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the DAC for channel 3, daughterboard 0.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB1_CHAN0_TILE" range="17..16" initialvalue="0">
|
||||
// <info>Tile number of the DAC for channel 0, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB1_CHAN0_BLOCK" range="19..18" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the DAC for channel 0, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB1_CHAN1_TILE" range="21..20" initialvalue="0">
|
||||
// <info>Tile number of the DAC for channel 1, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB1_CHAN1_BLOCK" range="23..22" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the DAC for channel 1, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB1_CHAN2_TILE" range="25..24" initialvalue="0">
|
||||
// <info>Tile number of the DAC for channel 2, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB1_CHAN2_BLOCK" range="27..26" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the DAC for channel 2, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB1_CHAN3_TILE" range="29..28" initialvalue="0">
|
||||
// <info>Tile number of the DAC for channel 3, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// <bitfield name="DAC_TILEMAP_DB1_CHAN3_BLOCK" range="31..30" initialvalue="0">
|
||||
// <info>Block number (within the tile) of the DAC for channel 3, daughterboard 1.</info>
|
||||
// </bitfield>
|
||||
// </regtype>
|
||||
//
|
||||
//
|
||||
// </group>
|
||||
//</regmap>
|
||||
//XmlParse xml_off
|
||||
@@ -0,0 +1,336 @@
|
||||
//
|
||||
// Copyright 2021 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: uhd_regs
|
||||
// Description:
|
||||
// Registers definition within the x4xx_ps_rfdc_bd IP.
|
||||
|
||||
//XmlParse xml_on
|
||||
//<regmap name="CMAC_REGMAP" markdown="true" generateverilog="false">
|
||||
// <group name="XILINX_CMAC_REGISTERS">
|
||||
// <info>
|
||||
// 100G MAC ethernet registers (Link 0) defined in the CMAC Manual starting on pg 187.
|
||||
//
|
||||
// - http://www.xilinx.com/support/documentation/ip_documentation/cmac_usplus/v2_4/pg203-cmac-usplus.pdf
|
||||
//
|
||||
// </info>
|
||||
// </group>
|
||||
//</regmap>
|
||||
|
||||
//XmlParse xml_on
|
||||
//<regmap name="XGE_MAC_REGMAP" markdown="true" generateverilog="false">
|
||||
// <group name="OPENCORE_XGE_REGISTERS">
|
||||
// <info>
|
||||
//
|
||||
// 10G MAC ethernet registers defined in the USRP OSS distribution fpga/usrp3/lib/xge/doc/xge_mac_spec.pdf
|
||||
//
|
||||
// </info>
|
||||
// </group>
|
||||
//</regmap>
|
||||
|
||||
|
||||
//<regmap name="DMA_REGMAP" markdown="true" generateverilog="false">
|
||||
// <group name="XILINX_DMA_REGISTERS">
|
||||
// <info>
|
||||
// Scatter Gather DMA block defined in Xilinx DMA manual start on pg 11
|
||||
//
|
||||
// - https://www.xilinx.com/support/documentation/ip_documentation/axi_dma/v7_1/pg021_axi_dma.pdf
|
||||
//
|
||||
// </info>
|
||||
// </group>
|
||||
//</regmap>
|
||||
|
||||
//<regmap name="NIXGE_REGMAP" markdown="true" generateverilog="false">
|
||||
// <group name="XGE_MAC_WINDOW">
|
||||
// <window name="XGE_MAC" offset="0x1000" size="0x1000" targetregmap="XGE_MAC_REGMAP"/>
|
||||
// </group>
|
||||
// <group name="XGE_MAC_REGS">
|
||||
// <info>
|
||||
// nixge (maps to 10g mac if present)
|
||||
// </info>
|
||||
// <register name="PORT_INFO" offset="0x0000">
|
||||
// <bitfield name="COMPAT_NUM" range="31..24">
|
||||
// <info>
|
||||
// Constant indicating version for this space.
|
||||
// Not used by the NIXGE driver (12/4/2020)
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="ACTIVITY" range="17">
|
||||
// <info>
|
||||
// Generically this mirrors the activity LED. Specific meaning varies based on the MGT_PROTOCOL.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="LINK_UP" range="16">
|
||||
// <info>
|
||||
// Generically means that a connection with a peer has been established. Specific
|
||||
// meaning varies based on the MGT_PROTOCOL.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="MGT_PROTOCOL" range="15..8">
|
||||
// <info>
|
||||
// Constant indicating what flavor of communication this port is using
|
||||
//
|
||||
// - 0 = NONE
|
||||
// - 1 = 1GbE
|
||||
// - 2 = 10GbE
|
||||
// - 3 = Aurora
|
||||
// - 4 = WhiteRabbit
|
||||
// - 5 = 100GbE
|
||||
//
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="PORTNUM" range="7..0">
|
||||
// <info>
|
||||
// Constant indicating which port this register is hooked to
|
||||
//
|
||||
// - 0 = QSFP0
|
||||
// - 1 = QSFP1
|
||||
//
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// </register>
|
||||
// <register name="MAC_CTRL_STATUS" offset="0x0004">
|
||||
// <info>
|
||||
// Definition of this register depends on Protocol
|
||||
//
|
||||
// **10GBE**
|
||||
//
|
||||
// *READ - Status*
|
||||
//
|
||||
// - 0 = status_crc_error
|
||||
// - 1 = status_fragment_error
|
||||
// - 2 = status_txdfifo_ovflow
|
||||
// - 3 = status_txdfifo_udflow
|
||||
// - 4 = status_rxdfifo_ovflow
|
||||
// - 5 = status_rxdfifo_udflow
|
||||
// - 6 = status_pause_frame_rx
|
||||
// - 7 = status_local_fault
|
||||
// - 8 = status_remote_fault
|
||||
//
|
||||
// *WRITE - Ctl*
|
||||
//
|
||||
// - 0 = ctrl_tx_enable
|
||||
//
|
||||
// **100 GBE**
|
||||
//
|
||||
// *READ - Status*
|
||||
//
|
||||
// - 0 = tx_ovfout - Sets if TX overflow reported by CMAC
|
||||
// (Stays set till MAC is reset). This is a fatal error
|
||||
// - 1 = tx_unfout - Sets if TX underflow reported by CMAC
|
||||
// (Stays set till MAC is reset). This is a fatal error
|
||||
// - 2 = stat_rx_aligned - goes high when CMAC has finished
|
||||
// alignment, and is ready to start reception of traffic.
|
||||
// - 3 = mac_dropped_packet - If the mac RX wants to push data(TVALID)
|
||||
// but upstream is trying to hold(TREADY)off we drop a packet.
|
||||
// Upstream circuitry should detect this when traffic is forked
|
||||
// between CHDR and CPU, so this bit will only set if there is a
|
||||
// HW design error.
|
||||
// - 4 = auto_config_done - This bit goes high when the auto_config
|
||||
// state machine finishes operation. It is very similiar to
|
||||
// stat_rx_alligned, but waits for extra writes which occur
|
||||
// after allignement to complete.
|
||||
// - 24:16 = pause_mask - readable version of pause_mask bellow.
|
||||
//
|
||||
// *WRITE - Ctl*
|
||||
//
|
||||
// - 0 = auto_enable - Defaults to ON after reset - Enables a
|
||||
// state machine that performs CMAC register writes to
|
||||
// bring up the MAC without SW intervention.
|
||||
// - 24:16 = pause_mask - A second layer of enables(the first being
|
||||
// register in the CMAC) on the pause_request mechanic. Bits
|
||||
// 7:0 of enable pause on PFC7:0. Bit 8 enables global pause
|
||||
// request (not priority controlled). The mask is used for TX
|
||||
// and RX.
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="MAC_PHY_STATUS" offset="0x0008">
|
||||
// <info>
|
||||
//
|
||||
// Definition of this register depends on Protocol
|
||||
//
|
||||
// **10GBE**
|
||||
//
|
||||
// *READ - Status *
|
||||
//
|
||||
// - 0 = core_status 0 - link_up
|
||||
// - 1 = core_status 1
|
||||
// - 2 = core_status 2
|
||||
// - 3 = core_status 3
|
||||
// - 4 = core_status 4
|
||||
// - 5 = core_status 5
|
||||
// - 6 = core_status 6
|
||||
// - 7 = core_status 7
|
||||
//
|
||||
// **100 GBE**
|
||||
//
|
||||
// *READ - Status*
|
||||
//
|
||||
// - 0 = usr_tx_reset - TX PLL's have locked - The clock for the 100G mac isn't stable till this bit sets.
|
||||
// - 1 = usr_rx_reset - RX PLL's have locked
|
||||
//
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="MAC_LED_CTL" offset="0x000C">
|
||||
// <bitfield name="identify_enable" range="0">
|
||||
// <info>
|
||||
// When set identify_value is used to control the activity LED.
|
||||
// When clear the activity LED set on any TX or RX traffic to the mgt
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="identify_value" range="1">
|
||||
// <info>
|
||||
// When identify_enable is set, this value controls the activity LED.
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// </register>
|
||||
// <register name="ETH_MDIO_BASE" offset="0x0010">
|
||||
// <info>
|
||||
// The x4xx family of products does not use MDIO.
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="AURORA_OVERRUNS" offset="0x0020">
|
||||
// <info>
|
||||
// Only valid if the protocol is Aurora.
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="AURORA_CHECKSUM_ERRORS" offset="0x0024">
|
||||
// <info>
|
||||
// Only valid if the protocol is Aurora.
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="AURORA_BIST_CHECKER_SAMPS" offset="0x0028">
|
||||
// <info>
|
||||
// Only valid if the protocol is Aurora.
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="AURORA_BIST_CHECKER_ERRORS" offset="0x002C">
|
||||
// <info>
|
||||
// Only valid if the protocol is Aurora.
|
||||
// </info>
|
||||
// </register>
|
||||
// </group>
|
||||
//</regmap>
|
||||
//
|
||||
//<regmap name="UIO_REGMAP" markdown="true" generateverilog="false">
|
||||
// <group name="UIO_REGS">
|
||||
// <info>
|
||||
// UIO
|
||||
// </info>
|
||||
// <register name="IP" offset="0x0000">
|
||||
// <info>
|
||||
// Set this port's IP address
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="UDP" offset="0x0004">
|
||||
// <info>
|
||||
// Set the UDP port for CHDR_traffic
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="BRIDGE_MAC_LSB" offset="0x0010">
|
||||
// <info>
|
||||
// If BRIDGE_ENABLE is set use this MAC_ID
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="BRIDGE_MAC_MSB" offset="0x0014">
|
||||
// <info>
|
||||
// If BRIDGE_ENABLE is set use this MAC_ID
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="BRIDGE_IP" offset="0x0018">
|
||||
// <info>
|
||||
// If BRIDGE_ENABLE is set use this IP Address
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="BRIDGE_UDP" offset="0x001C">
|
||||
// <info>
|
||||
// If BRIDGE_ENABLE is set use this UDP Port for CHDR_traffic
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="BRIDGE_ENABLE" offset="0x0020">
|
||||
// <info>
|
||||
// Bit 0 Controls the following logic
|
||||
//
|
||||
//```verilog
|
||||
// always_comb begin : bridge_mux
|
||||
// my_mac = bridge_en ? bridge_mac_reg : mac_reg;
|
||||
// my_ip = bridge_en ? bridge_ip_reg : ip_reg;
|
||||
// my_udp_chdr_port = bridge_en ? bridge_udp_port : udp_port;
|
||||
// end
|
||||
//```
|
||||
//
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="CHDR_DROPPED" offset="0x0030">
|
||||
// <info>
|
||||
// Count the number of Packets dropped that were addressed to the CHDR section.
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="CPU_DROPPED" offset="0x0034">
|
||||
// <info>
|
||||
// Count the number of Packets dropped that were addressed to us, but not to the CHDR section.
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="PAUSE" offset="0x0038">
|
||||
// <bitfield name="pause_set" range="15..0">
|
||||
// <info>
|
||||
// If the fullness of the CHDR_FIFO in ETH_W words exceeds this value request an ethernet pause. This feature is only
|
||||
// used with 100Gb ethernet
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// <bitfield name="pause_clear" range="31..16">
|
||||
// <info>
|
||||
// If the fullness of the CHDR_FIFO in ETH_W words falls bellow this value stop requesting an ethernet pause.
|
||||
// *Pause clear must be less than pause set or terrible things will happen.*
|
||||
// The clearing of the pause request causes the MAC to send a request to resume traffic. This feature is only
|
||||
// used with 100Gb ethernet
|
||||
// </info>
|
||||
// </bitfield>
|
||||
// </register>
|
||||
// </group>
|
||||
//</regmap>
|
||||
|
||||
//<regmap name="QSFP_REGMAP" markdown="true" generateverilog="false">
|
||||
// <group name="QSFP_WINDOWS">
|
||||
// <info>
|
||||
// Register space for a single QSFP Communication port. This currently breaks into 2 possible configurations
|
||||
//
|
||||
// - 1X10GB Ethernet - Using OpenCore XGE MAC
|
||||
// - 1x100GB Ethernet - Using Xilinx CMAC
|
||||
// - (future possible) - Xilinx Aurora (various rates and lane widths)
|
||||
// - (future possible) - 4X10GB Ethernet
|
||||
//
|
||||
// </info>
|
||||
// <window name="ETH_DMA" offset="0x000" size="0x4000" targetregmap="DMA_REGMAP"/>
|
||||
// <window name="NIXGE" offset="0x8000" size="0x2000" targetregmap="NIXGE_REGMAP"/>
|
||||
// <window name="UIO" offset="0xA000" size="0x2000" targetregmap="UIO_REGMAP"/>
|
||||
// <window name="CMAC" offset="0xC000" size="0x2000" targetregmap="CMAC_REGMAP"/>
|
||||
// </group>
|
||||
//</regmap>
|
||||
|
||||
|
||||
//<regmap name="AXI_HPM0_REGMAP" markdown="true" generateverilog="false">
|
||||
// <group name="UHD_ONLY">
|
||||
// <info>
|
||||
// - 0_0 indicates QSFP0 - Lane0 or a 4 LANE QSFP0
|
||||
// - 0_1 indicates QSFP0 - Lane1
|
||||
// - 0_2 indicates QSFP0 - Lane2
|
||||
// - 0_3 indicates QSFP0 - Lane3
|
||||
// - 1_0 indicates QSFP1 - Lane0 or a 4 LANE QSFP1
|
||||
// - 1_1 indicates QSFP1 - Lane1
|
||||
// - 1_2 indicates QSFP1 - Lane2
|
||||
// - 1_3 indicates QSFP1 - Lane3
|
||||
// </info>
|
||||
// <window name="QSFP_0_0" offset="0x1200000000" size="0x10000" targetregmap="QSFP_REGMAP"/>
|
||||
// <window name="QSFP_0_1" offset="0x1200010000" size="0x10000" targetregmap="QSFP_REGMAP"/>
|
||||
// <window name="QSFP_0_2" offset="0x1200020000" size="0x10000" targetregmap="QSFP_REGMAP"/>
|
||||
// <window name="QSFP_0_3" offset="0x1200030000" size="0x10000" targetregmap="QSFP_REGMAP"/>
|
||||
// <window name="QSFP_1_0" offset="0x1200040000" size="0x10000" targetregmap="QSFP_REGMAP"/>
|
||||
// <window name="QSFP_1_1" offset="0x1200050000" size="0x10000" targetregmap="QSFP_REGMAP"/>
|
||||
// <window name="QSFP_1_2" offset="0x1200060000" size="0x10000" targetregmap="QSFP_REGMAP"/>
|
||||
// <window name="QSFP_1_3" offset="0x1200070000" size="0x10000" targetregmap="QSFP_REGMAP"/>
|
||||
// </group>
|
||||
//</regmap>
|
||||
//XmlParse xml_off
|
||||
Reference in New Issue
Block a user