1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0+ 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun==================== 4*4882a593SmuzhiyunXilinx SD-FEC Driver 5*4882a593Smuzhiyun==================== 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunOverview 8*4882a593Smuzhiyun======== 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunThis driver supports SD-FEC Integrated Block for Zynq |Ultrascale+ (TM)| RFSoCs. 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun.. |Ultrascale+ (TM)| unicode:: Ultrascale+ U+2122 13*4882a593Smuzhiyun .. with trademark sign 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunFor a full description of SD-FEC core features, see the `SD-FEC Product Guide (PG256) <https://www.xilinx.com/cgi-bin/docs/ipdoc?c=sd_fec;v=latest;d=pg256-sdfec-integrated-block.pdf>`_ 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunThis driver supports the following features: 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun - Retrieval of the Integrated Block configuration and status information 20*4882a593Smuzhiyun - Configuration of LDPC codes 21*4882a593Smuzhiyun - Configuration of Turbo decoding 22*4882a593Smuzhiyun - Monitoring errors 23*4882a593Smuzhiyun 24*4882a593SmuzhiyunMissing features, known issues, and limitations of the SD-FEC driver are as 25*4882a593Smuzhiyunfollows: 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun - Only allows a single open file handler to any instance of the driver at any time 28*4882a593Smuzhiyun - Reset of the SD-FEC Integrated Block is not controlled by this driver 29*4882a593Smuzhiyun - Does not support shared LDPC code table wraparound 30*4882a593Smuzhiyun 31*4882a593SmuzhiyunThe device tree entry is described in: 32*4882a593Smuzhiyun`linux-xlnx/Documentation/devicetree/bindings/misc/xlnx,sd-fec.txt <https://github.com/Xilinx/linux-xlnx/blob/master/Documentation/devicetree/bindings/misc/xlnx%2Csd-fec.txt>`_ 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun 35*4882a593SmuzhiyunModes of Operation 36*4882a593Smuzhiyun------------------ 37*4882a593Smuzhiyun 38*4882a593SmuzhiyunThe driver works with the SD-FEC core in two modes of operation: 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun - Run-time configuration 41*4882a593Smuzhiyun - Programmable Logic (PL) initialization 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun 44*4882a593SmuzhiyunRun-time Configuration 45*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~ 46*4882a593Smuzhiyun 47*4882a593SmuzhiyunFor Run-time configuration the role of driver is to allow the software application to do the following: 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun - Load the configuration parameters for either Turbo decode or LDPC encode or decode 50*4882a593Smuzhiyun - Activate the SD-FEC core 51*4882a593Smuzhiyun - Monitor the SD-FEC core for errors 52*4882a593Smuzhiyun - Retrieve the status and configuration of the SD-FEC core 53*4882a593Smuzhiyun 54*4882a593SmuzhiyunProgrammable Logic (PL) Initialization 55*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 56*4882a593Smuzhiyun 57*4882a593SmuzhiyunFor PL initialization, supporting logic loads configuration parameters for either 58*4882a593Smuzhiyunthe Turbo decode or LDPC encode or decode. The role of the driver is to allow 59*4882a593Smuzhiyunthe software application to do the following: 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun - Activate the SD-FEC core 62*4882a593Smuzhiyun - Monitor the SD-FEC core for errors 63*4882a593Smuzhiyun - Retrieve the status and configuration of the SD-FEC core 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun 66*4882a593SmuzhiyunDriver Structure 67*4882a593Smuzhiyun================ 68*4882a593Smuzhiyun 69*4882a593SmuzhiyunThe driver provides a platform device where the ``probe`` and ``remove`` 70*4882a593Smuzhiyunoperations are provided. 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun - probe: Updates configuration register with device-tree entries plus determines the current activate state of the core, for example, is the core bypassed or has the core been started. 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun 75*4882a593SmuzhiyunThe driver defines the following driver file operations to provide user 76*4882a593Smuzhiyunapplication interfaces: 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun - open: Implements restriction that only a single file descriptor can be open per SD-FEC instance at any time 79*4882a593Smuzhiyun - release: Allows another file descriptor to be open, that is after current file descriptor is closed 80*4882a593Smuzhiyun - poll: Provides a method to monitor for SD-FEC Error events 81*4882a593Smuzhiyun - unlocked_ioctl: Provides the following ioctl commands that allows the application configure the SD-FEC core: 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun - :c:macro:`XSDFEC_START_DEV` 84*4882a593Smuzhiyun - :c:macro:`XSDFEC_STOP_DEV` 85*4882a593Smuzhiyun - :c:macro:`XSDFEC_GET_STATUS` 86*4882a593Smuzhiyun - :c:macro:`XSDFEC_SET_IRQ` 87*4882a593Smuzhiyun - :c:macro:`XSDFEC_SET_TURBO` 88*4882a593Smuzhiyun - :c:macro:`XSDFEC_ADD_LDPC_CODE_PARAMS` 89*4882a593Smuzhiyun - :c:macro:`XSDFEC_GET_CONFIG` 90*4882a593Smuzhiyun - :c:macro:`XSDFEC_SET_ORDER` 91*4882a593Smuzhiyun - :c:macro:`XSDFEC_SET_BYPASS` 92*4882a593Smuzhiyun - :c:macro:`XSDFEC_IS_ACTIVE` 93*4882a593Smuzhiyun - :c:macro:`XSDFEC_CLEAR_STATS` 94*4882a593Smuzhiyun - :c:macro:`XSDFEC_SET_DEFAULT_CONFIG` 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun 97*4882a593SmuzhiyunDriver Usage 98*4882a593Smuzhiyun============ 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun 101*4882a593SmuzhiyunOverview 102*4882a593Smuzhiyun-------- 103*4882a593Smuzhiyun 104*4882a593SmuzhiyunAfter opening the driver, the user should find out what operations need to be 105*4882a593Smuzhiyunperformed to configure and activate the SD-FEC core and determine the 106*4882a593Smuzhiyunconfiguration of the driver. 107*4882a593SmuzhiyunThe following outlines the flow the user should perform: 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun - Determine Configuration 110*4882a593Smuzhiyun - Set the order, if not already configured as desired 111*4882a593Smuzhiyun - Set Turbo decode, LPDC encode or decode parameters, depending on how the 112*4882a593Smuzhiyun SD-FEC core is configured plus if the SD-FEC has not been configured for PL 113*4882a593Smuzhiyun initialization 114*4882a593Smuzhiyun - Enable interrupts, if not already enabled 115*4882a593Smuzhiyun - Bypass the SD-FEC core, if required 116*4882a593Smuzhiyun - Start the SD-FEC core if not already started 117*4882a593Smuzhiyun - Get the SD-FEC core status 118*4882a593Smuzhiyun - Monitor for interrupts 119*4882a593Smuzhiyun - Stop the SD-FEC core 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun 122*4882a593SmuzhiyunNote: When monitoring for interrupts if a critical error is detected where a reset is required, the driver will be required to load the default configuration. 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun 125*4882a593SmuzhiyunDetermine Configuration 126*4882a593Smuzhiyun----------------------- 127*4882a593Smuzhiyun 128*4882a593SmuzhiyunDetermine the configuration of the SD-FEC core by using the ioctl 129*4882a593Smuzhiyun:c:macro:`XSDFEC_GET_CONFIG`. 130*4882a593Smuzhiyun 131*4882a593SmuzhiyunSet the Order 132*4882a593Smuzhiyun------------- 133*4882a593Smuzhiyun 134*4882a593SmuzhiyunSetting the order determines how the order of Blocks can change from input to output. 135*4882a593Smuzhiyun 136*4882a593SmuzhiyunSetting the order is done by using the ioctl :c:macro:`XSDFEC_SET_ORDER` 137*4882a593Smuzhiyun 138*4882a593SmuzhiyunSetting the order can only be done if the following restrictions are met: 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun - The ``state`` member of struct :c:type:`xsdfec_status <xsdfec_status>` filled by the ioctl :c:macro:`XSDFEC_GET_STATUS` indicates the SD-FEC core has not STARTED 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun 143*4882a593SmuzhiyunAdd LDPC Codes 144*4882a593Smuzhiyun-------------- 145*4882a593Smuzhiyun 146*4882a593SmuzhiyunThe following steps indicate how to add LDPC codes to the SD-FEC core: 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun - Use the auto-generated parameters to fill the :c:type:`struct xsdfec_ldpc_params <xsdfec_ldpc_params>` for the desired LDPC code. 149*4882a593Smuzhiyun - Set the SC, QA, and LA table offsets for the LPDC parameters and the parameters in the structure :c:type:`struct xsdfec_ldpc_params <xsdfec_ldpc_params>` 150*4882a593Smuzhiyun - Set the desired Code Id value in the structure :c:type:`struct xsdfec_ldpc_params <xsdfec_ldpc_params>` 151*4882a593Smuzhiyun - Add the LPDC Code Parameters using the ioctl :c:macro:`XSDFEC_ADD_LDPC_CODE_PARAMS` 152*4882a593Smuzhiyun - For the applied LPDC Code Parameter use the function :c:func:`xsdfec_calculate_shared_ldpc_table_entry_size` to calculate the size of shared LPDC code tables. This allows the user to determine the shared table usage so when selecting the table offsets for the next LDPC code parameters unused table areas can be selected. 153*4882a593Smuzhiyun - Repeat for each LDPC code parameter. 154*4882a593Smuzhiyun 155*4882a593SmuzhiyunAdding LDPC codes can only be done if the following restrictions are met: 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun - The ``code`` member of :c:type:`struct xsdfec_config <xsdfec_config>` filled by the ioctl :c:macro:`XSDFEC_GET_CONFIG` indicates the SD-FEC core is configured as LDPC 158*4882a593Smuzhiyun - The ``code_wr_protect`` of :c:type:`struct xsdfec_config <xsdfec_config>` filled by the ioctl :c:macro:`XSDFEC_GET_CONFIG` indicates that write protection is not enabled 159*4882a593Smuzhiyun - The ``state`` member of struct :c:type:`xsdfec_status <xsdfec_status>` filled by the ioctl :c:macro:`XSDFEC_GET_STATUS` indicates the SD-FEC core has not started 160*4882a593Smuzhiyun 161*4882a593SmuzhiyunSet Turbo Decode 162*4882a593Smuzhiyun---------------- 163*4882a593Smuzhiyun 164*4882a593SmuzhiyunConfiguring the Turbo decode parameters is done by using the ioctl :c:macro:`XSDFEC_SET_TURBO` using auto-generated parameters to fill the :c:type:`struct xsdfec_turbo <xsdfec_turbo>` for the desired Turbo code. 165*4882a593Smuzhiyun 166*4882a593SmuzhiyunAdding Turbo decode can only be done if the following restrictions are met: 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun - The ``code`` member of :c:type:`struct xsdfec_config <xsdfec_config>` filled by the ioctl :c:macro:`XSDFEC_GET_CONFIG` indicates the SD-FEC core is configured as TURBO 169*4882a593Smuzhiyun - The ``state`` member of struct :c:type:`xsdfec_status <xsdfec_status>` filled by the ioctl :c:macro:`XSDFEC_GET_STATUS` indicates the SD-FEC core has not STARTED 170*4882a593Smuzhiyun 171*4882a593SmuzhiyunEnable Interrupts 172*4882a593Smuzhiyun----------------- 173*4882a593Smuzhiyun 174*4882a593SmuzhiyunEnabling or disabling interrupts is done by using the ioctl :c:macro:`XSDFEC_SET_IRQ`. The members of the parameter passed, :c:type:`struct xsdfec_irq <xsdfec_irq>`, to the ioctl are used to set and clear different categories of interrupts. The category of interrupt is controlled as following: 175*4882a593Smuzhiyun 176*4882a593Smuzhiyun - ``enable_isr`` controls the ``tlast`` interrupts 177*4882a593Smuzhiyun - ``enable_ecc_isr`` controls the ECC interrupts 178*4882a593Smuzhiyun 179*4882a593SmuzhiyunIf the ``code`` member of :c:type:`struct xsdfec_config <xsdfec_config>` filled by the ioctl :c:macro:`XSDFEC_GET_CONFIG` indicates the SD-FEC core is configured as TURBO then the enabling ECC errors is not required. 180*4882a593Smuzhiyun 181*4882a593SmuzhiyunBypass the SD-FEC 182*4882a593Smuzhiyun----------------- 183*4882a593Smuzhiyun 184*4882a593SmuzhiyunBypassing the SD-FEC is done by using the ioctl :c:macro:`XSDFEC_SET_BYPASS` 185*4882a593Smuzhiyun 186*4882a593SmuzhiyunBypassing the SD-FEC can only be done if the following restrictions are met: 187*4882a593Smuzhiyun 188*4882a593Smuzhiyun - The ``state`` member of :c:type:`struct xsdfec_status <xsdfec_status>` filled by the ioctl :c:macro:`XSDFEC_GET_STATUS` indicates the SD-FEC core has not STARTED 189*4882a593Smuzhiyun 190*4882a593SmuzhiyunStart the SD-FEC core 191*4882a593Smuzhiyun--------------------- 192*4882a593Smuzhiyun 193*4882a593SmuzhiyunStart the SD-FEC core by using the ioctl :c:macro:`XSDFEC_START_DEV` 194*4882a593Smuzhiyun 195*4882a593SmuzhiyunGet SD-FEC Status 196*4882a593Smuzhiyun----------------- 197*4882a593Smuzhiyun 198*4882a593SmuzhiyunGet the SD-FEC status of the device by using the ioctl :c:macro:`XSDFEC_GET_STATUS`, which will fill the :c:type:`struct xsdfec_status <xsdfec_status>` 199*4882a593Smuzhiyun 200*4882a593SmuzhiyunMonitor for Interrupts 201*4882a593Smuzhiyun---------------------- 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun - Use the poll system call to monitor for an interrupt. The poll system call waits for an interrupt to wake it up or times out if no interrupt occurs. 204*4882a593Smuzhiyun - On return Poll ``revents`` will indicate whether stats and/or state have been updated 205*4882a593Smuzhiyun - ``POLLPRI`` indicates a critical error and the user should use :c:macro:`XSDFEC_GET_STATUS` and :c:macro:`XSDFEC_GET_STATS` to confirm 206*4882a593Smuzhiyun - ``POLLRDNORM`` indicates a non-critical error has occurred and the user should use :c:macro:`XSDFEC_GET_STATS` to confirm 207*4882a593Smuzhiyun - Get stats by using the ioctl :c:macro:`XSDFEC_GET_STATS` 208*4882a593Smuzhiyun - For critical error the ``isr_err_count`` or ``uecc_count`` member of :c:type:`struct xsdfec_stats <xsdfec_stats>` is non-zero 209*4882a593Smuzhiyun - For non-critical errors the ``cecc_count`` member of :c:type:`struct xsdfec_stats <xsdfec_stats>` is non-zero 210*4882a593Smuzhiyun - Get state by using the ioctl :c:macro:`XSDFEC_GET_STATUS` 211*4882a593Smuzhiyun - For a critical error the ``state`` of :c:type:`xsdfec_status <xsdfec_status>` will indicate a Reset Is Required 212*4882a593Smuzhiyun - Clear stats by using the ioctl :c:macro:`XSDFEC_CLEAR_STATS` 213*4882a593Smuzhiyun 214*4882a593SmuzhiyunIf a critical error is detected where a reset is required. The application is required to call the ioctl :c:macro:`XSDFEC_SET_DEFAULT_CONFIG`, after the reset and it is not required to call the ioctl :c:macro:`XSDFEC_STOP_DEV` 215*4882a593Smuzhiyun 216*4882a593SmuzhiyunNote: Using poll system call prevents busy looping using :c:macro:`XSDFEC_GET_STATS` and :c:macro:`XSDFEC_GET_STATUS` 217*4882a593Smuzhiyun 218*4882a593SmuzhiyunStop the SD-FEC Core 219*4882a593Smuzhiyun--------------------- 220*4882a593Smuzhiyun 221*4882a593SmuzhiyunStop the device by using the ioctl :c:macro:`XSDFEC_STOP_DEV` 222*4882a593Smuzhiyun 223*4882a593SmuzhiyunSet the Default Configuration 224*4882a593Smuzhiyun----------------------------- 225*4882a593Smuzhiyun 226*4882a593SmuzhiyunLoad default configuration by using the ioctl :c:macro:`XSDFEC_SET_DEFAULT_CONFIG` to restore the driver. 227*4882a593Smuzhiyun 228*4882a593SmuzhiyunLimitations 229*4882a593Smuzhiyun----------- 230*4882a593Smuzhiyun 231*4882a593SmuzhiyunUsers should not duplicate SD-FEC device file handlers, for example fork() or dup() a process that has a created an SD-FEC file handler. 232*4882a593Smuzhiyun 233*4882a593SmuzhiyunDriver IOCTLs 234*4882a593Smuzhiyun============== 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun.. c:macro:: XSDFEC_START_DEV 237*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 238*4882a593Smuzhiyun :doc: XSDFEC_START_DEV 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun.. c:macro:: XSDFEC_STOP_DEV 241*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 242*4882a593Smuzhiyun :doc: XSDFEC_STOP_DEV 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun.. c:macro:: XSDFEC_GET_STATUS 245*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 246*4882a593Smuzhiyun :doc: XSDFEC_GET_STATUS 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun.. c:macro:: XSDFEC_SET_IRQ 249*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 250*4882a593Smuzhiyun :doc: XSDFEC_SET_IRQ 251*4882a593Smuzhiyun 252*4882a593Smuzhiyun.. c:macro:: XSDFEC_SET_TURBO 253*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 254*4882a593Smuzhiyun :doc: XSDFEC_SET_TURBO 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun.. c:macro:: XSDFEC_ADD_LDPC_CODE_PARAMS 257*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 258*4882a593Smuzhiyun :doc: XSDFEC_ADD_LDPC_CODE_PARAMS 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun.. c:macro:: XSDFEC_GET_CONFIG 261*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 262*4882a593Smuzhiyun :doc: XSDFEC_GET_CONFIG 263*4882a593Smuzhiyun 264*4882a593Smuzhiyun.. c:macro:: XSDFEC_SET_ORDER 265*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 266*4882a593Smuzhiyun :doc: XSDFEC_SET_ORDER 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun.. c:macro:: XSDFEC_SET_BYPASS 269*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 270*4882a593Smuzhiyun :doc: XSDFEC_SET_BYPASS 271*4882a593Smuzhiyun 272*4882a593Smuzhiyun.. c:macro:: XSDFEC_IS_ACTIVE 273*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 274*4882a593Smuzhiyun :doc: XSDFEC_IS_ACTIVE 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun.. c:macro:: XSDFEC_CLEAR_STATS 277*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 278*4882a593Smuzhiyun :doc: XSDFEC_CLEAR_STATS 279*4882a593Smuzhiyun 280*4882a593Smuzhiyun.. c:macro:: XSDFEC_GET_STATS 281*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 282*4882a593Smuzhiyun :doc: XSDFEC_GET_STATS 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun.. c:macro:: XSDFEC_SET_DEFAULT_CONFIG 285*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 286*4882a593Smuzhiyun :doc: XSDFEC_SET_DEFAULT_CONFIG 287*4882a593Smuzhiyun 288*4882a593SmuzhiyunDriver Type Definitions 289*4882a593Smuzhiyun======================= 290*4882a593Smuzhiyun 291*4882a593Smuzhiyun.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h 292*4882a593Smuzhiyun :internal: 293