linux/drivers/media/platform/xilinx/xilinx-sdirxss.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Xilinx SDI Rx Subsystem
   4 *
   5 * Copyright (C) 2017 Xilinx, Inc.
   6 *
   7 * Contacts: Vishal Sagar <vsagar@xilinx.com>
   8 *
   9 */
  10
  11#include <dt-bindings/media/xilinx-vip.h>
  12#include <linux/bitfield.h>
  13#include <linux/bitops.h>
  14#include <linux/compiler.h>
  15#include <linux/clk.h>
  16#include <linux/delay.h>
  17#include <linux/device.h>
  18#include <linux/interrupt.h>
  19#include <linux/io.h>
  20#include <linux/kernel.h>
  21#include <linux/module.h>
  22#include <linux/of.h>
  23#include <linux/of_irq.h>
  24#include <linux/platform_device.h>
  25#include <linux/pm.h>
  26#include <linux/slab.h>
  27#include <linux/spinlock.h>
  28#include <linux/spinlock_types.h>
  29#include <linux/types.h>
  30#include <linux/v4l2-dv-timings.h>
  31#include <linux/v4l2-subdev.h>
  32#include <linux/xilinx-sdirxss.h>
  33#include <linux/xilinx-v4l2-controls.h>
  34#include <media/hdr-ctrls.h>
  35#include <media/media-entity.h>
  36#include <media/v4l2-common.h>
  37#include <media/v4l2-ctrls.h>
  38#include <media/v4l2-event.h>
  39#include <media/v4l2-fwnode.h>
  40#include <media/v4l2-subdev.h>
  41#include "xilinx-vip.h"
  42
  43/*
  44 * SDI Rx register map, bitmask and offsets
  45 */
  46#define XSDIRX_RST_CTRL_REG             0x00
  47#define XSDIRX_MDL_CTRL_REG             0x04
  48#define XSDIRX_GLBL_IER_REG             0x0C
  49#define XSDIRX_ISR_REG                  0x10
  50#define XSDIRX_IER_REG                  0x14
  51#define XSDIRX_ST352_VALID_REG          0x18
  52#define XSDIRX_ST352_DS1_REG            0x1C
  53#define XSDIRX_ST352_DS3_REG            0x20
  54#define XSDIRX_ST352_DS5_REG            0x24
  55#define XSDIRX_ST352_DS7_REG            0x28
  56#define XSDIRX_ST352_DS9_REG            0x2C
  57#define XSDIRX_ST352_DS11_REG           0x30
  58#define XSDIRX_ST352_DS13_REG           0x34
  59#define XSDIRX_ST352_DS15_REG           0x38
  60#define XSDIRX_VERSION_REG              0x3C
  61#define XSDIRX_SS_CONFIG_REG            0x40
  62#define XSDIRX_MODE_DET_STAT_REG        0x44
  63#define XSDIRX_TS_DET_STAT_REG          0x48
  64#define XSDIRX_EDH_STAT_REG             0x4C
  65#define XSDIRX_EDH_ERRCNT_EN_REG        0x50
  66#define XSDIRX_EDH_ERRCNT_REG           0x54
  67#define XSDIRX_CRC_ERRCNT_REG           0x58
  68#define XSDIRX_VID_LOCK_WINDOW_REG      0x5C
  69#define XSDIRX_SB_RX_STS_REG            0x60
  70
  71#define XSDIRX_RST_CTRL_SS_EN_MASK                      BIT(0)
  72#define XSDIRX_RST_CTRL_SRST_MASK                       BIT(1)
  73#define XSDIRX_RST_CTRL_RST_CRC_ERRCNT_MASK             BIT(2)
  74#define XSDIRX_RST_CTRL_RST_EDH_ERRCNT_MASK             BIT(3)
  75#define XSDIRX_RST_CTRL_SDIRX_BRIDGE_ENB_MASK           BIT(8)
  76#define XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK        BIT(9)
  77#define XSDIRX_RST_CTRL_BRIDGE_CH_FMT_OFFSET            10
  78#define XSDIRX_RST_CTRL_BRIDGE_CH_FMT_MASK              GENMASK(12, 10)
  79#define XSDIRX_RST_CTRL_BRIDGE_CH_FMT_YUV444            1
  80
  81#define XSDIRX_MDL_CTRL_FRM_EN_MASK             BIT(4)
  82#define XSDIRX_MDL_CTRL_MODE_DET_EN_MASK        BIT(5)
  83#define XSDIRX_MDL_CTRL_MODE_HD_EN_MASK         BIT(8)
  84#define XSDIRX_MDL_CTRL_MODE_SD_EN_MASK         BIT(9)
  85#define XSDIRX_MDL_CTRL_MODE_3G_EN_MASK         BIT(10)
  86#define XSDIRX_MDL_CTRL_MODE_6G_EN_MASK         BIT(11)
  87#define XSDIRX_MDL_CTRL_MODE_12GI_EN_MASK       BIT(12)
  88#define XSDIRX_MDL_CTRL_MODE_12GF_EN_MASK       BIT(13)
  89#define XSDIRX_MDL_CTRL_MODE_AUTO_DET_MASK      GENMASK(13, 8)
  90
  91#define XSDIRX_MDL_CTRL_FORCED_MODE_OFFSET      16
  92#define XSDIRX_MDL_CTRL_FORCED_MODE_MASK        GENMASK(18, 16)
  93
  94#define XSDIRX_GLBL_INTR_EN_MASK        BIT(0)
  95
  96#define XSDIRX_INTR_VIDLOCK_MASK        BIT(0)
  97#define XSDIRX_INTR_VIDUNLOCK_MASK      BIT(1)
  98#define XSDIRX_INTR_VSYNC_MASK          BIT(2)
  99#define XSDIRX_INTR_OVERFLOW_MASK       BIT(9)
 100#define XSDIRX_INTR_UNDERFLOW_MASK      BIT(10)
 101
 102#define XSDIRX_INTR_ALL_MASK    (XSDIRX_INTR_VIDLOCK_MASK |\
 103                                XSDIRX_INTR_VIDUNLOCK_MASK |\
 104                                XSDIRX_INTR_VSYNC_MASK |\
 105                                XSDIRX_INTR_OVERFLOW_MASK |\
 106                                XSDIRX_INTR_UNDERFLOW_MASK)
 107
 108#define XSDIRX_ST352_VALID_DS1_MASK     BIT(0)
 109#define XSDIRX_ST352_VALID_DS3_MASK     BIT(1)
 110#define XSDIRX_ST352_VALID_DS5_MASK     BIT(2)
 111#define XSDIRX_ST352_VALID_DS7_MASK     BIT(3)
 112#define XSDIRX_ST352_VALID_DS9_MASK     BIT(4)
 113#define XSDIRX_ST352_VALID_DS11_MASK    BIT(5)
 114#define XSDIRX_ST352_VALID_DS13_MASK    BIT(6)
 115#define XSDIRX_ST352_VALID_DS15_MASK    BIT(7)
 116
 117#define XSDIRX_MODE_DET_STAT_RX_MODE_MASK       GENMASK(2, 0)
 118#define XSDIRX_MODE_DET_STAT_MODE_LOCK_MASK     BIT(3)
 119#define XSDIRX_MODE_DET_STAT_ACT_STREAM_MASK    GENMASK(6, 4)
 120#define XSDIRX_MODE_DET_STAT_ACT_STREAM_OFFSET  4
 121#define XSDIRX_MODE_DET_STAT_LVLB_3G_MASK       BIT(7)
 122
 123#define XSDIRX_ACTIVE_STREAMS_1         0x0
 124#define XSDIRX_ACTIVE_STREAMS_2         0x1
 125#define XSDIRX_ACTIVE_STREAMS_4         0x2
 126#define XSDIRX_ACTIVE_STREAMS_8         0x3
 127#define XSDIRX_ACTIVE_STREAMS_16        0x4
 128
 129#define XSDIRX_TS_DET_STAT_LOCKED_MASK          BIT(0)
 130#define XSDIRX_TS_DET_STAT_SCAN_MASK            BIT(1)
 131#define XSDIRX_TS_DET_STAT_SCAN_OFFSET          (1)
 132#define XSDIRX_TS_DET_STAT_FAMILY_MASK          GENMASK(7, 4)
 133#define XSDIRX_TS_DET_STAT_FAMILY_OFFSET        (4)
 134#define XSDIRX_TS_DET_STAT_RATE_MASK            GENMASK(11, 8)
 135#define XSDIRX_TS_DET_STAT_RATE_OFFSET          (8)
 136
 137#define XSDIRX_TS_DET_STAT_RATE_NONE            0x0
 138#define XSDIRX_TS_DET_STAT_RATE_96HZ            0x1
 139#define XSDIRX_TS_DET_STAT_RATE_23_98HZ         0x2
 140#define XSDIRX_TS_DET_STAT_RATE_24HZ            0x3
 141#define XSDIRX_TS_DET_STAT_RATE_47_95HZ         0x4
 142#define XSDIRX_TS_DET_STAT_RATE_25HZ            0x5
 143#define XSDIRX_TS_DET_STAT_RATE_29_97HZ         0x6
 144#define XSDIRX_TS_DET_STAT_RATE_30HZ            0x7
 145#define XSDIRX_TS_DET_STAT_RATE_48HZ            0x8
 146#define XSDIRX_TS_DET_STAT_RATE_50HZ            0x9
 147#define XSDIRX_TS_DET_STAT_RATE_59_94HZ         0xA
 148#define XSDIRX_TS_DET_STAT_RATE_60HZ            0xB
 149#define XSDIRX_TS_DET_STAT_RATE_95_90HZ         0xC
 150#define XSDIRX_TS_DET_STAT_RATE_100HZ           0xD
 151#define XSDIRX_TS_DET_STAT_RATE_120HZ           0xE
 152#define XSDIRX_TS_DET_STAT_RATE_119_88HZ        0xF
 153
 154#define XSDIRX_EDH_STAT_EDH_AP_MASK     BIT(0)
 155#define XSDIRX_EDH_STAT_EDH_FF_MASK     BIT(1)
 156#define XSDIRX_EDH_STAT_EDH_ANC_MASK    BIT(2)
 157#define XSDIRX_EDH_STAT_AP_FLAG_MASK    GENMASK(8, 4)
 158#define XSDIRX_EDH_STAT_FF_FLAG_MASK    GENMASK(13, 9)
 159#define XSDIRX_EDH_STAT_ANC_FLAG_MASK   GENMASK(18, 14)
 160#define XSDIRX_EDH_STAT_PKT_FLAG_MASK   GENMASK(22, 19)
 161
 162#define XSDIRX_EDH_ERRCNT_COUNT_MASK    GENMASK(15, 0)
 163
 164#define XSDIRX_CRC_ERRCNT_COUNT_MASK    GENMASK(31, 16)
 165#define XSDIRX_CRC_ERRCNT_DS_CRC_MASK   GENMASK(15, 0)
 166
 167#define XSDIRX_VERSION_REV_MASK         GENMASK(7, 0)
 168#define XSDIRX_VERSION_PATCHID_MASK     GENMASK(11, 8)
 169#define XSDIRX_VERSION_VER_REV_MASK     GENMASK(15, 12)
 170#define XSDIRX_VERSION_VER_MIN_MASK     GENMASK(23, 16)
 171#define XSDIRX_VERSION_VER_MAJ_MASK     GENMASK(31, 24)
 172
 173#define XSDIRX_SS_CONFIG_EDH_INCLUDED_MASK              BIT(1)
 174
 175#define XSDIRX_STAT_SB_RX_TDATA_CHANGE_DONE_MASK        BIT(0)
 176#define XSDIRX_STAT_SB_RX_TDATA_CHANGE_FAIL_MASK        BIT(1)
 177#define XSDIRX_STAT_SB_RX_TDATA_GT_RESETDONE_MASK       BIT(2)
 178#define XSDIRX_STAT_SB_RX_TDATA_GT_BITRATE_MASK         BIT(3)
 179
 180#define XSDIRX_DEFAULT_WIDTH    (1920)
 181#define XSDIRX_DEFAULT_HEIGHT   (1080)
 182
 183#define XSDIRX_MAX_STR_LENGTH   16
 184
 185#define XSDIRXSS_SDI_STD_3G             0
 186#define XSDIRXSS_SDI_STD_6G             1
 187#define XSDIRXSS_SDI_STD_12G_8DS        2
 188
 189#define XSDIRX_DEFAULT_VIDEO_LOCK_WINDOW        0x3000
 190
 191#define XSDIRX_MODE_HD_MASK     0x0
 192#define XSDIRX_MODE_SD_MASK     0x1
 193#define XSDIRX_MODE_3G_MASK     0x2
 194#define XSDIRX_MODE_6G_MASK     0x4
 195#define XSDIRX_MODE_12GI_MASK   0x5
 196#define XSDIRX_MODE_12GF_MASK   0x6
 197
 198/* Maximum number of events per file handle. */
 199#define XSDIRX_MAX_EVENTS       (128)
 200
 201/* ST352 related macros */
 202#define XST352_PAYLOAD_BYTE_MASK        0xFF
 203#define XST352_PAYLOAD_BYTE1_SHIFT      0
 204#define XST352_PAYLOAD_BYTE2_SHIFT      8
 205#define XST352_PAYLOAD_BYTE3_SHIFT      16
 206#define XST352_PAYLOAD_BYTE4_SHIFT      24
 207
 208#define XST352_BYTE1_ST292_1x720L_1_5G          0x84
 209#define XST352_BYTE1_ST292_1x1080L_1_5G         0x85
 210#define XST352_BYTE1_ST425_2008_750L_3GB        0x88
 211#define XST352_BYTE1_ST425_2008_1125L_3GA       0x89
 212#define XST352_BYTE1_ST372_DL_3GB               0x8A
 213#define XST352_BYTE1_ST372_2x720L_3GB           0x8B
 214#define XST352_BYTE1_ST372_2x1080L_3GB          0x8C
 215#define XST352_BYTE1_ST2081_10_2160L_6G         0xC0
 216#define XST352_BYTE1_ST2081_10_2_1080L_6G       0xC1
 217#define XST352_BYTE1_ST2081_10_DL_2160L_6G      0xC2
 218#define XST352_BYTE1_ST2082_10_2160L_12G        0xCE
 219
 220#define XST352_BYTE2_TS_TYPE_MASK               BIT(15)
 221#define XST352_BYTE2_TS_TYPE_OFFSET             15
 222#define XST352_BYTE2_PIC_TYPE_MASK              BIT(14)
 223#define XST352_BYTE2_PIC_TYPE_OFFSET            14
 224#define XST352_BYTE2_TS_PIC_TYPE_INTERLACED     0
 225#define XST352_BYTE2_TS_PIC_TYPE_PROGRESSIVE    1
 226
 227#define XST352_BYTE2_FPS_MASK                   0xF
 228#define XST352_BYTE2_FPS_SHIFT                  8
 229#define XST352_BYTE2_FPS_96F                    0x1
 230#define XST352_BYTE2_FPS_24F                    0x2
 231#define XST352_BYTE2_FPS_24                     0x3
 232#define XST352_BYTE2_FPS_48F                    0x4
 233#define XST352_BYTE2_FPS_25                     0x5
 234#define XST352_BYTE2_FPS_30F                    0x6
 235#define XST352_BYTE2_FPS_30                     0x7
 236#define XST352_BYTE2_FPS_48                     0x8
 237#define XST352_BYTE2_FPS_50                     0x9
 238#define XST352_BYTE2_FPS_60F                    0xA
 239#define XST352_BYTE2_FPS_60                     0xB
 240/* Table 4 ST 2081-10:2015 */
 241#define XST352_BYTE2_FPS_96                     0xC
 242#define XST352_BYTE2_FPS_100                    0xD
 243#define XST352_BYTE2_FPS_120                    0xE
 244#define XST352_BYTE2_FPS_120F                   0xF
 245
 246/* Electro Optical Transfer Function Byte 2 bit[5:4] */
 247#define XST352_BYTE2_EOTF_MASK                  GENMASK(13, 12)
 248#define XST352_BYTE2_EOTF_OFFSET                12
 249#define XST352_BYTE2_EOTF_SDRTV                 0x0
 250#define XST352_BYTE2_EOTF_HLG                   0x1
 251#define XST352_BYTE2_EOTF_SMPTE2084             0x2
 252
 253#define XST352_BYTE2_COLORIMETRY_MASK           GENMASK(21, 20)
 254#define XST352_BYTE2_COLORIMETRY_OFFSET         20
 255#define XST352_BYTE2_COLORIMETRY_BT709          0
 256#define XST352_BYTE2_COLORIMETRY_VANC           1
 257#define XST352_BYTE2_COLORIMETRY_UHDTV          2
 258#define XST352_BYTE2_COLORIMETRY_UNKNOWN        3
 259
 260#define XST352_BYTE3_ACT_LUMA_COUNT_MASK        BIT(22)
 261#define XST352_BYTE3_ACT_LUMA_COUNT_OFFSET      22
 262
 263#define XST352_BYTE3_COLOR_FORMAT_MASK          GENMASK(19, 16)
 264#define XST352_BYTE3_COLOR_FORMAT_OFFSET        16
 265#define XST352_BYTE3_COLOR_FORMAT_422           0x0
 266#define XST352_BYTE3_COLOR_FORMAT_YUV444        0x1
 267#define XST352_BYTE3_COLOR_FORMAT_420           0x3
 268#define XST352_BYTE3_COLOR_FORMAT_GBR           0x2
 269
 270#define XST352_BYTE4_BIT_DEPTH_MASK             GENMASK(25, 24)
 271#define XST352_BYTE4_BIT_DEPTH_OFFSET           24
 272#define XST352_BYTE4_BIT_DEPTH_10               0x1
 273#define XST352_BYTE4_BIT_DEPTH_12               0x2
 274
 275/* Refer Table 3 ST2082-10:2018 */
 276#define XST352_BYTE4_LUM_COL_DIFF_MASK          BIT(28)
 277
 278#define CLK_INT         148500000UL
 279
 280/**
 281 * enum sdi_family_enc - SDI Transport Video Format Detected with Active Pixels
 282 * @XSDIRX_SMPTE_ST_274: SMPTE ST 274 detected with AP 1920x1080
 283 * @XSDIRX_SMPTE_ST_296: SMPTE ST 296 detected with AP 1280x720
 284 * @XSDIRX_SMPTE_ST_2048_2: SMPTE ST 2048-2 detected with AP 2048x1080
 285 * @XSDIRX_SMPTE_ST_295: SMPTE ST 295 detected with AP 1920x1080
 286 * @XSDIRX_NTSC: NTSC encoding detected with AP 720x486
 287 * @XSDIRX_PAL: PAL encoding detected with AP 720x576
 288 * @XSDIRX_TS_UNKNOWN: Unknown SMPTE Transport family type
 289 */
 290enum sdi_family_enc {
 291        XSDIRX_SMPTE_ST_274     = 0,
 292        XSDIRX_SMPTE_ST_296     = 1,
 293        XSDIRX_SMPTE_ST_2048_2  = 2,
 294        XSDIRX_SMPTE_ST_295     = 3,
 295        XSDIRX_NTSC             = 8,
 296        XSDIRX_PAL              = 9,
 297        XSDIRX_TS_UNKNOWN       = 15
 298};
 299
 300/**
 301 * struct xsdirxss_core - Core configuration SDI Rx Subsystem device structure
 302 * @dev: Platform structure
 303 * @iomem: Base address of subsystem
 304 * @irq: requested irq number
 305 * @include_edh: EDH processor presence
 306 * @mode: 3G/6G/12G mode
 307 * @clks: array of clocks
 308 * @num_clks: number of clocks
 309 * @rst_gt_gpio: reset gt gpio (fmc init done)
 310 * @rst_picxo_gpio: reset picxo core
 311 * @bpc: Bits per component, can be 10 or 12
 312 */
 313struct xsdirxss_core {
 314        struct device *dev;
 315        void __iomem *iomem;
 316        int irq;
 317        bool include_edh;
 318        int mode;
 319        struct clk_bulk_data *clks;
 320        int num_clks;
 321        struct gpio_desc *rst_gt_gpio;
 322        struct gpio_desc *rst_picxo_gpio;
 323        u32 bpc;
 324};
 325
 326/**
 327 * struct xsdirxss_state - SDI Rx Subsystem device structure
 328 * @core: Core structure for MIPI SDI Rx Subsystem
 329 * @subdev: The v4l2 subdev structure
 330 * @ctrl_handler: control handler
 331 * @event: Holds the video unlock event
 332 * @format: Active V4L2 format on source pad
 333 * @default_format: default V4L2 media bus format
 334 * @frame_interval: Captures the frame rate
 335 * @vip_format: format information corresponding to the active format
 336 * @pad: source media pad
 337 * @static_hdr: static hdr payload
 338 * @prev_payload: Previous ST352 payload
 339 * @vidlockwin: Video lock window value set by control
 340 * @edhmask: EDH mask set by control
 341 * @searchmask: Search mask set by control
 342 * @streaming: Flag for storing streaming state
 343 * @vidlocked: Flag indicating SDI Rx has locked onto video stream
 344 * @ts_is_interlaced: Flag indicating Transport Stream is interlaced.
 345 * @framer_enable: Flag for framer enabled or not set by control
 346 *
 347 * This structure contains the device driver related parameters
 348 */
 349struct xsdirxss_state {
 350        struct xsdirxss_core core;
 351        struct v4l2_subdev subdev;
 352        struct v4l2_ctrl_handler ctrl_handler;
 353        struct v4l2_event event;
 354        struct v4l2_mbus_framefmt format;
 355        struct v4l2_mbus_framefmt default_format;
 356        struct v4l2_fract frame_interval;
 357        const struct xvip_video_format *vip_format;
 358        struct media_pad pad;
 359        struct v4l2_hdr10_payload static_hdr;
 360        u32 prev_payload;
 361        u32 vidlockwin;
 362        u32 edhmask;
 363        u16 searchmask;
 364        bool streaming;
 365        bool vidlocked;
 366        bool ts_is_interlaced;
 367        bool framer_enable;
 368};
 369
 370/* List of clocks required by UHD-SDI Rx subsystem */
 371static const char * const xsdirxss_clks[] = {
 372        "s_axi_aclk", "sdi_rx_clk", "video_out_clk",
 373};
 374
 375static const u32 xsdirxss_10bpc_mbus_fmts[] = {
 376        MEDIA_BUS_FMT_UYVY10_1X20,
 377        MEDIA_BUS_FMT_VYYUYY10_4X20,
 378        MEDIA_BUS_FMT_VUY10_1X30,
 379        MEDIA_BUS_FMT_RBG101010_1X30,
 380};
 381
 382static const u32 xsdirxss_12bpc_mbus_fmts[] = {
 383        MEDIA_BUS_FMT_UYVY12_1X24,
 384        MEDIA_BUS_FMT_UYYVYY12_4X24,
 385        MEDIA_BUS_FMT_VUY12_1X36,
 386        MEDIA_BUS_FMT_RBG121212_1X36,
 387};
 388
 389#define XLNX_V4L2_DV_BT_2048X1080P24 { \
 390        .type = V4L2_DV_BT_656_1120, \
 391        V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \
 392                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 393                74250000, 510, 44, 148, 4, 5, 36, 0, 0, 0, \
 394                V4L2_DV_BT_STD_SDI) \
 395}
 396
 397#define XLNX_V4L2_DV_BT_2048X1080P25 { \
 398        .type = V4L2_DV_BT_656_1120, \
 399        V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \
 400                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 401                74250000, 400, 44, 148, 4, 5, 36, 0, 0, 0, \
 402                V4L2_DV_BT_STD_SDI) \
 403}
 404
 405#define XLNX_V4L2_DV_BT_2048X1080P30 { \
 406        .type = V4L2_DV_BT_656_1120, \
 407        V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \
 408                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 409                74250000, 66, 20, 66, 4, 5, 36, 0, 0, 0, \
 410                V4L2_DV_BT_STD_SDI) \
 411}
 412
 413#define XLNX_V4L2_DV_BT_2048X1080I48 { \
 414        .type = V4L2_DV_BT_656_1120, \
 415        V4L2_INIT_BT_TIMINGS(2048, 1080, 1, \
 416                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 417                74250000, 329, 44, 329, 2, 5, 15, 3, 5, 15, \
 418                V4L2_DV_BT_STD_SDI) \
 419}
 420
 421#define XLNX_V4L2_DV_BT_2048X1080I50 { \
 422        .type = V4L2_DV_BT_656_1120, \
 423        V4L2_INIT_BT_TIMINGS(2048, 1080, 1, \
 424                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 425                74250000, 274, 44, 274, 2, 5, 15, 3, 5, 15, \
 426                V4L2_DV_BT_STD_SDI) \
 427}
 428
 429#define XLNX_V4L2_DV_BT_2048X1080I60 { \
 430        .type = V4L2_DV_BT_656_1120, \
 431        V4L2_INIT_BT_TIMINGS(2048, 1080, 1, \
 432                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 433                74250000, 66, 20, 66, 2, 5, 15, 3, 5, 15, \
 434                V4L2_DV_BT_STD_SDI) \
 435}
 436
 437#define XLNX_V4L2_DV_BT_1920X1080P48 { \
 438        .type = V4L2_DV_BT_656_1120, \
 439        V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \
 440                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 441                148500000, 638, 44, 148, 4, 5, 36, 0, 0, 0, \
 442                V4L2_DV_BT_STD_SDI) \
 443}
 444
 445#define XLNX_V4L2_DV_BT_2048X1080P48 { \
 446        .type = V4L2_DV_BT_656_1120, \
 447        V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \
 448                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 449                148500000, 510, 44, 148, 4, 5, 36, 0, 0, 0, \
 450                V4L2_DV_BT_STD_SDI) \
 451}
 452
 453#define XLNX_V4L2_DV_BT_2048X1080P50 { \
 454        .type = V4L2_DV_BT_656_1120, \
 455        V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \
 456                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 457                148500000, 400, 44, 148, 4, 5, 36, 0, 0, 0, \
 458                V4L2_DV_BT_STD_SDI) \
 459}
 460
 461#define XLNX_V4L2_DV_BT_2048X1080P60 { \
 462        .type = V4L2_DV_BT_656_1120, \
 463        V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \
 464                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 465                148500000, 88, 44, 20, 4, 5, 36, 0, 0, 0, \
 466                V4L2_DV_BT_STD_SDI) \
 467}
 468
 469#define XLNX_V4L2_DV_BT_3840X2160P48 { \
 470        .type = V4L2_DV_BT_656_1120, \
 471        V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \
 472                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 473                594000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, \
 474                V4L2_DV_BT_STD_SDI) \
 475}
 476
 477#define XLNX_V4L2_DV_BT_4096X2160P48 { \
 478        .type = V4L2_DV_BT_656_1120, \
 479        V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \
 480                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 481                594000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, \
 482                V4L2_DV_BT_STD_SDI) \
 483}
 484
 485#define XLNX_V4L2_DV_BT_1920X1080I48 { \
 486        .type = V4L2_DV_BT_656_1120, \
 487        V4L2_INIT_BT_TIMINGS(1920, 1080, 1, \
 488                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 489                148500000, 371, 88, 371, 2, 5, 15, 3, 5, 15, \
 490                V4L2_DV_BT_STD_SDI) \
 491}
 492
 493#define XLNX_V4L2_DV_BT_1920X1080P96 { \
 494        .type = V4L2_DV_BT_656_1120, \
 495        V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \
 496                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 497                297000000, 638, 44, 148, 4, 5, 36, 0, 0, 0, \
 498                V4L2_DV_BT_STD_SDI) \
 499}
 500
 501#define XLNX_V4L2_DV_BT_1920X1080P100 { \
 502        .type = V4L2_DV_BT_656_1120, \
 503        V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \
 504                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 505                297000000, 528, 44, 148, 4, 5, 36, 0, 0, 0, \
 506                V4L2_DV_BT_STD_SDI) \
 507}
 508
 509#define XLNX_V4L2_DV_BT_1920X1080P120 { \
 510        .type = V4L2_DV_BT_656_1120, \
 511        V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \
 512                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 513                297000000, 88, 44, 148, 4, 5, 36, 0, 0, 0, \
 514                V4L2_DV_BT_STD_SDI) \
 515}
 516
 517#define XLNX_V4L2_DV_BT_2048X1080P96 { \
 518        .type = V4L2_DV_BT_656_1120, \
 519        V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \
 520                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 521                297000000, 510, 44, 148, 4, 5, 36, 0, 0, 0, \
 522                V4L2_DV_BT_STD_SDI) \
 523}
 524
 525#define XLNX_V4L2_DV_BT_2048X1080P100 { \
 526        .type = V4L2_DV_BT_656_1120, \
 527        V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \
 528                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 529                297000000, 400, 44, 148, 4, 5, 36, 0, 0, 0, \
 530                V4L2_DV_BT_STD_SDI) \
 531}
 532
 533#define XLNX_V4L2_DV_BT_2048X1080P120 { \
 534        .type = V4L2_DV_BT_656_1120, \
 535        V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \
 536                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 537                297000000, 88, 44, 20, 4, 5, 36, 0, 0, 0, \
 538                V4L2_DV_BT_STD_SDI) \
 539}
 540
 541static const struct v4l2_dv_timings fmt_cap[] = {
 542        V4L2_DV_BT_SDI_720X487I60,
 543        V4L2_DV_BT_CEA_720X576I50,
 544        V4L2_DV_BT_CEA_1280X720P24,
 545        V4L2_DV_BT_CEA_1280X720P25,
 546        V4L2_DV_BT_CEA_1280X720P30,
 547        V4L2_DV_BT_CEA_1280X720P50,
 548        V4L2_DV_BT_CEA_1280X720P60,
 549        V4L2_DV_BT_CEA_1920X1080P24,
 550        V4L2_DV_BT_CEA_1920X1080P30,
 551        V4L2_DV_BT_CEA_1920X1080I50,
 552        V4L2_DV_BT_CEA_1920X1080I60,
 553        V4L2_DV_BT_CEA_1920X1080P50,
 554        V4L2_DV_BT_CEA_1920X1080P60,
 555        V4L2_DV_BT_CEA_3840X2160P24,
 556        V4L2_DV_BT_CEA_3840X2160P30,
 557        V4L2_DV_BT_CEA_3840X2160P50,
 558        V4L2_DV_BT_CEA_3840X2160P60,
 559        V4L2_DV_BT_CEA_4096X2160P24,
 560        V4L2_DV_BT_CEA_4096X2160P25,
 561        V4L2_DV_BT_CEA_4096X2160P30,
 562        V4L2_DV_BT_CEA_4096X2160P50,
 563        V4L2_DV_BT_CEA_4096X2160P60,
 564
 565        XLNX_V4L2_DV_BT_2048X1080P24,
 566        XLNX_V4L2_DV_BT_2048X1080P25,
 567        XLNX_V4L2_DV_BT_2048X1080P30,
 568        XLNX_V4L2_DV_BT_2048X1080I48,
 569        XLNX_V4L2_DV_BT_2048X1080I50,
 570        XLNX_V4L2_DV_BT_2048X1080I60,
 571        XLNX_V4L2_DV_BT_2048X1080P48,
 572        XLNX_V4L2_DV_BT_2048X1080P50,
 573        XLNX_V4L2_DV_BT_2048X1080P60,
 574        XLNX_V4L2_DV_BT_1920X1080P48,
 575        XLNX_V4L2_DV_BT_1920X1080I48,
 576        XLNX_V4L2_DV_BT_3840X2160P48,
 577        XLNX_V4L2_DV_BT_4096X2160P48,
 578
 579        /* HFR */
 580        XLNX_V4L2_DV_BT_1920X1080P96,
 581        XLNX_V4L2_DV_BT_1920X1080P100,
 582        XLNX_V4L2_DV_BT_1920X1080P120,
 583        XLNX_V4L2_DV_BT_2048X1080P96,
 584        XLNX_V4L2_DV_BT_2048X1080P100,
 585        XLNX_V4L2_DV_BT_2048X1080P120,
 586};
 587
 588struct xsdirxss_dv_map {
 589        u32 width;
 590        u32 height;
 591        u32 fps;
 592        struct v4l2_dv_timings format;
 593};
 594
 595static const struct xsdirxss_dv_map xsdirxss_dv_timings[] = {
 596        /* SD - 720x487i60 */
 597        { 720, 243, 30, V4L2_DV_BT_SDI_720X487I60 },
 598        /* SD - 720x576i50 */
 599        { 720, 288, 25, V4L2_DV_BT_CEA_720X576I50 },
 600        /* HD - 1280x720p23.98 */
 601        /* HD - 1280x720p24 */
 602        { 1280, 720, 24, V4L2_DV_BT_CEA_1280X720P24 },
 603        /* HD - 1280x720p25 */
 604        { 1280, 720, 25, V4L2_DV_BT_CEA_1280X720P25 },
 605        /* HD - 1280x720p29.97 */
 606        /* HD - 1280x720p30 */
 607        { 1280, 720, 30, V4L2_DV_BT_CEA_1280X720P30 },
 608        /* HD - 1280x720p50 */
 609        { 1280, 720, 50, V4L2_DV_BT_CEA_1280X720P50 },
 610        /* HD - 1280x720p59.94 */
 611        /* HD - 1280x720p60 */
 612        { 1280, 720, 60, V4L2_DV_BT_CEA_1280X720P60 },
 613        /* HD - 1920x1080p23.98 */
 614        /* HD - 1920x1080p24 */
 615        { 1920, 1080, 24, V4L2_DV_BT_CEA_1920X1080P24 },
 616        /* HD - 1920x1080p25 */
 617        { 1920, 1080, 25, V4L2_DV_BT_CEA_1920X1080P25 },
 618        /* HD - 1920x1080p29.97 */
 619        /* HD - 1920x1080p30 */
 620        { 1920, 1080, 30, V4L2_DV_BT_CEA_1920X1080P30 },
 621
 622        /* HD - 2048x1080p23.98 */
 623        /* HD - 2048x1080p24 */
 624        { 2048, 1080, 24, XLNX_V4L2_DV_BT_2048X1080P24 },
 625        /* HD - 2048x1080p25 */
 626        { 2048, 1080, 24, XLNX_V4L2_DV_BT_2048X1080P25 },
 627        /* HD - 2048x1080p29.97 */
 628        /* HD - 2048x1080p30 */
 629        { 2048, 1080, 24, XLNX_V4L2_DV_BT_2048X1080P30 },
 630        /* HD - 1920x1080i47.95 */
 631        /* HD - 1920x1080i48 */
 632        { 1920, 540, 24, XLNX_V4L2_DV_BT_1920X1080I48 },
 633
 634        /* HD - 1920x1080i50 */
 635        { 1920, 540, 25, V4L2_DV_BT_CEA_1920X1080I50 },
 636        /* HD - 1920x1080i59.94 */
 637        /* HD - 1920x1080i60 */
 638        { 1920, 540, 30, V4L2_DV_BT_CEA_1920X1080I60 },
 639
 640        /* HD - 2048x1080i47.95 */
 641        /* HD - 2048x1080i48 */
 642        { 2048, 540, 24, XLNX_V4L2_DV_BT_2048X1080I48 },
 643        /* HD - 2048x1080i50 */
 644        { 2048, 540, 25, XLNX_V4L2_DV_BT_2048X1080I50 },
 645        /* HD - 2048x1080i59.94 */
 646        /* HD - 2048x1080i60 */
 647        { 2048, 540, 30, XLNX_V4L2_DV_BT_2048X1080I60 },
 648        /* 3G - 1920x1080p47.95 */
 649        /* 3G - 1920x1080p48 */
 650        { 1920, 1080, 48, XLNX_V4L2_DV_BT_1920X1080P48 },
 651
 652        /* 3G - 1920x1080p50 148.5 */
 653        { 1920, 1080, 50, V4L2_DV_BT_CEA_1920X1080P50 },
 654        /* 3G - 1920x1080p59.94 148.5/1.001 */
 655        /* 3G - 1920x1080p60 148.5 */
 656        { 1920, 1080, 60, V4L2_DV_BT_CEA_1920X1080P60 },
 657
 658        /* 3G - 2048x1080p47.95 */
 659        /* 3G - 2048x1080p48 */
 660        { 2048, 1080, 48, XLNX_V4L2_DV_BT_2048X1080P48 },
 661        /* 3G - 2048x1080p50 */
 662        { 2048, 1080, 50, XLNX_V4L2_DV_BT_2048X1080P50 },
 663        /* 3G - 2048x1080p59.94 */
 664        /* 3G - 2048x1080p60 */
 665        { 2048, 1080, 60, XLNX_V4L2_DV_BT_2048X1080P60 },
 666
 667        /* 6G - 3840X2160p23.98 */
 668        /* 6G - 3840X2160p24 */
 669        { 3840, 2160, 24, V4L2_DV_BT_CEA_3840X2160P24 },
 670        /* 6G - 3840X2160p25 */
 671        { 3840, 2160, 25, V4L2_DV_BT_CEA_3840X2160P25 },
 672        /* 6G - 3840X2160p29.97 */
 673        /* 6G - 3840X2160p30 */
 674        { 3840, 2160, 30, V4L2_DV_BT_CEA_3840X2160P30 },
 675        /* 6G - 4096X2160p23.98 */
 676        /* 6G - 4096X2160p24 */
 677        { 4096, 2160, 24, V4L2_DV_BT_CEA_4096X2160P24 },
 678        /* 6G - 4096X2160p25 */
 679        { 4096, 2160, 25, V4L2_DV_BT_CEA_4096X2160P25 },
 680        /* 6G - 4096X2160p29.97 */
 681        /* 6G - 4096X2160p30 */
 682        { 4096, 2160, 30, V4L2_DV_BT_CEA_4096X2160P30 },
 683        /* 12G - 3840X2160p47.95 */
 684        /* 12G - 3840X2160p48 */
 685        { 3840, 2160, 48, XLNX_V4L2_DV_BT_3840X2160P48 },
 686
 687        /* 12G - 3840X2160p50 */
 688        { 3840, 2160, 50, V4L2_DV_BT_CEA_3840X2160P50 },
 689        /* 12G - 3840X2160p59.94 */
 690        /* 12G - 3840X2160p60 */
 691        { 3840, 2160, 60, V4L2_DV_BT_CEA_3840X2160P60 },
 692
 693        /* 12G - 4096X2160p47.95 */
 694        /* 12G - 4096X2160p48 */
 695        { 3840, 2160, 48, XLNX_V4L2_DV_BT_4096X2160P48 },
 696
 697        /* 12G - 4096X2160p50 */
 698        { 4096, 2160, 50, V4L2_DV_BT_CEA_4096X2160P50 },
 699        /* 12G - 4096X2160p59.94 */
 700        /* 12G - 4096X2160p60 */
 701        { 4096, 2160, 60, V4L2_DV_BT_CEA_4096X2160P60 },
 702
 703        /* 6G/12G HFR */
 704        { 1920, 1080, 96, XLNX_V4L2_DV_BT_1920X1080P96 },
 705        { 1920, 1080, 100, XLNX_V4L2_DV_BT_1920X1080P100 },
 706        { 1920, 1080, 120, XLNX_V4L2_DV_BT_1920X1080P120 },
 707        { 2048, 1080, 96, XLNX_V4L2_DV_BT_2048X1080P96 },
 708        { 2048, 1080, 100, XLNX_V4L2_DV_BT_2048X1080P100 },
 709        { 2048, 1080, 120, XLNX_V4L2_DV_BT_2048X1080P120 },
 710};
 711
 712static inline struct xsdirxss_state *
 713to_xsdirxssstate(struct v4l2_subdev *subdev)
 714{
 715        return container_of(subdev, struct xsdirxss_state, subdev);
 716}
 717
 718/*
 719 * Register related operations
 720 */
 721static inline u32 xsdirxss_read(struct xsdirxss_core *xsdirxss, u32 addr)
 722{
 723        return ioread32(xsdirxss->iomem + addr);
 724}
 725
 726static inline void xsdirxss_write(struct xsdirxss_core *xsdirxss, u32 addr,
 727                                  u32 value)
 728{
 729        iowrite32(value, xsdirxss->iomem + addr);
 730}
 731
 732static inline void xsdirxss_clr(struct xsdirxss_core *xsdirxss, u32 addr,
 733                                u32 clr)
 734{
 735        xsdirxss_write(xsdirxss, addr, xsdirxss_read(xsdirxss, addr) & ~clr);
 736}
 737
 738static inline void xsdirxss_set(struct xsdirxss_core *xsdirxss, u32 addr,
 739                                u32 set)
 740{
 741        xsdirxss_write(xsdirxss, addr, xsdirxss_read(xsdirxss, addr) | set);
 742}
 743
 744static inline void xsdirx_core_disable(struct xsdirxss_core *core)
 745{
 746        xsdirxss_clr(core, XSDIRX_RST_CTRL_REG, XSDIRX_RST_CTRL_SS_EN_MASK);
 747}
 748
 749static inline void xsdirx_core_enable(struct xsdirxss_core *core)
 750{
 751        xsdirxss_set(core, XSDIRX_RST_CTRL_REG, XSDIRX_RST_CTRL_SS_EN_MASK);
 752}
 753
 754static void xsdirxss_gt_reset(struct xsdirxss_core *core)
 755{
 756        /* reset qpll0 */
 757        gpiod_set_value(core->rst_gt_gpio, 0x1);
 758        gpiod_set_value(core->rst_gt_gpio, 0x0);
 759        /* reset picxo core */
 760        gpiod_set_value(core->rst_picxo_gpio, 0x1);
 761        gpiod_set_value(core->rst_picxo_gpio, 0x0);
 762}
 763
 764static int xsdirx_set_modedetect(struct xsdirxss_core *core, u16 mask)
 765{
 766        u32 i, val;
 767
 768        mask &= XSDIRX_DETECT_ALL_MODES;
 769        if (!mask) {
 770                dev_err(core->dev, "Invalid bit mask = 0x%08x\n", mask);
 771                return -EINVAL;
 772        }
 773
 774        dev_dbg(core->dev, "mask = 0x%x\n", mask);
 775
 776        val = xsdirxss_read(core, XSDIRX_MDL_CTRL_REG);
 777        val &= ~XSDIRX_MDL_CTRL_MODE_DET_EN_MASK;
 778        val &= ~XSDIRX_MDL_CTRL_MODE_AUTO_DET_MASK;
 779        val &= ~XSDIRX_MDL_CTRL_FORCED_MODE_MASK;
 780
 781        if (hweight16(mask) > 1) {
 782                /* Multi mode detection as more than 1 bit set in mask */
 783                dev_dbg(core->dev, "Detect multiple modes\n");
 784                for (i = 0; i < XSDIRX_MODE_NUM_SUPPORTED; i++) {
 785                        switch (mask & (1 << i)) {
 786                        case BIT(XSDIRX_MODE_SD_OFFSET):
 787                                val |= XSDIRX_MDL_CTRL_MODE_SD_EN_MASK;
 788                                break;
 789                        case BIT(XSDIRX_MODE_HD_OFFSET):
 790                                val |= XSDIRX_MDL_CTRL_MODE_HD_EN_MASK;
 791                                break;
 792                        case BIT(XSDIRX_MODE_3G_OFFSET):
 793                                val |= XSDIRX_MDL_CTRL_MODE_3G_EN_MASK;
 794                                break;
 795                        case BIT(XSDIRX_MODE_6G_OFFSET):
 796                                val |= XSDIRX_MDL_CTRL_MODE_6G_EN_MASK;
 797                                break;
 798                        case BIT(XSDIRX_MODE_12GI_OFFSET):
 799                                val |= XSDIRX_MDL_CTRL_MODE_12GI_EN_MASK;
 800                                break;
 801                        case BIT(XSDIRX_MODE_12GF_OFFSET):
 802                                val |= XSDIRX_MDL_CTRL_MODE_12GF_EN_MASK;
 803                                break;
 804                        }
 805                }
 806                val |= XSDIRX_MDL_CTRL_MODE_DET_EN_MASK;
 807        } else {
 808                /* Fixed Mode */
 809                u32 forced_mode_mask;
 810
 811                dev_dbg(core->dev, "Detect fixed mode\n");
 812
 813                /* Find offset of first bit set */
 814                switch (__ffs(mask)) {
 815                case XSDIRX_MODE_SD_OFFSET:
 816                        forced_mode_mask = XSDIRX_MODE_SD_MASK;
 817                        break;
 818                case XSDIRX_MODE_HD_OFFSET:
 819                        forced_mode_mask = XSDIRX_MODE_HD_MASK;
 820                        break;
 821                case XSDIRX_MODE_3G_OFFSET:
 822                        forced_mode_mask = XSDIRX_MODE_3G_MASK;
 823                        break;
 824                case XSDIRX_MODE_6G_OFFSET:
 825                        forced_mode_mask = XSDIRX_MODE_6G_MASK;
 826                        break;
 827                case XSDIRX_MODE_12GI_OFFSET:
 828                        forced_mode_mask = XSDIRX_MODE_12GI_MASK;
 829                        break;
 830                case XSDIRX_MODE_12GF_OFFSET:
 831                        forced_mode_mask = XSDIRX_MODE_12GF_MASK;
 832                        break;
 833                default:
 834                        forced_mode_mask = 0;
 835                }
 836                dev_dbg(core->dev, "Forced Mode Mask : 0x%x\n",
 837                        forced_mode_mask);
 838                val |= forced_mode_mask << XSDIRX_MDL_CTRL_FORCED_MODE_OFFSET;
 839        }
 840
 841        dev_dbg(core->dev, "Modes to be detected : sdi ctrl reg = 0x%08x\n",
 842                val);
 843        xsdirxss_write(core, XSDIRX_MDL_CTRL_REG, val);
 844
 845        return 0;
 846}
 847
 848static void xsdirx_framer(struct xsdirxss_core *core, bool flag)
 849{
 850        if (flag)
 851                xsdirxss_set(core, XSDIRX_MDL_CTRL_REG,
 852                             XSDIRX_MDL_CTRL_FRM_EN_MASK);
 853        else
 854                xsdirxss_clr(core, XSDIRX_MDL_CTRL_REG,
 855                             XSDIRX_MDL_CTRL_FRM_EN_MASK);
 856}
 857
 858static void xsdirx_setedherrcnttrigger(struct xsdirxss_core *core, u32 enable)
 859{
 860        u32 val;
 861
 862        val = enable & XSDIRX_EDH_ALLERR_MASK;
 863
 864        xsdirxss_write(core, XSDIRX_EDH_ERRCNT_EN_REG, val);
 865}
 866
 867static inline void xsdirx_setvidlockwindow(struct xsdirxss_core *core, u32 val)
 868{
 869        /*
 870         * The video lock window is the amount of time for which
 871         * the mode and transport stream should be locked to get
 872         * the video lock interrupt.
 873         */
 874        xsdirxss_write(core, XSDIRX_VID_LOCK_WINDOW_REG, val);
 875}
 876
 877static inline void xsdirx_disableintr(struct xsdirxss_core *core, u32 mask)
 878{
 879        xsdirxss_clr(core, XSDIRX_IER_REG, mask);
 880}
 881
 882static inline void xsdirx_enableintr(struct xsdirxss_core *core, u32 mask)
 883{
 884        xsdirxss_set(core, XSDIRX_IER_REG, mask);
 885}
 886
 887static void xsdirx_globalintr(struct xsdirxss_core *core, bool flag)
 888{
 889        if (flag)
 890                xsdirxss_set(core, XSDIRX_GLBL_IER_REG,
 891                             XSDIRX_GLBL_INTR_EN_MASK);
 892        else
 893                xsdirxss_clr(core, XSDIRX_GLBL_IER_REG,
 894                             XSDIRX_GLBL_INTR_EN_MASK);
 895}
 896
 897static inline void xsdirx_clearintr(struct xsdirxss_core *core, u32 mask)
 898{
 899        xsdirxss_set(core, XSDIRX_ISR_REG, mask);
 900}
 901
 902static void xsdirx_vid_bridge_control(struct xsdirxss_core *core,
 903                                      bool enable)
 904{
 905        struct xsdirxss_state *state =
 906                container_of(core, struct xsdirxss_state, core);
 907        u32 mask = XSDIRX_RST_CTRL_SDIRX_BRIDGE_ENB_MASK;
 908
 909        if (state->format.code == MEDIA_BUS_FMT_VUY10_1X30 ||
 910            state->format.code == MEDIA_BUS_FMT_RBG101010_1X30 ||
 911            state->format.code == MEDIA_BUS_FMT_RBG121212_1X36 ||
 912            state->format.code == MEDIA_BUS_FMT_VUY12_1X36)
 913                mask |= (XSDIRX_RST_CTRL_BRIDGE_CH_FMT_YUV444 <<
 914                         XSDIRX_RST_CTRL_BRIDGE_CH_FMT_OFFSET);
 915
 916        if (enable)
 917                xsdirxss_set(core, XSDIRX_RST_CTRL_REG, mask);
 918        else
 919                xsdirxss_clr(core, XSDIRX_RST_CTRL_REG, mask);
 920}
 921
 922static void xsdirx_axis4_bridge_control(struct xsdirxss_core *core,
 923                                        bool enable)
 924{
 925        if (enable)
 926                xsdirxss_set(core, XSDIRX_RST_CTRL_REG,
 927                             XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK);
 928        else
 929                xsdirxss_clr(core, XSDIRX_RST_CTRL_REG,
 930                             XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK);
 931}
 932
 933static void xsdirx_streamflow_control(struct xsdirxss_core *core, bool enable)
 934{
 935        /* The sdi to native bridge is followed by native to axis4 bridge */
 936        if (enable) {
 937                xsdirx_axis4_bridge_control(core, enable);
 938                xsdirx_vid_bridge_control(core, enable);
 939        } else {
 940                xsdirx_vid_bridge_control(core, enable);
 941                xsdirx_axis4_bridge_control(core, enable);
 942        }
 943}
 944
 945static void xsdirxss_get_framerate(struct v4l2_fract *frame_interval,
 946                                   u32 framerate)
 947{
 948        switch (framerate) {
 949        case XSDIRX_TS_DET_STAT_RATE_23_98HZ:
 950                frame_interval->numerator = 1001;
 951                frame_interval->denominator = 24000;
 952                break;
 953        case XSDIRX_TS_DET_STAT_RATE_24HZ:
 954                frame_interval->numerator = 1000;
 955                frame_interval->denominator = 24000;
 956                break;
 957        case XSDIRX_TS_DET_STAT_RATE_25HZ:
 958                frame_interval->numerator = 1000;
 959                frame_interval->denominator = 25000;
 960                break;
 961        case XSDIRX_TS_DET_STAT_RATE_29_97HZ:
 962                frame_interval->numerator = 1001;
 963                frame_interval->denominator = 30000;
 964                break;
 965        case XSDIRX_TS_DET_STAT_RATE_30HZ:
 966                frame_interval->numerator = 1000;
 967                frame_interval->denominator = 30000;
 968                break;
 969        case XSDIRX_TS_DET_STAT_RATE_47_95HZ:
 970                frame_interval->numerator = 1001;
 971                frame_interval->denominator = 48000;
 972                break;
 973        case XSDIRX_TS_DET_STAT_RATE_48HZ:
 974                frame_interval->numerator = 1000;
 975                frame_interval->denominator = 48000;
 976                break;
 977        case XSDIRX_TS_DET_STAT_RATE_50HZ:
 978                frame_interval->numerator = 1000;
 979                frame_interval->denominator = 50000;
 980                break;
 981        case XSDIRX_TS_DET_STAT_RATE_59_94HZ:
 982                frame_interval->numerator = 1001;
 983                frame_interval->denominator = 60000;
 984                break;
 985        case XSDIRX_TS_DET_STAT_RATE_60HZ:
 986                frame_interval->numerator = 1000;
 987                frame_interval->denominator = 60000;
 988                break;
 989        case XSDIRX_TS_DET_STAT_RATE_95_90HZ:
 990                frame_interval->numerator = 1001;
 991                frame_interval->denominator = 96000;
 992                break;
 993        case XSDIRX_TS_DET_STAT_RATE_96HZ:
 994                frame_interval->numerator = 1000;
 995                frame_interval->denominator = 96000;
 996                break;
 997        case XSDIRX_TS_DET_STAT_RATE_100HZ:
 998                frame_interval->numerator = 1000;
 999                frame_interval->denominator = 100000;
1000                break;
1001        case XSDIRX_TS_DET_STAT_RATE_119_88HZ:
1002                frame_interval->numerator = 1001;
1003                frame_interval->denominator = 120000;
1004                break;
1005        case XSDIRX_TS_DET_STAT_RATE_120HZ:
1006                frame_interval->numerator = 1000;
1007                frame_interval->denominator = 120000;
1008                break;
1009        default:
1010                frame_interval->numerator = 1;
1011                frame_interval->denominator = 1;
1012        }
1013}
1014
1015static void xsdirxss_set_gtclk(struct xsdirxss_state *state)
1016{
1017        struct clk *gtclk;
1018        unsigned long clkrate;
1019        int ret, is_frac;
1020        struct xsdirxss_core *core = &state->core;
1021        u32 mode;
1022
1023        mode = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1024        mode &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
1025
1026        xsdirx_core_disable(core);
1027        xsdirx_globalintr(core, false);
1028        xsdirx_disableintr(core, XSDIRX_INTR_ALL_MASK);
1029
1030        /* get sdi_rx_clk */
1031        gtclk = core->clks[1].clk;
1032        is_frac = state->frame_interval.numerator == 1001 ? 1 : 0;
1033
1034        /*
1035         * PLL ref clock is 148.5MHz for integer frame rates
1036         * and 148.35MHz for fractional frame rates.
1037         * For SD mode its always 148.5MHz for integer & fractional.
1038         * Please refer to Table 5-2 in PG290
1039         * https://www.xilinx.com/support/documentation/ip_documentation/v_smpte_uhdsdi_rx_ss/v2_0/pg290-v-smpte-uhdsdi-rx-ss.pdf
1040         */
1041        if (!is_frac || mode == XSDIRX_MODE_SD_MASK)
1042                clkrate = CLK_INT;
1043        else
1044                clkrate = (CLK_INT * 1000) / 1001;
1045
1046        ret = clk_set_rate(gtclk, clkrate);
1047        if (ret)
1048                dev_err(core->dev, "failed to set clk rate = %d\n", ret);
1049
1050        /* reset qpll0 and picxo core */
1051        xsdirxss_gt_reset(core);
1052
1053        clkrate = clk_get_rate(gtclk);
1054
1055        dev_dbg(core->dev, "clkrate = %lu is_frac = %d\n",
1056                clkrate, is_frac);
1057
1058        xsdirx_framer(core, state->framer_enable);
1059        xsdirx_setedherrcnttrigger(core, state->edhmask);
1060        xsdirx_setvidlockwindow(core, state->vidlockwin);
1061        xsdirx_set_modedetect(core, state->searchmask);
1062        xsdirx_enableintr(core, XSDIRX_INTR_ALL_MASK);
1063        xsdirx_globalintr(core, true);
1064        xsdirx_core_enable(core);
1065}
1066
1067/**
1068 * xsdirx_get_stream_properties - Get SDI Rx stream properties
1069 * @state: pointer to driver state
1070 *
1071 * This function decodes the stream's ST352 payload (if available) to get
1072 * stream properties like width, height, picture type (interlaced/progressive),
1073 * etc.
1074 *
1075 * Return: 0 for success else errors
1076 */
1077static int xsdirx_get_stream_properties(struct xsdirxss_state *state)
1078{
1079        struct xsdirxss_core *core = &state->core;
1080        u32 mode, payload = 0, val, family, valid, tscan;
1081        u8 byte1 = 0, active_luma = 0, pic_type = 0, framerate = 0;
1082        u8 sampling = XST352_BYTE3_COLOR_FORMAT_422;
1083        struct v4l2_mbus_framefmt *format = &state->format;
1084        u32 bpc = XST352_BYTE4_BIT_DEPTH_10;
1085
1086        mode = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1087        mode &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
1088
1089        valid = xsdirxss_read(core, XSDIRX_ST352_VALID_REG);
1090
1091        if (mode >= XSDIRX_MODE_3G_MASK && !valid) {
1092                dev_err_ratelimited(core->dev, "No valid ST352 payload present even for 3G mode and above\n");
1093                return -EINVAL;
1094        }
1095
1096        val = xsdirxss_read(core, XSDIRX_TS_DET_STAT_REG);
1097        if (valid & XSDIRX_ST352_VALID_DS1_MASK) {
1098                payload = xsdirxss_read(core, XSDIRX_ST352_DS1_REG);
1099                byte1 = (payload >> XST352_PAYLOAD_BYTE1_SHIFT) &
1100                                XST352_PAYLOAD_BYTE_MASK;
1101                active_luma = (payload & XST352_BYTE3_ACT_LUMA_COUNT_MASK) >>
1102                                XST352_BYTE3_ACT_LUMA_COUNT_OFFSET;
1103                pic_type = (payload & XST352_BYTE2_PIC_TYPE_MASK) >>
1104                                XST352_BYTE2_PIC_TYPE_OFFSET;
1105                framerate = (payload >> XST352_BYTE2_FPS_SHIFT) &
1106                                XST352_BYTE2_FPS_MASK;
1107                tscan = (payload & XST352_BYTE2_TS_TYPE_MASK) >>
1108                                XST352_BYTE2_TS_TYPE_OFFSET;
1109                sampling = (payload & XST352_BYTE3_COLOR_FORMAT_MASK) >>
1110                           XST352_BYTE3_COLOR_FORMAT_OFFSET;
1111                bpc = (payload & XST352_BYTE4_BIT_DEPTH_MASK) >>
1112                        XST352_BYTE4_BIT_DEPTH_OFFSET;
1113        } else {
1114                dev_dbg(core->dev, "No ST352 payload available : Mode = %d\n",
1115                        mode);
1116                framerate = (val & XSDIRX_TS_DET_STAT_RATE_MASK) >>
1117                                XSDIRX_TS_DET_STAT_RATE_OFFSET;
1118                tscan = (val & XSDIRX_TS_DET_STAT_SCAN_MASK) >>
1119                                XSDIRX_TS_DET_STAT_SCAN_OFFSET;
1120        }
1121
1122        if ((bpc == XST352_BYTE4_BIT_DEPTH_10 && core->bpc != 10) ||
1123            (bpc == XST352_BYTE4_BIT_DEPTH_12 && core->bpc != 12)) {
1124                dev_dbg(core->dev, "Bit depth not supported. bpc = %d core->bpc = %d\n",
1125                        bpc, core->bpc);
1126                return -EINVAL;
1127        }
1128
1129        family = (val & XSDIRX_TS_DET_STAT_FAMILY_MASK) >>
1130                        XSDIRX_TS_DET_STAT_FAMILY_OFFSET;
1131        state->ts_is_interlaced = tscan ? false : true;
1132
1133        dev_dbg(core->dev, "ts_is_interlaced = %d, family = %d\n",
1134                state->ts_is_interlaced, family);
1135
1136        switch (mode) {
1137        case XSDIRX_MODE_HD_MASK:
1138                if (!valid) {
1139                        /* No payload obtained */
1140                        dev_dbg(core->dev, "frame rate : %d, tscan = %d\n",
1141                                framerate, tscan);
1142                        /*
1143                         * NOTE : A progressive segmented frame pSF will be
1144                         * reported incorrectly as Interlaced as we rely on IP's
1145                         * transport scan locked bit.
1146                         */
1147                        dev_warn(core->dev, "pSF will be incorrectly reported as Interlaced\n");
1148
1149                        switch (framerate) {
1150                        case XSDIRX_TS_DET_STAT_RATE_23_98HZ:
1151                        case XSDIRX_TS_DET_STAT_RATE_24HZ:
1152                        case XSDIRX_TS_DET_STAT_RATE_25HZ:
1153                        case XSDIRX_TS_DET_STAT_RATE_29_97HZ:
1154                        case XSDIRX_TS_DET_STAT_RATE_30HZ:
1155                                if (family == XSDIRX_SMPTE_ST_296) {
1156                                        format->width = 1280;
1157                                        format->height = 720;
1158                                        format->field = V4L2_FIELD_NONE;
1159                                } else if (family == XSDIRX_SMPTE_ST_2048_2) {
1160                                        format->width = 2048;
1161                                        format->height = 1080;
1162                                        if (tscan)
1163                                                format->field = V4L2_FIELD_NONE;
1164                                        else
1165                                                format->field =
1166                                                        V4L2_FIELD_ALTERNATE;
1167                                } else {
1168                                        format->width = 1920;
1169                                        format->height = 1080;
1170                                        if (tscan)
1171                                                format->field = V4L2_FIELD_NONE;
1172                                        else
1173                                                format->field =
1174                                                        V4L2_FIELD_ALTERNATE;
1175                                }
1176                                break;
1177                        case XSDIRX_TS_DET_STAT_RATE_50HZ:
1178                        case XSDIRX_TS_DET_STAT_RATE_59_94HZ:
1179                        case XSDIRX_TS_DET_STAT_RATE_60HZ:
1180                                if (family == XSDIRX_SMPTE_ST_274) {
1181                                        format->width = 1920;
1182                                        format->height = 1080;
1183                                } else {
1184                                        format->width = 1280;
1185                                        format->height = 720;
1186                                }
1187                                format->field = V4L2_FIELD_NONE;
1188                                break;
1189                        default:
1190                                format->width = 1920;
1191                                format->height = 1080;
1192                                format->field = V4L2_FIELD_NONE;
1193                        }
1194                } else {
1195                        dev_dbg(core->dev, "Got the payload\n");
1196                        switch (byte1) {
1197                        case XST352_BYTE1_ST292_1x720L_1_5G:
1198                                /* SMPTE ST 292-1 for 720 line payloads */
1199                                format->width = 1280;
1200                                format->height = 720;
1201                                break;
1202                        case XST352_BYTE1_ST292_1x1080L_1_5G:
1203                                /* SMPTE ST 292-1 for 1080 line payloads */
1204                                format->height = 1080;
1205                                if (active_luma)
1206                                        format->width = 2048;
1207                                else
1208                                        format->width = 1920;
1209                                break;
1210                        default:
1211                                dev_dbg(core->dev, "Unknown HD Mode SMPTE standard\n");
1212                                return -EINVAL;
1213                        }
1214                }
1215                break;
1216        case XSDIRX_MODE_SD_MASK:
1217                format->field = V4L2_FIELD_ALTERNATE;
1218
1219                switch (family) {
1220                case XSDIRX_NTSC:
1221                        format->width = 720;
1222                        format->height = 486;
1223                        break;
1224                case XSDIRX_PAL:
1225                        format->width = 720;
1226                        format->height = 576;
1227                        break;
1228                default:
1229                        dev_dbg(core->dev, "Unknown SD Mode SMPTE standard\n");
1230                        return -EINVAL;
1231                }
1232                break;
1233        case XSDIRX_MODE_3G_MASK:
1234                switch (byte1) {
1235                case XST352_BYTE1_ST425_2008_750L_3GB:
1236                        /* Sec 4.1.6.1 SMPTE 425-2008 */
1237                case XST352_BYTE1_ST372_2x720L_3GB:
1238                        /* Table 13 SMPTE 425-2008 */
1239                        format->width = 1280;
1240                        format->height = 720;
1241                        break;
1242                case XST352_BYTE1_ST425_2008_1125L_3GA:
1243                        /* ST352 Table SMPTE 425-1 */
1244                case XST352_BYTE1_ST372_DL_3GB:
1245                        /* Table 13 SMPTE 425-2008 */
1246                case XST352_BYTE1_ST372_2x1080L_3GB:
1247                        /* Table 13 SMPTE 425-2008 */
1248                        format->height = 1080;
1249                        if (active_luma)
1250                                format->width = 2048;
1251                        else
1252                                format->width = 1920;
1253                        break;
1254                default:
1255                        dev_dbg(core->dev, "Unknown 3G Mode SMPTE standard\n");
1256                        return -EINVAL;
1257                }
1258                break;
1259        case XSDIRX_MODE_6G_MASK:
1260                switch (byte1) {
1261                case XST352_BYTE1_ST2081_10_DL_2160L_6G:
1262                        /* Dual link 6G */
1263                case XST352_BYTE1_ST2081_10_2160L_6G:
1264                        /* Table 3 SMPTE ST 2081-10 */
1265                        format->height = 2160;
1266                        if (active_luma)
1267                                format->width = 4096;
1268                        else
1269                                format->width = 3840;
1270                        break;
1271                case XST352_BYTE1_ST2081_10_2_1080L_6G:
1272                        format->height = 1080;
1273                        if (active_luma)
1274                                format->width = 2048;
1275                        else
1276                                format->width = 1920;
1277                        break;
1278                default:
1279                        dev_dbg(core->dev, "Unknown 6G Mode SMPTE standard\n");
1280                        return -EINVAL;
1281                }
1282                break;
1283        case XSDIRX_MODE_12GI_MASK:
1284        case XSDIRX_MODE_12GF_MASK:
1285                switch (byte1) {
1286                case XST352_BYTE1_ST2082_10_2160L_12G:
1287                        /* Section 4.3.1 SMPTE ST 2082-10 */
1288                        format->height = 2160;
1289                        if (active_luma)
1290                                format->width = 4096;
1291                        else
1292                                format->width = 3840;
1293                        break;
1294                default:
1295                        dev_dbg(core->dev, "Unknown 12G Mode SMPTE standard\n");
1296                        return -EINVAL;
1297                }
1298                break;
1299        default:
1300                dev_err(core->dev, "Invalid Mode\n");
1301                return -EINVAL;
1302        }
1303
1304        if (valid) {
1305                if (pic_type)
1306                        format->field = V4L2_FIELD_NONE;
1307                else
1308                        format->field = V4L2_FIELD_ALTERNATE;
1309
1310                if (format->height == 1080 && pic_type && !tscan)
1311                        format->field = V4L2_FIELD_ALTERNATE;
1312
1313                if (byte1 == XST352_BYTE1_ST372_DL_3GB) {
1314                        if (!pic_type)
1315                                format->field = V4L2_FIELD_ALTERNATE;
1316                        else
1317                                format->field = V4L2_FIELD_NONE;
1318                }
1319        }
1320
1321        if (format->field == V4L2_FIELD_ALTERNATE)
1322                format->height = format->height / 2;
1323
1324        switch (sampling) {
1325        case XST352_BYTE3_COLOR_FORMAT_420:
1326                if (core->bpc == 10)
1327                        format->code = MEDIA_BUS_FMT_VYYUYY10_4X20;
1328                else
1329                        format->code = MEDIA_BUS_FMT_UYYVYY12_4X24;
1330                break;
1331        case XST352_BYTE3_COLOR_FORMAT_422:
1332                if (core->bpc == 10)
1333                        format->code = MEDIA_BUS_FMT_UYVY10_1X20;
1334                else
1335                        format->code = MEDIA_BUS_FMT_UYVY12_1X24;
1336                break;
1337        case XST352_BYTE3_COLOR_FORMAT_YUV444:
1338                if (core->bpc == 10)
1339                        format->code = MEDIA_BUS_FMT_VUY10_1X30;
1340                else
1341                        format->code = MEDIA_BUS_FMT_VUY12_1X36;
1342                break;
1343        case XST352_BYTE3_COLOR_FORMAT_GBR:
1344                if (core->bpc == 10)
1345                        format->code = MEDIA_BUS_FMT_RBG101010_1X30;
1346                else
1347                        format->code = MEDIA_BUS_FMT_RBG121212_1X36;
1348                break;
1349        default:
1350                dev_err(core->dev, "Unsupported color format : %d\n", sampling);
1351                return -EINVAL;
1352        }
1353
1354        xsdirxss_get_framerate(&state->frame_interval, framerate);
1355
1356        memset(&state->static_hdr, 0, sizeof(state->static_hdr));
1357
1358        state->static_hdr.eotf = V4L2_EOTF_TRADITIONAL_GAMMA_SDR;
1359        format->colorspace = V4L2_COLORSPACE_SMPTE170M;
1360        format->xfer_func = V4L2_XFER_FUNC_709;
1361        format->ycbcr_enc = V4L2_YCBCR_ENC_601;
1362        format->quantization = V4L2_QUANTIZATION_LIM_RANGE;
1363
1364        if (mode != XSDIRX_MODE_SD_MASK) {
1365                u8 eotf = (payload & XST352_BYTE2_EOTF_MASK) >>
1366                        XST352_BYTE2_EOTF_OFFSET;
1367
1368                u8 colorimetry = (payload & XST352_BYTE2_COLORIMETRY_MASK) >>
1369                        XST352_BYTE2_COLORIMETRY_OFFSET;
1370
1371                /*
1372                 * Bit 7 and 4 of byte 3 form the colorimetry field for HD.
1373                 * Checkout SMPTE 292-1:2018 Sec 9.5 for details
1374                 */
1375                if (mode == XSDIRX_MODE_HD_MASK ||
1376                    byte1 == XST352_BYTE1_ST372_DL_3GB) {
1377                        /* For case when there might be no payload */
1378                        colorimetry = XST352_BYTE2_COLORIMETRY_BT709;
1379
1380                        if (valid & XSDIRX_ST352_VALID_DS1_MASK) {
1381                                colorimetry = (FIELD_GET(BIT(23), payload) << 1) |
1382                                        FIELD_GET(BIT(20), payload);
1383                        }
1384                }
1385
1386                /* Get the EOTF function */
1387                switch (eotf) {
1388                case XST352_BYTE2_EOTF_SDRTV:
1389                        state->static_hdr.eotf =
1390                                V4L2_EOTF_TRADITIONAL_GAMMA_SDR;
1391                        break;
1392                case XST352_BYTE2_EOTF_SMPTE2084:
1393                        state->static_hdr.eotf = V4L2_EOTF_SMPTE_ST2084;
1394                        format->xfer_func = V4L2_XFER_FUNC_SMPTE2084;
1395                        break;
1396                case XST352_BYTE2_EOTF_HLG:
1397                        state->static_hdr.eotf = V4L2_EOTF_BT_2100_HLG;
1398                        format->xfer_func = V4L2_XFER_FUNC_HLG;
1399                        break;
1400                }
1401
1402                /* Get the colorimetry data */
1403                switch (colorimetry) {
1404                case XST352_BYTE2_COLORIMETRY_BT709:
1405                        format->colorspace = V4L2_COLORSPACE_REC709;
1406                        format->ycbcr_enc = V4L2_YCBCR_ENC_709;
1407                        break;
1408                case XST352_BYTE2_COLORIMETRY_UHDTV:
1409                        format->colorspace = V4L2_COLORSPACE_BT2020;
1410                        format->ycbcr_enc = V4L2_YCBCR_ENC_BT2020;
1411                        break;
1412                default:
1413                        /*
1414                         * Modes which will have VANC and Unknown colorimetery
1415                         * are currently not supported
1416                         */
1417                        format->colorspace = V4L2_COLORSPACE_DEFAULT;
1418                        format->xfer_func = V4L2_XFER_FUNC_DEFAULT;
1419                        break;
1420                }
1421        }
1422
1423        /* Refer to Table 3 ST 2082-10:2018 */
1424        if (mode == XSDIRX_MODE_12GI_OFFSET ||
1425            mode == XSDIRX_MODE_12GF_OFFSET) {
1426                switch (sampling) {
1427                case XST352_BYTE3_COLOR_FORMAT_420:
1428                case XST352_BYTE3_COLOR_FORMAT_422:
1429                case XST352_BYTE3_COLOR_FORMAT_YUV444:
1430                        if (payload & XST352_BYTE4_LUM_COL_DIFF_MASK)
1431                                format->ycbcr_enc =
1432                                        V4L2_YCBCR_ENC_BT2020_CONST_LUM;
1433                        else
1434                                format->ycbcr_enc =
1435                                        V4L2_YCBCR_ENC_BT2020;
1436                }
1437        }
1438
1439        /* Set quantization range */
1440        if (sampling == XST352_BYTE3_COLOR_FORMAT_GBR &&
1441            format->colorspace != V4L2_COLORSPACE_BT2020)
1442                format->quantization = V4L2_QUANTIZATION_FULL_RANGE;
1443
1444        /*
1445         * Save the payload to be used in vsync interrupt to check for
1446         * change in payload without video lock/unlock sequence
1447         */
1448        if (valid & XSDIRX_ST352_VALID_DS1_MASK)
1449                state->prev_payload = payload;
1450
1451        dev_dbg(core->dev, "Stream width = %d height = %d Field = %d payload = 0x%08x ts = 0x%08x\n",
1452                format->width, format->height, format->field, payload, val);
1453        dev_dbg(core->dev, "frame rate numerator = %d denominator = %d\n",
1454                state->frame_interval.numerator,
1455                state->frame_interval.denominator);
1456        dev_dbg(core->dev, "Stream code = 0x%x\n", format->code);
1457        return 0;
1458}
1459
1460/**
1461 * xsdirxss_irq_handler - Interrupt handler for SDI Rx
1462 * @irq: IRQ number
1463 * @dev_id: Pointer to device state
1464 *
1465 * The SDI Rx interrupts are cleared by writing 1 to corresponding bit.
1466 *
1467 * Return: IRQ_HANDLED after handling interrupts
1468 */
1469static irqreturn_t xsdirxss_irq_handler(int irq, void *dev_id)
1470{
1471        struct xsdirxss_state *state = (struct xsdirxss_state *)dev_id;
1472        struct xsdirxss_core *core = &state->core;
1473        u32 status;
1474
1475        status = xsdirxss_read(core, XSDIRX_ISR_REG);
1476        dev_dbg(core->dev, "interrupt status = 0x%08x\n", status);
1477
1478        if (!status)
1479                return IRQ_NONE;
1480
1481        xsdirxss_write(core, XSDIRX_ISR_REG, status);
1482
1483        if (status & XSDIRX_INTR_VIDLOCK_MASK ||
1484            status & XSDIRX_INTR_VIDUNLOCK_MASK) {
1485                u32 val1, val2;
1486                bool gen_event = true;
1487
1488                dev_dbg(core->dev, "video lock/unlock interrupt\n");
1489
1490                xsdirx_streamflow_control(core, false);
1491                state->streaming = false;
1492
1493                val1 = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1494                val2 = xsdirxss_read(core, XSDIRX_TS_DET_STAT_REG);
1495
1496                if ((val1 & XSDIRX_MODE_DET_STAT_MODE_LOCK_MASK) &&
1497                    (val2 & XSDIRX_TS_DET_STAT_LOCKED_MASK)) {
1498                        u32 mask = XSDIRX_RST_CTRL_RST_CRC_ERRCNT_MASK |
1499                                   XSDIRX_RST_CTRL_RST_EDH_ERRCNT_MASK;
1500
1501                        dev_dbg(core->dev, "video lock interrupt\n");
1502
1503                        xsdirxss_set(core, XSDIRX_RST_CTRL_REG, mask);
1504                        xsdirxss_clr(core, XSDIRX_RST_CTRL_REG, mask);
1505
1506                        val1 = xsdirxss_read(core, XSDIRX_ST352_VALID_REG);
1507                        val2 = xsdirxss_read(core, XSDIRX_ST352_DS1_REG);
1508
1509                        dev_dbg(core->dev, "valid st352 mask = 0x%08x\n", val1);
1510                        dev_dbg(core->dev, "st352 payload = 0x%08x\n", val2);
1511
1512                        if (state->vidlocked) {
1513                                gen_event = false;
1514                        } else if (!xsdirx_get_stream_properties(state)) {
1515                                state->vidlocked = true;
1516                                xsdirxss_set_gtclk(state);
1517                        } else {
1518                                dev_err_ratelimited(core->dev, "Unable to get stream properties!\n");
1519                                state->vidlocked = false;
1520                        }
1521
1522                } else {
1523                        dev_dbg(core->dev, "video unlock interrupt\n");
1524                        state->vidlocked = false;
1525                }
1526                if (gen_event) {
1527                        memset(&state->event, 0, sizeof(state->event));
1528                        state->event.type = V4L2_EVENT_SOURCE_CHANGE;
1529                        state->event.u.src_change.changes =
1530                                V4L2_EVENT_SRC_CH_RESOLUTION;
1531                        v4l2_subdev_notify_event(&state->subdev, &state->event);
1532                }
1533        }
1534
1535        if (status & XSDIRX_INTR_UNDERFLOW_MASK) {
1536                dev_dbg(core->dev, "Video in to AXI4 Stream core underflow interrupt\n");
1537
1538                memset(&state->event, 0, sizeof(state->event));
1539                state->event.type = V4L2_EVENT_XLNXSDIRX_UNDERFLOW;
1540                v4l2_subdev_notify_event(&state->subdev, &state->event);
1541        }
1542
1543        if (status & XSDIRX_INTR_OVERFLOW_MASK) {
1544                dev_dbg(core->dev, "Video in to AXI4 Stream core overflow interrupt\n");
1545
1546                memset(&state->event, 0, sizeof(state->event));
1547                state->event.type = V4L2_EVENT_XLNXSDIRX_OVERFLOW;
1548                v4l2_subdev_notify_event(&state->subdev, &state->event);
1549        }
1550
1551        if (status & XSDIRX_INTR_VSYNC_MASK) {
1552                u32 valid, payload;
1553                /*
1554                 * If ST352 payload changed without generating video unlock/
1555                 * lock sequence, then use vsync interrupt to update the
1556                 * frame rate, video format and static hdr structures and
1557                 * notify the userspace.
1558                 */
1559
1560                /*
1561                 * Do this while driver has state as video locked though
1562                 * it is implicit from the interrupt type i.e. vsync interrupt
1563                 * can occur only when video is locked.
1564                 * Avoid generating source change event twice.
1565                 */
1566                if (status & XSDIRX_INTR_VIDLOCK_MASK)
1567                        return IRQ_HANDLED;
1568
1569                valid = xsdirxss_read(core, XSDIRX_ST352_VALID_REG);
1570                if (!(valid & XSDIRX_ST352_VALID_DS1_MASK))
1571                        return IRQ_HANDLED;
1572
1573                payload = xsdirxss_read(core, XSDIRX_ST352_DS1_REG);
1574                /* Return if previous and current payload are same */
1575                if (payload == state->prev_payload)
1576                        return IRQ_HANDLED;
1577
1578                if (xsdirx_get_stream_properties(state))
1579                        return IRQ_HANDLED;
1580
1581                memset(&state->event, 0, sizeof(state->event));
1582                state->event.type = V4L2_EVENT_SOURCE_CHANGE;
1583                state->event.u.src_change.changes =
1584                        V4L2_EVENT_SRC_CH_RESOLUTION;
1585                v4l2_subdev_notify_event(&state->subdev, &state->event);
1586        }
1587
1588        return IRQ_HANDLED;
1589}
1590
1591/**
1592 * xsdirxss_subscribe_event - Subscribe to video lock and unlock event
1593 * @sd: V4L2 Sub device
1594 * @fh: V4L2 File Handle
1595 * @sub: Subcribe event structure
1596 *
1597 * Return: 0 on success, errors otherwise
1598 */
1599static int xsdirxss_subscribe_event(struct v4l2_subdev *sd,
1600                                    struct v4l2_fh *fh,
1601                                    struct v4l2_event_subscription *sub)
1602{
1603        int ret;
1604        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1605        struct xsdirxss_core *core = &xsdirxss->core;
1606
1607        switch (sub->type) {
1608        case V4L2_EVENT_XLNXSDIRX_UNDERFLOW:
1609        case V4L2_EVENT_XLNXSDIRX_OVERFLOW:
1610                ret = v4l2_event_subscribe(fh, sub, XSDIRX_MAX_EVENTS, NULL);
1611                break;
1612        case V4L2_EVENT_SOURCE_CHANGE:
1613                ret = v4l2_src_change_event_subscribe(fh, sub);
1614                break;
1615        default:
1616                return -EINVAL;
1617        }
1618        dev_dbg(core->dev, "Event subscribed : 0x%08x\n", sub->type);
1619        return ret;
1620}
1621
1622/**
1623 * xsdirxss_unsubscribe_event - Unsubscribe from all events registered
1624 * @sd: V4L2 Sub device
1625 * @fh: V4L2 file handle
1626 * @sub: pointer to Event unsubscription structure
1627 *
1628 * Return: zero on success, else a negative error code.
1629 */
1630static int xsdirxss_unsubscribe_event(struct v4l2_subdev *sd,
1631                                      struct v4l2_fh *fh,
1632                                      struct v4l2_event_subscription *sub)
1633{
1634        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1635        struct xsdirxss_core *core = &xsdirxss->core;
1636
1637        dev_dbg(core->dev, "Event unsubscribe : 0x%08x\n", sub->type);
1638        return v4l2_event_unsubscribe(fh, sub);
1639}
1640
1641/**
1642 * xsdirxss_s_ctrl - This is used to set the Xilinx SDI Rx V4L2 controls
1643 * @ctrl: V4L2 control to be set
1644 *
1645 * This function is used to set the V4L2 controls for the Xilinx SDI Rx
1646 * Subsystem.
1647 *
1648 * Return: 0 on success, errors otherwise
1649 */
1650static int xsdirxss_s_ctrl(struct v4l2_ctrl *ctrl)
1651{
1652        int ret = 0;
1653        struct xsdirxss_state *xsdirxss =
1654                container_of(ctrl->handler,
1655                             struct xsdirxss_state, ctrl_handler);
1656        struct xsdirxss_core *core = &xsdirxss->core;
1657
1658        dev_dbg(core->dev, "set ctrl id = 0x%08x val = 0x%08x\n",
1659                ctrl->id, ctrl->val);
1660
1661        if (xsdirxss->streaming) {
1662                dev_err(core->dev, "Cannot set controls while streaming\n");
1663                return -EINVAL;
1664        }
1665
1666        xsdirx_core_disable(core);
1667        switch (ctrl->id) {
1668        case V4L2_CID_XILINX_SDIRX_FRAMER:
1669                xsdirx_framer(core, ctrl->val);
1670                xsdirxss->framer_enable = ctrl->val;
1671                break;
1672        case V4L2_CID_XILINX_SDIRX_VIDLOCK_WINDOW:
1673                xsdirx_setvidlockwindow(core, ctrl->val);
1674                xsdirxss->vidlockwin = ctrl->val;
1675                break;
1676        case V4L2_CID_XILINX_SDIRX_EDH_ERRCNT_ENABLE:
1677                xsdirx_setedherrcnttrigger(core, ctrl->val);
1678                xsdirxss->edhmask = ctrl->val;
1679                break;
1680        case V4L2_CID_XILINX_SDIRX_SEARCH_MODES:
1681                if (ctrl->val) {
1682                        if (core->mode == XSDIRXSS_SDI_STD_3G) {
1683                                dev_dbg(core->dev, "Upto 3G supported\n");
1684                                ctrl->val &= ~(BIT(XSDIRX_MODE_6G_OFFSET) |
1685                                               BIT(XSDIRX_MODE_12GI_OFFSET) |
1686                                               BIT(XSDIRX_MODE_12GF_OFFSET));
1687                        }
1688
1689                        if (core->mode == XSDIRXSS_SDI_STD_6G) {
1690                                dev_dbg(core->dev, "Upto 6G supported\n");
1691                                ctrl->val &= ~(BIT(XSDIRX_MODE_12GI_OFFSET) |
1692                                               BIT(XSDIRX_MODE_12GF_OFFSET));
1693                        }
1694
1695                        ret = xsdirx_set_modedetect(core, ctrl->val);
1696                        if (!ret)
1697                                xsdirxss->searchmask = ctrl->val;
1698                } else {
1699                        dev_err(core->dev, "Select at least one mode!\n");
1700                        return -EINVAL;
1701                }
1702                break;
1703        default:
1704                xsdirxss_set(core, XSDIRX_RST_CTRL_REG,
1705                             XSDIRX_RST_CTRL_SS_EN_MASK);
1706                return -EINVAL;
1707        }
1708        xsdirx_core_enable(core);
1709        return ret;
1710}
1711
1712/**
1713 * xsdirxss_g_volatile_ctrl - get the Xilinx SDI Rx controls
1714 * @ctrl: Pointer to V4L2 control
1715 *
1716 * Return: 0 on success, errors otherwise
1717 */
1718static int xsdirxss_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1719{
1720        u32 val;
1721        struct xsdirxss_state *xsdirxss =
1722                container_of(ctrl->handler,
1723                             struct xsdirxss_state, ctrl_handler);
1724        struct xsdirxss_core *core = &xsdirxss->core;
1725        struct v4l2_metadata_hdr *hdr_ptr;
1726
1727        switch (ctrl->id) {
1728        case V4L2_CID_XILINX_SDIRX_MODE_DETECT:
1729                if (!xsdirxss->vidlocked) {
1730                        dev_err(core->dev, "Can't get values when video not locked!\n");
1731                        return -EINVAL;
1732                }
1733                val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1734                val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
1735
1736                switch (val) {
1737                case XSDIRX_MODE_SD_MASK:
1738                        ctrl->val = XSDIRX_MODE_SD_OFFSET;
1739                        break;
1740                case XSDIRX_MODE_HD_MASK:
1741                        ctrl->val = XSDIRX_MODE_HD_OFFSET;
1742                        break;
1743                case XSDIRX_MODE_3G_MASK:
1744                        ctrl->val = XSDIRX_MODE_3G_OFFSET;
1745                        break;
1746                case XSDIRX_MODE_6G_MASK:
1747                        ctrl->val = XSDIRX_MODE_6G_OFFSET;
1748                        break;
1749                case XSDIRX_MODE_12GI_MASK:
1750                        ctrl->val = XSDIRX_MODE_12GI_OFFSET;
1751                        break;
1752                case XSDIRX_MODE_12GF_MASK:
1753                        ctrl->val = XSDIRX_MODE_12GF_OFFSET;
1754                        break;
1755                }
1756                break;
1757        case V4L2_CID_XILINX_SDIRX_CRC:
1758                ctrl->val = xsdirxss_read(core, XSDIRX_CRC_ERRCNT_REG);
1759                xsdirxss_write(core, XSDIRX_CRC_ERRCNT_REG, 0xFFFF);
1760                break;
1761        case V4L2_CID_XILINX_SDIRX_EDH_ERRCNT:
1762                val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1763                val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
1764                if (val == XSDIRX_MODE_SD_MASK) {
1765                        ctrl->val = xsdirxss_read(core, XSDIRX_EDH_ERRCNT_REG);
1766                } else {
1767                        dev_dbg(core->dev, "%d - not in SD mode\n", ctrl->id);
1768                        return -EINVAL;
1769                }
1770                break;
1771        case V4L2_CID_XILINX_SDIRX_EDH_STATUS:
1772                val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1773                val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
1774                if (val == XSDIRX_MODE_SD_MASK) {
1775                        ctrl->val = xsdirxss_read(core, XSDIRX_EDH_STAT_REG);
1776                } else {
1777                        dev_dbg(core->dev, "%d - not in SD mode\n", ctrl->id);
1778                        return -EINVAL;
1779                }
1780                break;
1781        case V4L2_CID_XILINX_SDIRX_TS_IS_INTERLACED:
1782                if (!xsdirxss->vidlocked) {
1783                        dev_err(core->dev, "Can't get values when video not locked!\n");
1784                        return -EINVAL;
1785                }
1786                ctrl->val = xsdirxss->ts_is_interlaced;
1787                break;
1788        case V4L2_CID_XILINX_SDIRX_ACTIVE_STREAMS:
1789                if (!xsdirxss->vidlocked) {
1790                        dev_err(core->dev, "Can't get values when video not locked!\n");
1791                        return -EINVAL;
1792                }
1793                val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1794                val &= XSDIRX_MODE_DET_STAT_ACT_STREAM_MASK;
1795                val >>= XSDIRX_MODE_DET_STAT_ACT_STREAM_OFFSET;
1796                ctrl->val = 1 << val;
1797                break;
1798        case V4L2_CID_XILINX_SDIRX_IS_3GB:
1799                if (!xsdirxss->vidlocked) {
1800                        dev_err(core->dev, "Can't get values when video not locked!\n");
1801                        return -EINVAL;
1802                }
1803                val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1804                val &= XSDIRX_MODE_DET_STAT_LVLB_3G_MASK;
1805                ctrl->val = val ? true : false;
1806                break;
1807        case V4L2_CID_METADATA_HDR:
1808                if (!xsdirxss->vidlocked) {
1809                        dev_err(core->dev, "Can't get values when video not locked!\n");
1810                        return -EINVAL;
1811                }
1812                hdr_ptr = (struct v4l2_metadata_hdr *)ctrl->p_new.p;
1813                hdr_ptr->metadata_type = V4L2_HDR_TYPE_HDR10;
1814                hdr_ptr->size = sizeof(struct v4l2_hdr10_payload);
1815                memcpy(hdr_ptr->payload, &xsdirxss->static_hdr,
1816                       hdr_ptr->size);
1817                break;
1818        default:
1819                dev_err(core->dev, "Get Invalid control id 0x%0x\n", ctrl->id);
1820                return -EINVAL;
1821        }
1822        dev_dbg(core->dev, "Get ctrl id = 0x%08x val = 0x%08x\n",
1823                ctrl->id, ctrl->val);
1824        return 0;
1825}
1826
1827/**
1828 * xsdirxss_log_status - Logs the status of the SDI Rx Subsystem
1829 * @sd: Pointer to V4L2 subdevice structure
1830 *
1831 * This function prints the current status of Xilinx SDI Rx Subsystem
1832 *
1833 * Return: 0 on success
1834 */
1835static int xsdirxss_log_status(struct v4l2_subdev *sd)
1836{
1837        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1838        struct xsdirxss_core *core = &xsdirxss->core;
1839        u32 i;
1840
1841        v4l2_info(sd, "***** SDI Rx subsystem reg dump start *****\n");
1842        for (i = 0; i < 0x28; i++) {
1843                u32 data;
1844
1845                data = xsdirxss_read(core, i * 4);
1846                v4l2_info(sd, "offset 0x%08x data 0x%08x\n",
1847                          i * 4, data);
1848        }
1849        v4l2_info(sd, "***** SDI Rx subsystem reg dump end *****\n");
1850        return 0;
1851}
1852
1853/**
1854 * xsdirxss_g_frame_interval - Get the frame interval
1855 * @sd: V4L2 Sub device
1856 * @fi: Pointer to V4l2 Sub device frame interval structure
1857 *
1858 * This function is used to get the frame interval.
1859 * The frame rate can be integral or fractional.
1860 * Integral frame rate e.g. numerator = 1000, denominator = 24000 => 24 fps
1861 * Fractional frame rate e.g. numerator = 1001, denominator = 24000 => 23.97 fps
1862 *
1863 * Return: 0 on success
1864 */
1865static int xsdirxss_g_frame_interval(struct v4l2_subdev *sd,
1866                                     struct v4l2_subdev_frame_interval *fi)
1867{
1868        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1869        struct xsdirxss_core *core = &xsdirxss->core;
1870
1871        if (!xsdirxss->vidlocked) {
1872                dev_err(core->dev, "Video not locked!\n");
1873                return -EINVAL;
1874        }
1875
1876        fi->interval = xsdirxss->frame_interval;
1877
1878        dev_dbg(core->dev, "frame rate numerator = %d denominator = %d\n",
1879                xsdirxss->frame_interval.numerator,
1880                xsdirxss->frame_interval.denominator);
1881        return 0;
1882}
1883
1884/**
1885 * xsdirxss_s_stream - It is used to start/stop the streaming.
1886 * @sd: V4L2 Sub device
1887 * @enable: Flag (True / False)
1888 *
1889 * This function controls the start or stop of streaming for the
1890 * Xilinx SDI Rx Subsystem.
1891 *
1892 * Return: 0 on success, errors otherwise
1893 */
1894static int xsdirxss_s_stream(struct v4l2_subdev *sd, int enable)
1895{
1896        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1897        struct xsdirxss_core *core = &xsdirxss->core;
1898
1899        if (enable) {
1900                if (!xsdirxss->vidlocked) {
1901                        dev_dbg(core->dev, "Video is not locked\n");
1902                        return -EINVAL;
1903                }
1904                if (xsdirxss->streaming) {
1905                        dev_dbg(core->dev, "Already streaming\n");
1906                        return -EINVAL;
1907                }
1908
1909                xsdirx_streamflow_control(core, true);
1910                xsdirxss->streaming = true;
1911                dev_dbg(core->dev, "Streaming started\n");
1912        } else {
1913                if (!xsdirxss->streaming) {
1914                        dev_dbg(core->dev, "Stopped streaming already\n");
1915                        return 0;
1916                }
1917
1918                xsdirx_streamflow_control(core, false);
1919                xsdirxss->streaming = false;
1920                dev_dbg(core->dev, "Streaming stopped\n");
1921        }
1922
1923        return 0;
1924}
1925
1926/**
1927 * xsdirxss_g_input_status - It is used to determine if the video signal
1928 * is present / locked onto or not.
1929 *
1930 * @sd: V4L2 Sub device
1931 * @status: status of signal locked
1932 *
1933 * This is used to determine if the video signal is present and locked onto
1934 * by the SDI Rx core or not based on vidlocked flag.
1935 *
1936 * Return: zero on success
1937 */
1938static int xsdirxss_g_input_status(struct v4l2_subdev *sd, u32 *status)
1939{
1940        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1941
1942        if (!xsdirxss->vidlocked)
1943                *status = V4L2_IN_ST_NO_SYNC | V4L2_IN_ST_NO_SIGNAL;
1944        else
1945                *status = 0;
1946
1947        return 0;
1948}
1949
1950static struct v4l2_mbus_framefmt *
1951__xsdirxss_get_pad_format(struct xsdirxss_state *xsdirxss,
1952                          struct v4l2_subdev_pad_config *cfg,
1953                          unsigned int pad, u32 which)
1954{
1955        struct v4l2_mbus_framefmt *format;
1956
1957        switch (which) {
1958        case V4L2_SUBDEV_FORMAT_TRY:
1959                format = v4l2_subdev_get_try_format(&xsdirxss->subdev, cfg,
1960                                                    pad);
1961                break;
1962        case V4L2_SUBDEV_FORMAT_ACTIVE:
1963                format = &xsdirxss->format;
1964                break;
1965        default:
1966                format = NULL;
1967                break;
1968        }
1969
1970        return format;
1971}
1972
1973/**
1974 * xsdirxss_get_format - Get the pad format
1975 * @sd: Pointer to V4L2 Sub device structure
1976 * @cfg: Pointer to sub device pad information structure
1977 * @fmt: Pointer to pad level media bus format
1978 *
1979 * This function is used to get the pad format information.
1980 *
1981 * Return: 0 on success
1982 */
1983static int xsdirxss_get_format(struct v4l2_subdev *sd,
1984                               struct v4l2_subdev_pad_config *cfg,
1985                               struct v4l2_subdev_format *fmt)
1986{
1987        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1988        struct xsdirxss_core *core = &xsdirxss->core;
1989        struct v4l2_mbus_framefmt *format;
1990
1991        if (!xsdirxss->vidlocked) {
1992                dev_err(core->dev, "Video not locked!\n");
1993                return -EINVAL;
1994        }
1995
1996        format = __xsdirxss_get_pad_format(xsdirxss, cfg,
1997                                           fmt->pad, fmt->which);
1998        if (!format)
1999                return -EINVAL;
2000
2001        fmt->format = *format;
2002
2003        dev_dbg(core->dev, "Stream width = %d height = %d Field = %d\n",
2004                fmt->format.width, fmt->format.height, fmt->format.field);
2005
2006        return 0;
2007}
2008
2009/**
2010 * xsdirxss_set_format - This is used to set the pad format
2011 * @sd: Pointer to V4L2 Sub device structure
2012 * @cfg: Pointer to sub device pad information structure
2013 * @fmt: Pointer to pad level media bus format
2014 *
2015 * This function is used to set the pad format.
2016 * Since the pad format is fixed in hardware, it can't be
2017 * modified on run time.
2018 *
2019 * Return: 0 on success
2020 */
2021static int xsdirxss_set_format(struct v4l2_subdev *sd,
2022                               struct v4l2_subdev_pad_config *cfg,
2023                               struct v4l2_subdev_format *fmt)
2024{
2025        struct v4l2_mbus_framefmt *__format;
2026        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
2027
2028        dev_dbg(xsdirxss->core.dev,
2029                "set width %d height %d code %d field %d colorspace %d\n",
2030                fmt->format.width, fmt->format.height,
2031                fmt->format.code, fmt->format.field,
2032                fmt->format.colorspace);
2033
2034        __format = __xsdirxss_get_pad_format(xsdirxss, cfg,
2035                                             fmt->pad, fmt->which);
2036        if (!__format)
2037                return -EINVAL;
2038
2039        /* Currently reset the code to one fixed in hardware */
2040        /* TODO : Add checks for width height */
2041        fmt->format.code = __format->code;
2042
2043        return 0;
2044}
2045
2046/**
2047 * xsdirxss_enum_mbus_code - Handle pixel format enumeration
2048 * @sd: pointer to v4l2 subdev structure
2049 * @cfg: V4L2 subdev pad configuration
2050 * @code: pointer to v4l2_subdev_mbus_code_enum structure
2051 *
2052 * Return: -EINVAL or zero on success
2053 */
2054static int xsdirxss_enum_mbus_code(struct v4l2_subdev *sd,
2055                                   struct v4l2_subdev_pad_config *cfg,
2056                                   struct v4l2_subdev_mbus_code_enum *code)
2057{
2058        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
2059        u32 index = code->index;
2060
2061        if (code->pad || index >= 4)
2062                return -EINVAL;
2063
2064        if (xsdirxss->core.bpc == 12)
2065                code->code = xsdirxss_12bpc_mbus_fmts[index];
2066        else
2067                code->code = xsdirxss_10bpc_mbus_fmts[index];
2068
2069        return 0;
2070}
2071
2072/**
2073 * xsdirxss_enum_dv_timings: Enumerate all the supported DV timings
2074 * @sd: pointer to v4l2 subdev structure
2075 * @timings: DV timings structure to be returned.
2076 *
2077 * Return: -EINVAL incase of invalid index and pad or zero on success
2078 */
2079static int xsdirxss_enum_dv_timings(struct v4l2_subdev *sd,
2080                                    struct v4l2_enum_dv_timings *timings)
2081{
2082        if (timings->index >= ARRAY_SIZE(fmt_cap))
2083                return -EINVAL;
2084
2085        if (timings->pad != 0)
2086                return -EINVAL;
2087
2088        timings->timings = fmt_cap[timings->index];
2089        return 0;
2090}
2091
2092/**
2093 * xsdirxss_query_dv_timings: Query for the current DV timings
2094 * @sd: pointer to v4l2 subdev structure
2095 * @timings: DV timings structure to be returned.
2096 *
2097 * Return: -ENOLCK when video is not locked, -ERANGE when corresponding timing
2098 * entry is not found or zero on success.
2099 */
2100static int xsdirxss_query_dv_timings(struct v4l2_subdev *sd,
2101                                     struct v4l2_dv_timings *timings)
2102{
2103        struct xsdirxss_state *state = to_xsdirxssstate(sd);
2104        unsigned int i;
2105
2106        if (!state->vidlocked)
2107                return -ENOLCK;
2108
2109        for (i = 0; i < ARRAY_SIZE(xsdirxss_dv_timings); i++) {
2110                if (state->format.width == xsdirxss_dv_timings[i].width &&
2111                    state->format.height == xsdirxss_dv_timings[i].height &&
2112                    state->frame_interval.denominator ==
2113                    (xsdirxss_dv_timings[i].fps * 1000)) {
2114                        *timings = xsdirxss_dv_timings[i].format;
2115                        return 0;
2116                }
2117        }
2118
2119        return -ERANGE;
2120}
2121
2122/**
2123 * xsdirxss_open - Called on v4l2_open()
2124 * @sd: Pointer to V4L2 sub device structure
2125 * @fh: Pointer to V4L2 File handle
2126 *
2127 * This function is called on v4l2_open(). It sets the default format for pad.
2128 *
2129 * Return: 0 on success
2130 */
2131static int xsdirxss_open(struct v4l2_subdev *sd,
2132                         struct v4l2_subdev_fh *fh)
2133{
2134        struct v4l2_mbus_framefmt *format;
2135        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
2136
2137        format = v4l2_subdev_get_try_format(sd, fh->pad, 0);
2138        *format = xsdirxss->default_format;
2139
2140        return 0;
2141}
2142
2143/**
2144 * xsdirxss_close - Called on v4l2_close()
2145 * @sd: Pointer to V4L2 sub device structure
2146 * @fh: Pointer to V4L2 File handle
2147 *
2148 * This function is called on v4l2_close().
2149 *
2150 * Return: 0 on success
2151 */
2152static int xsdirxss_close(struct v4l2_subdev *sd,
2153                          struct v4l2_subdev_fh *fh)
2154{
2155        return 0;
2156}
2157
2158/* -----------------------------------------------------------------------------
2159 * Media Operations
2160 */
2161
2162static const struct media_entity_operations xsdirxss_media_ops = {
2163        .link_validate = v4l2_subdev_link_validate
2164};
2165
2166static const struct v4l2_ctrl_ops xsdirxss_ctrl_ops = {
2167        .g_volatile_ctrl = xsdirxss_g_volatile_ctrl,
2168        .s_ctrl = xsdirxss_s_ctrl
2169};
2170
2171static const struct v4l2_ctrl_config xsdirxss_edh_ctrls[] = {
2172        {
2173                .ops    = &xsdirxss_ctrl_ops,
2174                .id     = V4L2_CID_XILINX_SDIRX_EDH_ERRCNT_ENABLE,
2175                .name   = "SDI Rx : EDH Error Count Enable",
2176                .type   = V4L2_CTRL_TYPE_BITMASK,
2177                .min    = 0,
2178                .max    = XSDIRX_EDH_ALLERR_MASK,
2179                .def    = 0,
2180        }, {
2181                .ops    = &xsdirxss_ctrl_ops,
2182                .id     = V4L2_CID_XILINX_SDIRX_EDH_ERRCNT,
2183                .name   = "SDI Rx : EDH Error Count",
2184                .type   = V4L2_CTRL_TYPE_INTEGER,
2185                .min    = 0,
2186                .max    = 0xFFFF,
2187                .step   = 1,
2188                .def    = 0,
2189                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
2190        }, {
2191                .ops    = &xsdirxss_ctrl_ops,
2192                .id     = V4L2_CID_XILINX_SDIRX_EDH_STATUS,
2193                .name   = "SDI Rx : EDH Status",
2194                .type   = V4L2_CTRL_TYPE_INTEGER,
2195                .min    = 0,
2196                .max    = 0xFFFFFFFF,
2197                .step   = 1,
2198                .def    = 0,
2199                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
2200        }
2201};
2202
2203static const struct v4l2_ctrl_config xsdirxss_ctrls[] = {
2204        {
2205                .ops    = &xsdirxss_ctrl_ops,
2206                .id     = V4L2_CID_XILINX_SDIRX_FRAMER,
2207                .name   = "SDI Rx : Enable Framer",
2208                .type   = V4L2_CTRL_TYPE_BOOLEAN,
2209                .min    = false,
2210                .max    = true,
2211                .step   = 1,
2212                .def    = true,
2213        }, {
2214                .ops    = &xsdirxss_ctrl_ops,
2215                .id     = V4L2_CID_XILINX_SDIRX_VIDLOCK_WINDOW,
2216                .name   = "SDI Rx : Video Lock Window",
2217                .type   = V4L2_CTRL_TYPE_INTEGER,
2218                .min    = 0,
2219                .max    = 0xFFFFFFFF,
2220                .step   = 1,
2221                .def    = XSDIRX_DEFAULT_VIDEO_LOCK_WINDOW,
2222        }, {
2223                .ops    = &xsdirxss_ctrl_ops,
2224                .id     = V4L2_CID_XILINX_SDIRX_SEARCH_MODES,
2225                .name   = "SDI Rx : Modes search Mask",
2226                .type   = V4L2_CTRL_TYPE_BITMASK,
2227                .min    = 0,
2228                .max    = XSDIRX_DETECT_ALL_MODES,
2229                .def    = XSDIRX_DETECT_ALL_MODES,
2230        }, {
2231                .ops    = &xsdirxss_ctrl_ops,
2232                .id     = V4L2_CID_XILINX_SDIRX_MODE_DETECT,
2233                .name   = "SDI Rx : Mode Detect Status",
2234                .type   = V4L2_CTRL_TYPE_INTEGER,
2235                .min    = XSDIRX_MODE_SD_OFFSET,
2236                .max    = XSDIRX_MODE_12GF_OFFSET,
2237                .step   = 1,
2238                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
2239        }, {
2240                .ops    = &xsdirxss_ctrl_ops,
2241                .id     = V4L2_CID_XILINX_SDIRX_CRC,
2242                .name   = "SDI Rx : CRC Error status",
2243                .type   = V4L2_CTRL_TYPE_INTEGER,
2244                .min    = 0,
2245                .max    = 0xFFFFFFFF,
2246                .step   = 1,
2247                .def    = 0,
2248                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
2249        }, {
2250                .ops    = &xsdirxss_ctrl_ops,
2251                .id     = V4L2_CID_XILINX_SDIRX_TS_IS_INTERLACED,
2252                .name   = "SDI Rx : TS is Interlaced",
2253                .type   = V4L2_CTRL_TYPE_BOOLEAN,
2254                .min    = false,
2255                .max    = true,
2256                .def    = false,
2257                .step   = 1,
2258                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
2259        }, {
2260                .ops    = &xsdirxss_ctrl_ops,
2261                .id     = V4L2_CID_XILINX_SDIRX_ACTIVE_STREAMS,
2262                .name   = "SDI Rx : Active Streams",
2263                .type   = V4L2_CTRL_TYPE_INTEGER,
2264                .min    = 1,
2265                .max    = 16,
2266                .def    = 1,
2267                .step   = 1,
2268                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
2269        }, {
2270                .ops    = &xsdirxss_ctrl_ops,
2271                .id     = V4L2_CID_XILINX_SDIRX_IS_3GB,
2272                .name   = "SDI Rx : Is 3GB",
2273                .type   = V4L2_CTRL_TYPE_BOOLEAN,
2274                .min    = false,
2275                .max    = true,
2276                .def    = false,
2277                .step   = 1,
2278                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
2279        }, {
2280                .ops    = &xsdirxss_ctrl_ops,
2281                .id     = V4L2_CID_METADATA_HDR,
2282                .name   = "HDR Controls",
2283                .type   = V4L2_CTRL_TYPE_HDR,
2284                .min    = 0x8000000000000000,
2285                .max    = 0x7FFFFFFFFFFFFFFF,
2286                .step   = 1,
2287                .def    = 0,
2288                .elem_size = sizeof(struct v4l2_metadata_hdr),
2289                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_HAS_PAYLOAD |
2290                        V4L2_CTRL_FLAG_READ_ONLY,
2291        },
2292};
2293
2294static const struct v4l2_subdev_core_ops xsdirxss_core_ops = {
2295        .log_status = xsdirxss_log_status,
2296        .subscribe_event = xsdirxss_subscribe_event,
2297        .unsubscribe_event = xsdirxss_unsubscribe_event
2298};
2299
2300static const struct v4l2_subdev_video_ops xsdirxss_video_ops = {
2301        .g_frame_interval = xsdirxss_g_frame_interval,
2302        .s_stream = xsdirxss_s_stream,
2303        .g_input_status = xsdirxss_g_input_status,
2304        .query_dv_timings = xsdirxss_query_dv_timings,
2305};
2306
2307static const struct v4l2_subdev_pad_ops xsdirxss_pad_ops = {
2308        .get_fmt = xsdirxss_get_format,
2309        .set_fmt = xsdirxss_set_format,
2310        .enum_mbus_code = xsdirxss_enum_mbus_code,
2311        .enum_dv_timings = xsdirxss_enum_dv_timings,
2312};
2313
2314static const struct v4l2_subdev_ops xsdirxss_ops = {
2315        .core = &xsdirxss_core_ops,
2316        .video = &xsdirxss_video_ops,
2317        .pad = &xsdirxss_pad_ops
2318};
2319
2320static const struct v4l2_subdev_internal_ops xsdirxss_internal_ops = {
2321        .open = xsdirxss_open,
2322        .close = xsdirxss_close
2323};
2324
2325/* -----------------------------------------------------------------------------
2326 * Platform Device Driver
2327 */
2328
2329static int xsdirxss_parse_of(struct xsdirxss_state *xsdirxss)
2330{
2331        struct device_node *node = xsdirxss->core.dev->of_node;
2332        struct device_node *ports = NULL;
2333        struct device_node *port = NULL;
2334        unsigned int nports = 0;
2335        struct xsdirxss_core *core = &xsdirxss->core;
2336        int ret;
2337        const char *sdi_std;
2338
2339        core->include_edh = of_property_read_bool(node, "xlnx,include-edh");
2340        dev_dbg(core->dev, "EDH property = %s\n",
2341                core->include_edh ? "Present" : "Absent");
2342
2343        ret = of_property_read_string(node, "xlnx,line-rate", &sdi_std);
2344        if (ret < 0) {
2345                dev_err(core->dev, "xlnx,line-rate property not found\n");
2346                return ret;
2347        }
2348
2349        if (!strncmp(sdi_std, "12G_SDI_8DS", XSDIRX_MAX_STR_LENGTH)) {
2350                core->mode = XSDIRXSS_SDI_STD_12G_8DS;
2351        } else if (!strncmp(sdi_std, "6G_SDI", XSDIRX_MAX_STR_LENGTH)) {
2352                core->mode = XSDIRXSS_SDI_STD_6G;
2353        } else if (!strncmp(sdi_std, "3G_SDI", XSDIRX_MAX_STR_LENGTH)) {
2354                core->mode = XSDIRXSS_SDI_STD_3G;
2355        } else {
2356                dev_err(core->dev, "Invalid Line Rate\n");
2357                return -EINVAL;
2358        }
2359        dev_dbg(core->dev, "SDI Rx Line Rate = %s, mode = %d\n", sdi_std,
2360                core->mode);
2361
2362        ret = of_property_read_u32(node, "xlnx,bpp", &core->bpc);
2363        if (ret < 0) {
2364                if (ret != -EINVAL) {
2365                        dev_err(core->dev, "failed to get xlnx,bpp\n");
2366                        return ret;
2367                }
2368
2369                /*
2370                 * For backward compatibility, set default bpc as 10
2371                 * in case xlnx,bpp is not present.
2372                 */
2373                core->bpc = 10;
2374        }
2375
2376        if (core->bpc != 10 && core->bpc != 12) {
2377                dev_err(core->dev, "bits per component=%u. Can be 10 or 12 only\n",
2378                        core->bpc);
2379                return -EINVAL;
2380        }
2381
2382        ports = of_get_child_by_name(node, "ports");
2383        if (!ports)
2384                ports = node;
2385
2386        for_each_child_of_node(ports, port) {
2387                const struct xvip_video_format *format;
2388                struct device_node *endpoint;
2389
2390                if (!port->name || of_node_cmp(port->name, "port"))
2391                        continue;
2392
2393                format = xvip_of_get_format(port);
2394                if (IS_ERR(format)) {
2395                        dev_err(core->dev, "invalid format in DT");
2396                        return PTR_ERR(format);
2397                }
2398
2399                dev_dbg(core->dev, "vf_code = %d bpc = %d bpp = %d\n",
2400                        format->vf_code, format->width, format->bpp);
2401
2402                if (format->vf_code != XVIP_VF_YUV_422 &&
2403                    format->vf_code != XVIP_VF_YUV_420 &&
2404                    format->vf_code != XVIP_VF_YUV_444 &&
2405                    format->vf_code != XVIP_VF_RBG &&
2406                    ((core->bpc == 10 && format->width != 10) ||
2407                     (core->bpc == 12 && format->width != 12))) {
2408                        dev_err(core->dev,
2409                                "Incorrect UG934 video format set.\n");
2410                        return -EINVAL;
2411                }
2412                xsdirxss->vip_format = format;
2413
2414                endpoint = of_get_next_child(port, NULL);
2415                if (!endpoint) {
2416                        dev_err(core->dev, "No port at\n");
2417                        return -EINVAL;
2418                }
2419
2420                /* Count the number of ports. */
2421                nports++;
2422        }
2423
2424        if (nports != 1) {
2425                dev_err(core->dev, "invalid number of ports %u\n", nports);
2426                return -EINVAL;
2427        }
2428
2429        /* Register interrupt handler */
2430        core->irq = irq_of_parse_and_map(node, 0);
2431        ret = devm_request_threaded_irq(core->dev, core->irq, NULL,
2432                                        xsdirxss_irq_handler, IRQF_ONESHOT,
2433                                        "xilinx-sdirxss", xsdirxss);
2434        if (ret) {
2435                dev_err(core->dev, "Err = %d Interrupt handler reg failed!\n",
2436                        ret);
2437                return ret;
2438        }
2439
2440        return 0;
2441}
2442
2443static int xsdirxss_probe(struct platform_device *pdev)
2444{
2445        struct v4l2_subdev *subdev;
2446        struct xsdirxss_state *xsdirxss;
2447        struct xsdirxss_core *core;
2448        struct resource *res;
2449        int ret;
2450        unsigned int num_ctrls, num_edh_ctrls = 0, i;
2451
2452        xsdirxss = devm_kzalloc(&pdev->dev, sizeof(*xsdirxss), GFP_KERNEL);
2453        if (!xsdirxss)
2454                return -ENOMEM;
2455
2456        xsdirxss->core.dev = &pdev->dev;
2457        core = &xsdirxss->core;
2458
2459        core->rst_gt_gpio = devm_gpiod_get_optional(&pdev->dev, "reset_gt",
2460                                                    GPIOD_OUT_HIGH);
2461        if (IS_ERR(core->rst_gt_gpio)) {
2462                ret = PTR_ERR(core->rst_gt_gpio);
2463                if (ret != -EPROBE_DEFER)
2464                        dev_err(&pdev->dev, "Reset GT GPIO not setup in DT\n");
2465                return ret;
2466        }
2467
2468        core->rst_picxo_gpio = devm_gpiod_get_optional(&pdev->dev,
2469                                                       "picxo_reset",
2470                                                       GPIOD_OUT_LOW);
2471        if (IS_ERR(core->rst_picxo_gpio)) {
2472                ret = PTR_ERR(core->rst_picxo_gpio);
2473                if (ret != -EPROBE_DEFER)
2474                        dev_err(&pdev->dev, "PICXO Reset GPIO not setup in DT\n");
2475                return ret;
2476        }
2477
2478        core->num_clks = ARRAY_SIZE(xsdirxss_clks);
2479        core->clks = devm_kcalloc(&pdev->dev, core->num_clks,
2480                                  sizeof(*core->clks), GFP_KERNEL);
2481        if (!core->clks)
2482                return -ENOMEM;
2483
2484        for (i = 0; i < core->num_clks; i++)
2485                core->clks[i].id = xsdirxss_clks[i];
2486
2487        ret = devm_clk_bulk_get(&pdev->dev, core->num_clks, core->clks);
2488        if (ret)
2489                return ret;
2490
2491        ret = clk_bulk_prepare_enable(core->num_clks, core->clks);
2492        if (ret)
2493                return ret;
2494
2495        ret = xsdirxss_parse_of(xsdirxss);
2496        if (ret < 0)
2497                goto clk_err;
2498
2499        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2500        xsdirxss->core.iomem = devm_ioremap_resource(xsdirxss->core.dev, res);
2501        if (IS_ERR(xsdirxss->core.iomem)) {
2502                ret = PTR_ERR(xsdirxss->core.iomem);
2503                goto clk_err;
2504        }
2505
2506        /* Reset the core */
2507        xsdirx_streamflow_control(core, false);
2508        xsdirx_core_disable(core);
2509        xsdirx_clearintr(core, XSDIRX_INTR_ALL_MASK);
2510        xsdirx_disableintr(core, XSDIRX_INTR_ALL_MASK);
2511        xsdirx_enableintr(core, XSDIRX_INTR_ALL_MASK);
2512        xsdirx_globalintr(core, true);
2513        xsdirxss_write(core, XSDIRX_CRC_ERRCNT_REG, 0xFFFF);
2514
2515        /* Initialize V4L2 subdevice and media entity */
2516        xsdirxss->pad.flags = MEDIA_PAD_FL_SOURCE;
2517
2518        /* Initialize the default format */
2519        xsdirxss->default_format.code = xsdirxss->vip_format->code;
2520        xsdirxss->default_format.field = V4L2_FIELD_NONE;
2521        xsdirxss->default_format.colorspace = V4L2_COLORSPACE_DEFAULT;
2522        xsdirxss->default_format.width = XSDIRX_DEFAULT_WIDTH;
2523        xsdirxss->default_format.height = XSDIRX_DEFAULT_HEIGHT;
2524
2525        xsdirxss->format = xsdirxss->default_format;
2526
2527        /* Initialize V4L2 subdevice and media entity */
2528        subdev = &xsdirxss->subdev;
2529        v4l2_subdev_init(subdev, &xsdirxss_ops);
2530
2531        subdev->dev = &pdev->dev;
2532        subdev->internal_ops = &xsdirxss_internal_ops;
2533        strscpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
2534
2535        subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
2536
2537        subdev->entity.ops = &xsdirxss_media_ops;
2538
2539        v4l2_set_subdevdata(subdev, xsdirxss);
2540
2541        ret = media_entity_pads_init(&subdev->entity, 1, &xsdirxss->pad);
2542        if (ret < 0)
2543                goto error;
2544
2545        /* Initialise and register the controls */
2546        num_ctrls = ARRAY_SIZE(xsdirxss_ctrls);
2547
2548        if (xsdirxss->core.include_edh)
2549                num_edh_ctrls = ARRAY_SIZE(xsdirxss_edh_ctrls);
2550
2551        v4l2_ctrl_handler_init(&xsdirxss->ctrl_handler,
2552                               (num_ctrls + num_edh_ctrls));
2553
2554        for (i = 0; i < num_ctrls; i++) {
2555                struct v4l2_ctrl *ctrl;
2556
2557                dev_dbg(xsdirxss->core.dev, "%d %s ctrl = 0x%x\n",
2558                        i, xsdirxss_ctrls[i].name, xsdirxss_ctrls[i].id);
2559
2560                ctrl = v4l2_ctrl_new_custom(&xsdirxss->ctrl_handler,
2561                                            &xsdirxss_ctrls[i], NULL);
2562                if (!ctrl) {
2563                        dev_dbg(xsdirxss->core.dev, "Failed to add %s ctrl\n",
2564                                xsdirxss_ctrls[i].name);
2565                        goto error;
2566                }
2567        }
2568
2569        if (xsdirxss->core.include_edh) {
2570                for (i = 0; i < num_edh_ctrls; i++) {
2571                        struct v4l2_ctrl *ctrl;
2572
2573                        dev_dbg(xsdirxss->core.dev, "%d %s ctrl = 0x%x\n",
2574                                i, xsdirxss_edh_ctrls[i].name,
2575                                xsdirxss_edh_ctrls[i].id);
2576
2577                        ctrl = v4l2_ctrl_new_custom(&xsdirxss->ctrl_handler,
2578                                                    &xsdirxss_edh_ctrls[i],
2579                                                    NULL);
2580                        if (!ctrl) {
2581                                dev_dbg(xsdirxss->core.dev, "Failed to add %s ctrl\n",
2582                                        xsdirxss_edh_ctrls[i].name);
2583                                goto error;
2584                        }
2585                }
2586        }
2587
2588        if (xsdirxss->ctrl_handler.error) {
2589                dev_err(&pdev->dev, "failed to add controls\n");
2590                ret = xsdirxss->ctrl_handler.error;
2591                goto error;
2592        }
2593
2594        subdev->ctrl_handler = &xsdirxss->ctrl_handler;
2595
2596        ret = v4l2_ctrl_handler_setup(&xsdirxss->ctrl_handler);
2597        if (ret < 0) {
2598                dev_err(&pdev->dev, "failed to set controls\n");
2599                goto error;
2600        }
2601
2602        platform_set_drvdata(pdev, xsdirxss);
2603
2604        ret = v4l2_async_register_subdev(subdev);
2605        if (ret < 0) {
2606                dev_err(&pdev->dev, "failed to register subdev\n");
2607                goto error;
2608        }
2609
2610        xsdirxss->streaming = false;
2611
2612        xsdirx_core_enable(core);
2613
2614        dev_info(xsdirxss->core.dev, "Xilinx SDI Rx Subsystem device found!\n");
2615
2616        return 0;
2617error:
2618        v4l2_ctrl_handler_free(&xsdirxss->ctrl_handler);
2619        media_entity_cleanup(&subdev->entity);
2620        xsdirx_globalintr(core, false);
2621        xsdirx_disableintr(core, XSDIRX_INTR_ALL_MASK);
2622clk_err:
2623        clk_bulk_disable_unprepare(core->num_clks, core->clks);
2624        return ret;
2625}
2626
2627static int xsdirxss_remove(struct platform_device *pdev)
2628{
2629        struct xsdirxss_state *xsdirxss = platform_get_drvdata(pdev);
2630        struct xsdirxss_core *core = &xsdirxss->core;
2631        struct v4l2_subdev *subdev = &xsdirxss->subdev;
2632
2633        v4l2_async_unregister_subdev(subdev);
2634        v4l2_ctrl_handler_free(&xsdirxss->ctrl_handler);
2635        media_entity_cleanup(&subdev->entity);
2636
2637        xsdirx_globalintr(core, false);
2638        xsdirx_disableintr(core, XSDIRX_INTR_ALL_MASK);
2639        xsdirx_core_disable(core);
2640        xsdirx_streamflow_control(core, false);
2641
2642        clk_bulk_disable_unprepare(core->num_clks, core->clks);
2643
2644        return 0;
2645}
2646
2647static const struct of_device_id xsdirxss_of_id_table[] = {
2648        { .compatible = "xlnx,v-smpte-uhdsdi-rx-ss" },
2649        { }
2650};
2651MODULE_DEVICE_TABLE(of, xsdirxss_of_id_table);
2652
2653static struct platform_driver xsdirxss_driver = {
2654        .driver = {
2655                .name           = "xilinx-sdirxss",
2656                .of_match_table = xsdirxss_of_id_table,
2657        },
2658        .probe                  = xsdirxss_probe,
2659        .remove                 = xsdirxss_remove,
2660};
2661
2662module_platform_driver(xsdirxss_driver);
2663
2664MODULE_AUTHOR("Vishal Sagar <vsagar@xilinx.com>");
2665MODULE_DESCRIPTION("Xilinx SDI Rx Subsystem Driver");
2666MODULE_LICENSE("GPL v2");
2667