linux/drivers/media/platform/xilinx/xilinx-sdirxss.c
<<
>>
Prefs
   1/*
   2 * Xilinx SDI Rx Subsystem
   3 *
   4 * Copyright (C) 2017 Xilinx, Inc.
   5 *
   6 * Contacts: Vishal Sagar <vsagar@xilinx.com>
   7 *
   8 * This software is licensed under the terms of the GNU General Public
   9 * License version 2, as published by the Free Software Foundation, and
  10 * may be copied, distributed, and modified under those terms.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 */
  17
  18#include <dt-bindings/media/xilinx-vip.h>
  19#include <linux/bitops.h>
  20#include <linux/compiler.h>
  21#include <linux/clk.h>
  22#include <linux/delay.h>
  23#include <linux/device.h>
  24#include <linux/interrupt.h>
  25#include <linux/io.h>
  26#include <linux/kernel.h>
  27#include <linux/module.h>
  28#include <linux/of.h>
  29#include <linux/of_irq.h>
  30#include <linux/platform_device.h>
  31#include <linux/pm.h>
  32#include <linux/slab.h>
  33#include <linux/spinlock.h>
  34#include <linux/spinlock_types.h>
  35#include <linux/types.h>
  36#include <linux/v4l2-subdev.h>
  37#include <linux/xilinx-sdirxss.h>
  38#include <linux/xilinx-v4l2-controls.h>
  39#include <media/media-entity.h>
  40#include <media/v4l2-common.h>
  41#include <media/v4l2-ctrls.h>
  42#include <media/v4l2-event.h>
  43#include <media/v4l2-fwnode.h>
  44#include <media/v4l2-subdev.h>
  45#include "xilinx-vip.h"
  46
  47/*
  48 * SDI Rx register map, bitmask and offsets
  49 */
  50#define XSDIRX_RST_CTRL_REG             0x00
  51#define XSDIRX_MDL_CTRL_REG             0x04
  52#define XSDIRX_GLBL_IER_REG             0x0C
  53#define XSDIRX_ISR_REG                  0x10
  54#define XSDIRX_IER_REG                  0x14
  55#define XSDIRX_ST352_VALID_REG          0x18
  56#define XSDIRX_ST352_DS1_REG            0x1C
  57#define XSDIRX_ST352_DS3_REG            0x20
  58#define XSDIRX_ST352_DS5_REG            0x24
  59#define XSDIRX_ST352_DS7_REG            0x28
  60#define XSDIRX_ST352_DS9_REG            0x2C
  61#define XSDIRX_ST352_DS11_REG           0x30
  62#define XSDIRX_ST352_DS13_REG           0x34
  63#define XSDIRX_ST352_DS15_REG           0x38
  64#define XSDIRX_VERSION_REG              0x3C
  65#define XSDIRX_SS_CONFIG_REG            0x40
  66#define XSDIRX_MODE_DET_STAT_REG        0x44
  67#define XSDIRX_TS_DET_STAT_REG          0x48
  68#define XSDIRX_EDH_STAT_REG             0x4C
  69#define XSDIRX_EDH_ERRCNT_EN_REG        0x50
  70#define XSDIRX_EDH_ERRCNT_REG           0x54
  71#define XSDIRX_CRC_ERRCNT_REG           0x58
  72#define XSDIRX_VID_LOCK_WINDOW_REG      0x5C
  73#define XSDIRX_SB_RX_STS_REG            0x60
  74
  75#define XSDIRX_RST_CTRL_SS_EN_MASK                      BIT(0)
  76#define XSDIRX_RST_CTRL_SRST_MASK                       BIT(1)
  77#define XSDIRX_RST_CTRL_RST_CRC_ERRCNT_MASK             BIT(2)
  78#define XSDIRX_RST_CTRL_RST_EDH_ERRCNT_MASK             BIT(3)
  79#define XSDIRX_RST_CTRL_SDIRX_BRIDGE_ENB_MASK           BIT(8)
  80#define XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK        BIT(9)
  81
  82#define XSDIRX_MDL_CTRL_FRM_EN_MASK             BIT(4)
  83#define XSDIRX_MDL_CTRL_MODE_DET_EN_MASK        BIT(5)
  84#define XSDIRX_MDL_CTRL_MODE_HD_EN_MASK         BIT(8)
  85#define XSDIRX_MDL_CTRL_MODE_SD_EN_MASK         BIT(9)
  86#define XSDIRX_MDL_CTRL_MODE_3G_EN_MASK         BIT(10)
  87#define XSDIRX_MDL_CTRL_MODE_6G_EN_MASK         BIT(11)
  88#define XSDIRX_MDL_CTRL_MODE_12GI_EN_MASK       BIT(12)
  89#define XSDIRX_MDL_CTRL_MODE_12GF_EN_MASK       BIT(13)
  90#define XSDIRX_MDL_CTRL_MODE_AUTO_DET_MASK      GENMASK(13, 8)
  91
  92#define XSDIRX_MDL_CTRL_FORCED_MODE_OFFSET      16
  93#define XSDIRX_MDL_CTRL_FORCED_MODE_MASK        GENMASK(18, 16)
  94
  95#define XSDIRX_GLBL_INTR_EN_MASK        BIT(0)
  96
  97#define XSDIRX_INTR_VIDLOCK_MASK        BIT(0)
  98#define XSDIRX_INTR_VIDUNLOCK_MASK      BIT(1)
  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_OVERFLOW_MASK |\
 105                                XSDIRX_INTR_UNDERFLOW_MASK)
 106
 107#define XSDIRX_ST352_VALID_DS1_MASK     BIT(0)
 108#define XSDIRX_ST352_VALID_DS3_MASK     BIT(1)
 109#define XSDIRX_ST352_VALID_DS5_MASK     BIT(2)
 110#define XSDIRX_ST352_VALID_DS7_MASK     BIT(3)
 111#define XSDIRX_ST352_VALID_DS9_MASK     BIT(4)
 112#define XSDIRX_ST352_VALID_DS11_MASK    BIT(5)
 113#define XSDIRX_ST352_VALID_DS13_MASK    BIT(6)
 114#define XSDIRX_ST352_VALID_DS15_MASK    BIT(7)
 115
 116#define XSDIRX_MODE_DET_STAT_RX_MODE_MASK       GENMASK(2, 0)
 117#define XSDIRX_MODE_DET_STAT_MODE_LOCK_MASK     BIT(3)
 118#define XSDIRX_MODE_DET_STAT_ACT_STREAM_MASK    GENMASK(6, 4)
 119#define XSDIRX_MODE_DET_STAT_ACT_STREAM_OFFSET  4
 120#define XSDIRX_MODE_DET_STAT_LVLB_3G_MASK       BIT(7)
 121
 122#define XSDIRX_ACTIVE_STREAMS_1         0x0
 123#define XSDIRX_ACTIVE_STREAMS_2         0x1
 124#define XSDIRX_ACTIVE_STREAMS_4         0x2
 125#define XSDIRX_ACTIVE_STREAMS_8         0x3
 126#define XSDIRX_ACTIVE_STREAMS_16        0x4
 127
 128#define XSDIRX_TS_DET_STAT_LOCKED_MASK          BIT(0)
 129#define XSDIRX_TS_DET_STAT_SCAN_MASK            BIT(1)
 130#define XSDIRX_TS_DET_STAT_SCAN_OFFSET          (1)
 131#define XSDIRX_TS_DET_STAT_FAMILY_MASK          GENMASK(7, 4)
 132#define XSDIRX_TS_DET_STAT_FAMILY_OFFSET        (4)
 133#define XSDIRX_TS_DET_STAT_RATE_MASK            GENMASK(11, 8)
 134#define XSDIRX_TS_DET_STAT_RATE_OFFSET          (8)
 135
 136#define XSDIRX_TS_DET_STAT_RATE_NONE            0x0
 137#define XSDIRX_TS_DET_STAT_RATE_23_98HZ         0x2
 138#define XSDIRX_TS_DET_STAT_RATE_24HZ            0x3
 139#define XSDIRX_TS_DET_STAT_RATE_47_95HZ         0x4
 140#define XSDIRX_TS_DET_STAT_RATE_25HZ            0x5
 141#define XSDIRX_TS_DET_STAT_RATE_29_97HZ         0x6
 142#define XSDIRX_TS_DET_STAT_RATE_30HZ            0x7
 143#define XSDIRX_TS_DET_STAT_RATE_48HZ            0x8
 144#define XSDIRX_TS_DET_STAT_RATE_50HZ            0x9
 145#define XSDIRX_TS_DET_STAT_RATE_59_94HZ         0xA
 146#define XSDIRX_TS_DET_STAT_RATE_60HZ            0xB
 147
 148#define XSDIRX_EDH_STAT_EDH_AP_MASK     BIT(0)
 149#define XSDIRX_EDH_STAT_EDH_FF_MASK     BIT(1)
 150#define XSDIRX_EDH_STAT_EDH_ANC_MASK    BIT(2)
 151#define XSDIRX_EDH_STAT_AP_FLAG_MASK    GENMASK(8, 4)
 152#define XSDIRX_EDH_STAT_FF_FLAG_MASK    GENMASK(13, 9)
 153#define XSDIRX_EDH_STAT_ANC_FLAG_MASK   GENMASK(18, 14)
 154#define XSDIRX_EDH_STAT_PKT_FLAG_MASK   GENMASK(22, 19)
 155
 156#define XSDIRX_EDH_ERRCNT_COUNT_MASK    GENMASK(15, 0)
 157
 158#define XSDIRX_CRC_ERRCNT_COUNT_MASK    GENMASK(31, 16)
 159#define XSDIRX_CRC_ERRCNT_DS_CRC_MASK   GENMASK(15, 0)
 160
 161#define XSDIRX_VERSION_REV_MASK         GENMASK(7, 0)
 162#define XSDIRX_VERSION_PATCHID_MASK     GENMASK(11, 8)
 163#define XSDIRX_VERSION_VER_REV_MASK     GENMASK(15, 12)
 164#define XSDIRX_VERSION_VER_MIN_MASK     GENMASK(23, 16)
 165#define XSDIRX_VERSION_VER_MAJ_MASK     GENMASK(31, 24)
 166
 167#define XSDIRX_SS_CONFIG_EDH_INCLUDED_MASK              BIT(1)
 168
 169#define XSDIRX_STAT_SB_RX_TDATA_CHANGE_DONE_MASK        BIT(0)
 170#define XSDIRX_STAT_SB_RX_TDATA_CHANGE_FAIL_MASK        BIT(1)
 171#define XSDIRX_STAT_SB_RX_TDATA_GT_RESETDONE_MASK       BIT(2)
 172#define XSDIRX_STAT_SB_RX_TDATA_GT_BITRATE_MASK         BIT(3)
 173
 174/* Number of media pads */
 175#define XSDIRX_MEDIA_PADS       (1)
 176
 177#define XSDIRX_DEFAULT_WIDTH    (1920)
 178#define XSDIRX_DEFAULT_HEIGHT   (1080)
 179
 180#define XSDIRX_MAX_STR_LENGTH   16
 181
 182#define XSDIRXSS_SDI_STD_3G             0
 183#define XSDIRXSS_SDI_STD_6G             1
 184#define XSDIRXSS_SDI_STD_12G_8DS        2
 185
 186#define XSDIRX_DEFAULT_VIDEO_LOCK_WINDOW        0x3000
 187
 188#define XSDIRX_MODE_HD_MASK     0x0
 189#define XSDIRX_MODE_SD_MASK     0x1
 190#define XSDIRX_MODE_3G_MASK     0x2
 191#define XSDIRX_MODE_6G_MASK     0x4
 192#define XSDIRX_MODE_12GI_MASK   0x5
 193#define XSDIRX_MODE_12GF_MASK   0x6
 194
 195/*
 196 * Maximum number of events per file handle.
 197 */
 198#define XSDIRX_MAX_EVENTS       (128)
 199
 200/* ST352 related macros */
 201#define XST352_PAYLOAD_BYTE_MASK        0xFF
 202#define XST352_PAYLOAD_BYTE1_SHIFT      0
 203#define XST352_PAYLOAD_BYTE2_SHIFT      8
 204#define XST352_PAYLOAD_BYTE3_SHIFT      16
 205#define XST352_PAYLOAD_BYTE4_SHIFT      24
 206
 207#define XST352_BYTE1_ST292_1x720L_1_5G          0x84
 208#define XST352_BYTE1_ST292_1x1080L_1_5G         0x85
 209#define XST352_BYTE1_ST425_2008_750L_3GB        0x88
 210#define XST352_BYTE1_ST425_2008_1125L_3GA       0x89
 211#define XST352_BYTE1_ST372_DL_3GB               0x8A
 212#define XST352_BYTE1_ST372_2x720L_3GB           0x8B
 213#define XST352_BYTE1_ST372_2x1080L_3GB          0x8C
 214#define XST352_BYTE1_ST2081_10_2160L_6G         0xC0
 215#define XST352_BYTE1_ST2081_10_DL_2160L_6G      0xC2
 216#define XST352_BYTE1_ST2082_10_2160L_12G        0xCE
 217
 218#define XST352_BYTE2_TS_TYPE_MASK               BIT(15)
 219#define XST352_BYTE2_TS_TYPE_OFFSET             15
 220#define XST352_BYTE2_PIC_TYPE_MASK              BIT(14)
 221#define XST352_BYTE2_PIC_TYPE_OFFSET            14
 222#define XST352_BYTE2_TS_PIC_TYPE_INTERLACED     0
 223#define XST352_BYTE2_TS_PIC_TYPE_PROGRESSIVE    1
 224
 225#define XST352_BYTE2_FPS_MASK                   0xF
 226#define XST352_BYTE2_FPS_SHIFT                  8
 227#define XST352_BYTE2_FPS_24F                    0x2
 228#define XST352_BYTE2_FPS_24                     0x3
 229#define XST352_BYTE2_FPS_48F                    0x4
 230#define XST352_BYTE2_FPS_25                     0x5
 231#define XST352_BYTE2_FPS_30F                    0x6
 232#define XST352_BYTE2_FPS_30                     0x7
 233#define XST352_BYTE2_FPS_48                     0x8
 234#define XST352_BYTE2_FPS_50                     0x9
 235#define XST352_BYTE2_FPS_60F                    0xA
 236#define XST352_BYTE2_FPS_60                     0xB
 237/* Table 4 ST 2081-10:2015 */
 238#define XST352_BYTE2_FPS_96                     0xC
 239#define XST352_BYTE2_FPS_100                    0xD
 240#define XST352_BYTE2_FPS_120                    0xE
 241#define XST352_BYTE2_FPS_120F                   0xF
 242
 243#define XST352_BYTE3_ACT_LUMA_COUNT_MASK        BIT(22)
 244#define XST352_BYTE3_ACT_LUMA_COUNT_OFFSET      22
 245
 246#define XST352_BYTE3_COLOR_FORMAT_MASK          GENMASK(19, 16)
 247#define XST352_BYTE3_COLOR_FORMAT_OFFSET        16
 248#define XST352_BYTE3_COLOR_FORMAT_422           0x0
 249#define XST352_BYTE3_COLOR_FORMAT_420           0x3
 250
 251/**
 252 * enum sdi_family_enc - SDI Transport Video Format Detected with Active Pixels
 253 * @XSDIRX_SMPTE_ST_274: SMPTE ST 274 detected with AP 1920x1080
 254 * @XSDIRX_SMPTE_ST_296: SMPTE ST 296 detected with AP 1280x720
 255 * @XSDIRX_SMPTE_ST_2048_2: SMPTE ST 2048-2 detected with AP 2048x1080
 256 * @XSDIRX_SMPTE_ST_295: SMPTE ST 295 detected with AP 1920x1080
 257 * @XSDIRX_NTSC: NTSC encoding detected with AP 720x486
 258 * @XSDIRX_PAL: PAL encoding detected with AP 720x576
 259 * @XSDIRX_TS_UNKNOWN: Unknown SMPTE Transport family type
 260 */
 261enum sdi_family_enc {
 262        XSDIRX_SMPTE_ST_274     = 0,
 263        XSDIRX_SMPTE_ST_296     = 1,
 264        XSDIRX_SMPTE_ST_2048_2  = 2,
 265        XSDIRX_SMPTE_ST_295     = 3,
 266        XSDIRX_NTSC             = 8,
 267        XSDIRX_PAL              = 9,
 268        XSDIRX_TS_UNKNOWN       = 15
 269};
 270
 271/**
 272 * struct xsdirxss_core - Core configuration SDI Rx Subsystem device structure
 273 * @dev: Platform structure
 274 * @iomem: Base address of subsystem
 275 * @irq: requested irq number
 276 * @include_edh: EDH processor presence
 277 * @mode: 3G/6G/12G mode
 278 * @axi_clk: Axi lite interface clock
 279 * @sdirx_clk: SDI Rx GT clock
 280 * @vidout_clk: Video clock
 281 */
 282struct xsdirxss_core {
 283        struct device *dev;
 284        void __iomem *iomem;
 285        int irq;
 286        bool include_edh;
 287        int mode;
 288        struct clk *axi_clk;
 289        struct clk *sdirx_clk;
 290        struct clk *vidout_clk;
 291};
 292
 293/**
 294 * struct xsdirxss_state - SDI Rx Subsystem device structure
 295 * @core: Core structure for MIPI SDI Rx Subsystem
 296 * @subdev: The v4l2 subdev structure
 297 * @ctrl_handler: control handler
 298 * @event: Holds the video unlock event
 299 * @formats: Active V4L2 formats on each pad
 300 * @default_format: default V4L2 media bus format
 301 * @frame_interval: Captures the frame rate
 302 * @vip_format: format information corresponding to the active format
 303 * @pads: media pads
 304 * @streaming: Flag for storing streaming state
 305 * @vidlocked: Flag indicating SDI Rx has locked onto video stream
 306 * @ts_is_interlaced: Flag indicating Transport Stream is interlaced.
 307 *
 308 * This structure contains the device driver related parameters
 309 */
 310struct xsdirxss_state {
 311        struct xsdirxss_core core;
 312        struct v4l2_subdev subdev;
 313        struct v4l2_ctrl_handler ctrl_handler;
 314        struct v4l2_event event;
 315        struct v4l2_mbus_framefmt formats[XSDIRX_MEDIA_PADS];
 316        struct v4l2_mbus_framefmt default_format;
 317        struct v4l2_fract frame_interval;
 318        const struct xvip_video_format *vip_format;
 319        struct media_pad pads[XSDIRX_MEDIA_PADS];
 320        bool streaming;
 321        bool vidlocked;
 322        bool ts_is_interlaced;
 323};
 324
 325static inline struct xsdirxss_state *
 326to_xsdirxssstate(struct v4l2_subdev *subdev)
 327{
 328        return container_of(subdev, struct xsdirxss_state, subdev);
 329}
 330
 331/*
 332 * Register related operations
 333 */
 334static inline u32 xsdirxss_read(struct xsdirxss_core *xsdirxss, u32 addr)
 335{
 336        return ioread32(xsdirxss->iomem + addr);
 337}
 338
 339static inline void xsdirxss_write(struct xsdirxss_core *xsdirxss, u32 addr,
 340                                  u32 value)
 341{
 342        iowrite32(value, xsdirxss->iomem + addr);
 343}
 344
 345static inline void xsdirxss_clr(struct xsdirxss_core *xsdirxss, u32 addr,
 346                                u32 clr)
 347{
 348        xsdirxss_write(xsdirxss, addr, xsdirxss_read(xsdirxss, addr) & ~clr);
 349}
 350
 351static inline void xsdirxss_set(struct xsdirxss_core *xsdirxss, u32 addr,
 352                                u32 set)
 353{
 354        xsdirxss_write(xsdirxss, addr, xsdirxss_read(xsdirxss, addr) | set);
 355}
 356
 357static void xsdirx_core_disable(struct xsdirxss_core *core)
 358{
 359        xsdirxss_clr(core, XSDIRX_RST_CTRL_REG, XSDIRX_RST_CTRL_SS_EN_MASK);
 360}
 361
 362static void xsdirx_core_enable(struct xsdirxss_core *core)
 363{
 364        xsdirxss_set(core, XSDIRX_RST_CTRL_REG, XSDIRX_RST_CTRL_SS_EN_MASK);
 365}
 366
 367static int xsdirx_set_modedetect(struct xsdirxss_core *core, u16 mask)
 368{
 369        u32 i, val;
 370
 371        mask &= XSDIRX_DETECT_ALL_MODES;
 372        if (!mask) {
 373                dev_err(core->dev, "Invalid bit mask = 0x%08x\n", mask);
 374                return -EINVAL;
 375        }
 376
 377        dev_dbg(core->dev, "mask = 0x%x\n", mask);
 378
 379        val = xsdirxss_read(core, XSDIRX_MDL_CTRL_REG);
 380        val &= ~(XSDIRX_MDL_CTRL_MODE_DET_EN_MASK);
 381        val &= ~(XSDIRX_MDL_CTRL_MODE_AUTO_DET_MASK);
 382        val &= ~(XSDIRX_MDL_CTRL_FORCED_MODE_MASK);
 383
 384        if (hweight16(mask) > 1) {
 385                /* Multi mode detection as more than 1 bit set in mask */
 386                dev_dbg(core->dev, "Detect multiple modes\n");
 387                for (i = 0; i < XSDIRX_MODE_NUM_SUPPORTED; i++) {
 388                        switch (mask & (1 << i)) {
 389                        case BIT(XSDIRX_MODE_SD_OFFSET):
 390                                val |= XSDIRX_MDL_CTRL_MODE_SD_EN_MASK;
 391                                break;
 392                        case BIT(XSDIRX_MODE_HD_OFFSET):
 393                                val |= XSDIRX_MDL_CTRL_MODE_HD_EN_MASK;
 394                                break;
 395                        case BIT(XSDIRX_MODE_3G_OFFSET):
 396                                val |= XSDIRX_MDL_CTRL_MODE_3G_EN_MASK;
 397                                break;
 398                        case BIT(XSDIRX_MODE_6G_OFFSET):
 399                                val |= XSDIRX_MDL_CTRL_MODE_6G_EN_MASK;
 400                                break;
 401                        case BIT(XSDIRX_MODE_12GI_OFFSET):
 402                                val |= XSDIRX_MDL_CTRL_MODE_12GI_EN_MASK;
 403                                break;
 404                        case BIT(XSDIRX_MODE_12GF_OFFSET):
 405                                val |= XSDIRX_MDL_CTRL_MODE_12GF_EN_MASK;
 406                                break;
 407                        }
 408                }
 409                val |= XSDIRX_MDL_CTRL_MODE_DET_EN_MASK;
 410        } else {
 411                /* Fixed Mode */
 412                u32 forced_mode_mask = 0;
 413
 414                dev_dbg(core->dev, "Detect fixed mode\n");
 415
 416                /* Find offset of first bit set */
 417                switch (__ffs(mask)) {
 418                case XSDIRX_MODE_SD_OFFSET:
 419                        forced_mode_mask = XSDIRX_MODE_SD_MASK;
 420                        break;
 421                case XSDIRX_MODE_HD_OFFSET:
 422                        forced_mode_mask = XSDIRX_MODE_HD_MASK;
 423                        break;
 424                case XSDIRX_MODE_3G_OFFSET:
 425                        forced_mode_mask = XSDIRX_MODE_3G_MASK;
 426                        break;
 427                case XSDIRX_MODE_6G_OFFSET:
 428                        forced_mode_mask = XSDIRX_MODE_6G_MASK;
 429                        break;
 430                case XSDIRX_MODE_12GI_OFFSET:
 431                        forced_mode_mask = XSDIRX_MODE_12GI_MASK;
 432                        break;
 433                case XSDIRX_MODE_12GF_OFFSET:
 434                        forced_mode_mask = XSDIRX_MODE_12GF_MASK;
 435                        break;
 436                }
 437                dev_dbg(core->dev, "Forced Mode Mask : 0x%x\n",
 438                        forced_mode_mask);
 439                val |= forced_mode_mask << XSDIRX_MDL_CTRL_FORCED_MODE_OFFSET;
 440        }
 441
 442        dev_dbg(core->dev, "Modes to be detected : sdi ctrl reg = 0x%08x\n",
 443                val);
 444        xsdirxss_write(core, XSDIRX_MDL_CTRL_REG, val);
 445
 446        return 0;
 447}
 448
 449static void xsdirx_framer(struct xsdirxss_core *core, bool flag)
 450{
 451        if (flag)
 452                xsdirxss_set(core, XSDIRX_MDL_CTRL_REG,
 453                             XSDIRX_MDL_CTRL_FRM_EN_MASK);
 454        else
 455                xsdirxss_clr(core, XSDIRX_MDL_CTRL_REG,
 456                             XSDIRX_MDL_CTRL_FRM_EN_MASK);
 457}
 458
 459static void xsdirx_setedherrcnttrigger(struct xsdirxss_core *core, u32 enable)
 460{
 461        u32 val = xsdirxss_read(core, XSDIRX_EDH_ERRCNT_EN_REG);
 462
 463        val = enable & XSDIRX_EDH_ALLERR_MASK;
 464
 465        xsdirxss_write(core, XSDIRX_EDH_ERRCNT_EN_REG, val);
 466}
 467
 468static void xsdirx_setvidlockwindow(struct xsdirxss_core *core, u32 val)
 469{
 470        /*
 471         * The video lock window is the amount of time for which the
 472         * the mode and transport stream should be locked to get the
 473         * video lock interrupt.
 474         */
 475        xsdirxss_write(core, XSDIRX_VID_LOCK_WINDOW_REG, val);
 476}
 477
 478static void xsdirx_disableintr(struct xsdirxss_core *core, u32 mask)
 479{
 480        xsdirxss_clr(core, XSDIRX_IER_REG, mask);
 481}
 482
 483static void xsdirx_enableintr(struct xsdirxss_core *core, u32 mask)
 484{
 485        xsdirxss_set(core, XSDIRX_IER_REG, mask);
 486}
 487
 488static void xsdirx_globalintr(struct xsdirxss_core *core, bool flag)
 489{
 490        if (flag)
 491                xsdirxss_set(core, XSDIRX_GLBL_IER_REG,
 492                             XSDIRX_GLBL_INTR_EN_MASK);
 493        else
 494                xsdirxss_clr(core, XSDIRX_GLBL_IER_REG,
 495                             XSDIRX_GLBL_INTR_EN_MASK);
 496}
 497
 498static void xsdirx_clearintr(struct xsdirxss_core *core, u32 mask)
 499{
 500        xsdirxss_set(core, XSDIRX_ISR_REG, mask);
 501}
 502
 503static void xsdirx_vid_bridge_control(struct xsdirxss_core *core, bool enable)
 504{
 505        if (enable)
 506                xsdirxss_set(core, XSDIRX_RST_CTRL_REG,
 507                             XSDIRX_RST_CTRL_SDIRX_BRIDGE_ENB_MASK);
 508        else
 509                xsdirxss_clr(core, XSDIRX_RST_CTRL_REG,
 510                             XSDIRX_RST_CTRL_SDIRX_BRIDGE_ENB_MASK);
 511}
 512
 513static void xsdirx_axis4_bridge_control(struct xsdirxss_core *core, bool enable)
 514{
 515        if (enable)
 516                xsdirxss_set(core, XSDIRX_RST_CTRL_REG,
 517                             XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK);
 518        else
 519                xsdirxss_clr(core, XSDIRX_RST_CTRL_REG,
 520                             XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK);
 521}
 522
 523static void xsdirx_streamflow_control(struct xsdirxss_core *core, bool enable)
 524{
 525        /* The sdi to native bridge is followed by native to axis4 bridge */
 526        if (enable) {
 527                xsdirx_axis4_bridge_control(core, enable);
 528                xsdirx_vid_bridge_control(core, enable);
 529        } else {
 530                xsdirx_vid_bridge_control(core, enable);
 531                xsdirx_axis4_bridge_control(core, enable);
 532        }
 533}
 534
 535static void xsdirx_streamdowncb(struct xsdirxss_core *core)
 536{
 537        xsdirx_streamflow_control(core, false);
 538}
 539
 540static void xsdirxss_get_framerate(struct v4l2_fract *frame_interval,
 541                                   u32 framerate)
 542{
 543        switch (framerate) {
 544        case XSDIRX_TS_DET_STAT_RATE_23_98HZ:
 545                frame_interval->numerator = 1001;
 546                frame_interval->denominator = 24000;
 547                break;
 548        case XSDIRX_TS_DET_STAT_RATE_24HZ:
 549                frame_interval->numerator = 1000;
 550                frame_interval->denominator = 24000;
 551                break;
 552        case XSDIRX_TS_DET_STAT_RATE_25HZ:
 553                frame_interval->numerator = 1000;
 554                frame_interval->denominator = 25000;
 555                break;
 556        case XSDIRX_TS_DET_STAT_RATE_29_97HZ:
 557                frame_interval->numerator = 1001;
 558                frame_interval->denominator = 30000;
 559                break;
 560        case XSDIRX_TS_DET_STAT_RATE_30HZ:
 561                frame_interval->numerator = 1000;
 562                frame_interval->denominator = 30000;
 563                break;
 564        case XSDIRX_TS_DET_STAT_RATE_47_95HZ:
 565                frame_interval->numerator = 1001;
 566                frame_interval->denominator = 48000;
 567                break;
 568        case XSDIRX_TS_DET_STAT_RATE_48HZ:
 569                frame_interval->numerator = 1000;
 570                frame_interval->denominator = 48000;
 571                break;
 572        case XSDIRX_TS_DET_STAT_RATE_50HZ:
 573                frame_interval->numerator = 1000;
 574                frame_interval->denominator = 50000;
 575                break;
 576        case XSDIRX_TS_DET_STAT_RATE_59_94HZ:
 577                frame_interval->numerator = 1001;
 578                frame_interval->denominator = 60000;
 579                break;
 580        case XSDIRX_TS_DET_STAT_RATE_60HZ:
 581                frame_interval->numerator = 1000;
 582                frame_interval->denominator = 60000;
 583                break;
 584        default:
 585                frame_interval->numerator = 1;
 586                frame_interval->denominator = 1;
 587        }
 588}
 589
 590/**
 591 * xsdirx_get_stream_properties - Get SDI Rx stream properties
 592 * @state: pointer to driver state
 593 *
 594 * This function decodes the stream's ST352 payload (if available) to get
 595 * stream properties like width, height, picture type (interlaced/progressive),
 596 * etc.
 597 *
 598 * Return: 0 for success else errors
 599 */
 600static int xsdirx_get_stream_properties(struct xsdirxss_state *state)
 601{
 602        struct xsdirxss_core *core = &state->core;
 603        u32 mode, payload = 0, val, family, valid, tscan;
 604        u8 byte1 = 0, active_luma = 0, pic_type = 0, framerate = 0;
 605        u8 sampling = XST352_BYTE3_COLOR_FORMAT_422;
 606        struct v4l2_mbus_framefmt *format = &state->formats[0];
 607
 608        mode = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
 609        mode &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
 610
 611        valid = xsdirxss_read(core, XSDIRX_ST352_VALID_REG);
 612
 613        if ((mode >= XSDIRX_MODE_3G_MASK) && !valid) {
 614                dev_err(core->dev, "No valid ST352 payload present even for 3G mode and above\n");
 615                return -EINVAL;
 616        }
 617
 618        val = xsdirxss_read(core, XSDIRX_TS_DET_STAT_REG);
 619        if (valid & XSDIRX_ST352_VALID_DS1_MASK) {
 620                payload = xsdirxss_read(core, XSDIRX_ST352_DS1_REG);
 621                byte1 = (payload >> XST352_PAYLOAD_BYTE1_SHIFT) &
 622                                XST352_PAYLOAD_BYTE_MASK;
 623                active_luma = (payload & XST352_BYTE3_ACT_LUMA_COUNT_MASK) >>
 624                                XST352_BYTE3_ACT_LUMA_COUNT_OFFSET;
 625                pic_type = (payload & XST352_BYTE2_PIC_TYPE_MASK) >>
 626                                XST352_BYTE2_PIC_TYPE_OFFSET;
 627                framerate = (payload >> XST352_BYTE2_FPS_SHIFT) &
 628                                XST352_BYTE2_FPS_MASK;
 629                tscan = (payload & XST352_BYTE2_TS_TYPE_MASK) >>
 630                                XST352_BYTE2_TS_TYPE_OFFSET;
 631                sampling = (payload & XST352_BYTE3_COLOR_FORMAT_MASK) >>
 632                           XST352_BYTE3_COLOR_FORMAT_OFFSET;
 633        } else {
 634                dev_dbg(core->dev, "No ST352 payload available : Mode = %d\n",
 635                        mode);
 636                framerate = (val & XSDIRX_TS_DET_STAT_RATE_MASK) >>
 637                                XSDIRX_TS_DET_STAT_RATE_OFFSET;
 638                tscan = (val & XSDIRX_TS_DET_STAT_SCAN_MASK) >>
 639                                XSDIRX_TS_DET_STAT_SCAN_OFFSET;
 640        }
 641
 642        family = (val & XSDIRX_TS_DET_STAT_FAMILY_MASK) >>
 643                  XSDIRX_TS_DET_STAT_FAMILY_OFFSET;
 644        state->ts_is_interlaced = tscan ? false : true;
 645
 646        dev_dbg(core->dev, "ts_is_interlaced = %d, family = %d\n",
 647                state->ts_is_interlaced, family);
 648
 649        switch (mode) {
 650        case XSDIRX_MODE_HD_MASK:
 651                if (!valid) {
 652                        /* No payload obtained */
 653                        dev_dbg(core->dev, "frame rate : %d, tscan = %d\n",
 654                                framerate, tscan);
 655                        /*
 656                         * NOTE : A progressive segmented frame pSF will be
 657                         * reported incorrectly as Interlaced as we rely on IP's
 658                         * transport scan locked bit.
 659                         */
 660                        dev_warn(core->dev, "pSF will be incorrectly reported as Interlaced\n");
 661
 662                        switch (framerate) {
 663                        case XSDIRX_TS_DET_STAT_RATE_23_98HZ:
 664                        case XSDIRX_TS_DET_STAT_RATE_24HZ:
 665                        case XSDIRX_TS_DET_STAT_RATE_25HZ:
 666                        case XSDIRX_TS_DET_STAT_RATE_29_97HZ:
 667                        case XSDIRX_TS_DET_STAT_RATE_30HZ:
 668                                if (family == XSDIRX_SMPTE_ST_296) {
 669                                        format->width = 1280;
 670                                        format->height = 720;
 671                                        format->field = V4L2_FIELD_NONE;
 672                                } else if (family == XSDIRX_SMPTE_ST_2048_2) {
 673                                        format->width = 2048;
 674                                        format->height = 1080;
 675                                        if (tscan)
 676                                                format->field = V4L2_FIELD_NONE;
 677                                        else
 678                                                format->field =
 679                                                        V4L2_FIELD_ALTERNATE;
 680                                } else {
 681                                        format->width = 1920;
 682                                        format->height = 1080;
 683                                        if (tscan)
 684                                                format->field = V4L2_FIELD_NONE;
 685                                        else
 686                                                format->field =
 687                                                        V4L2_FIELD_ALTERNATE;
 688                                }
 689                                break;
 690                        case XSDIRX_TS_DET_STAT_RATE_50HZ:
 691                        case XSDIRX_TS_DET_STAT_RATE_59_94HZ:
 692                        case XSDIRX_TS_DET_STAT_RATE_60HZ:
 693                                if (family == XSDIRX_SMPTE_ST_274) {
 694                                        format->width = 1920;
 695                                        format->height = 1080;
 696                                } else {
 697                                        format->width = 1280;
 698                                        format->height = 720;
 699                                }
 700                                format->field = V4L2_FIELD_NONE;
 701                                break;
 702                        default:
 703                                format->width = 1920;
 704                                format->height = 1080;
 705                                format->field = V4L2_FIELD_NONE;
 706                        }
 707                } else {
 708                        dev_dbg(core->dev, "Got the payload\n");
 709                        switch (byte1) {
 710                        case XST352_BYTE1_ST292_1x720L_1_5G:
 711                                /* SMPTE ST 292-1 for 720 line payloads */
 712                                format->width = 1280;
 713                                format->height = 720;
 714                                break;
 715                        case XST352_BYTE1_ST292_1x1080L_1_5G:
 716                                /* SMPTE ST 292-1 for 1080 line payloads */
 717                                format->height = 1080;
 718                                if (active_luma)
 719                                        format->width = 2048;
 720                                else
 721                                        format->width = 1920;
 722                                break;
 723                        default:
 724                                dev_dbg(core->dev, "Unknown HD Mode SMPTE standard\n");
 725                                return -EINVAL;
 726                        }
 727                }
 728                break;
 729        case XSDIRX_MODE_SD_MASK:
 730                format->field = V4L2_FIELD_ALTERNATE;
 731
 732                switch (family) {
 733                case XSDIRX_NTSC:
 734                        format->width = 720;
 735                        format->height = 486;
 736                        break;
 737                case XSDIRX_PAL:
 738                        format->width = 720;
 739                        format->height = 576;
 740                        break;
 741                default:
 742                        dev_dbg(core->dev, "Unknown SD Mode SMPTE standard\n");
 743                        return -EINVAL;
 744                }
 745                break;
 746        case XSDIRX_MODE_3G_MASK:
 747                switch (byte1) {
 748                case XST352_BYTE1_ST425_2008_750L_3GB:
 749                        /* Sec 4.1.6.1 SMPTE 425-2008 */
 750                case XST352_BYTE1_ST372_2x720L_3GB:
 751                        /* Table 13 SMPTE 425-2008 */
 752                        format->width = 1280;
 753                        format->height = 720;
 754                        break;
 755                case XST352_BYTE1_ST425_2008_1125L_3GA:
 756                        /* ST352 Table SMPTE 425-1 */
 757                case XST352_BYTE1_ST372_DL_3GB:
 758                        /* Table 13 SMPTE 425-2008 */
 759                case XST352_BYTE1_ST372_2x1080L_3GB:
 760                        /* Table 13 SMPTE 425-2008 */
 761                        format->height = 1080;
 762                        if (active_luma)
 763                                format->width = 2048;
 764                        else
 765                                format->width = 1920;
 766                        break;
 767                default:
 768                        dev_dbg(core->dev, "Unknown 3G Mode SMPTE standard\n");
 769                        return -EINVAL;
 770                }
 771                break;
 772        case XSDIRX_MODE_6G_MASK:
 773                switch (byte1) {
 774                case XST352_BYTE1_ST2081_10_DL_2160L_6G:
 775                        /* Dual link 6G */
 776                case XST352_BYTE1_ST2081_10_2160L_6G:
 777                        /* Table 3 SMPTE ST 2081-10 */
 778                        format->height = 2160;
 779                        if (active_luma)
 780                                format->width = 4096;
 781                        else
 782                                format->width = 3840;
 783                        break;
 784                default:
 785                        dev_dbg(core->dev, "Unknown 6G Mode SMPTE standard\n");
 786                        return -EINVAL;
 787                }
 788                break;
 789        case XSDIRX_MODE_12GI_MASK:
 790        case XSDIRX_MODE_12GF_MASK:
 791                switch (byte1) {
 792                case XST352_BYTE1_ST2082_10_2160L_12G:
 793                        /* Section 4.3.1 SMPTE ST 2082-10 */
 794                        format->height = 2160;
 795                        if (active_luma)
 796                                format->width = 4096;
 797                        else
 798                                format->width = 3840;
 799                        break;
 800                default:
 801                        dev_dbg(core->dev, "Unknown 12G Mode SMPTE standard\n");
 802                        return -EINVAL;
 803                }
 804                break;
 805        default:
 806                dev_err(core->dev, "Invalid Mode\n");
 807                return -EINVAL;
 808        }
 809
 810        if (valid) {
 811                if (pic_type)
 812                        format->field = V4L2_FIELD_NONE;
 813                else
 814                        format->field = V4L2_FIELD_ALTERNATE;
 815        }
 816
 817        if (format->field == V4L2_FIELD_ALTERNATE)
 818                format->height = format->height / 2;
 819
 820        switch (sampling) {
 821        case XST352_BYTE3_COLOR_FORMAT_420:
 822                format->code = MEDIA_BUS_FMT_VYYUYY8_1X24;
 823                break;
 824        case XST352_BYTE3_COLOR_FORMAT_422:
 825                format->code = MEDIA_BUS_FMT_UYVY8_1X16;
 826                break;
 827        default:
 828                dev_err(core->dev, "Unsupported color format : %d\n", sampling);
 829                return -EINVAL;
 830        }
 831
 832        xsdirxss_get_framerate(&state->frame_interval, framerate);
 833
 834        dev_dbg(core->dev, "Stream width = %d height = %d Field = %d payload = 0x%08x ts = 0x%08x\n",
 835                format->width, format->height, format->field, payload, val);
 836        dev_dbg(core->dev, "frame rate numerator = %d denominator = %d\n",
 837                state->frame_interval.numerator,
 838                state->frame_interval.denominator);
 839        dev_dbg(core->dev, "Stream code = 0x%x\n", format->code);
 840        return 0;
 841}
 842
 843/**
 844 * xsdirxss_irq_handler - Interrupt handler for SDI Rx
 845 * @irq: IRQ number
 846 * @dev_id: Pointer to device state
 847 *
 848 * The SDI Rx interrupts are cleared by first setting and then clearing the bits
 849 * in the interrupt clear register. The interrupt status register is read only.
 850 *
 851 * Return: IRQ_HANDLED after handling interrupts
 852 */
 853static irqreturn_t xsdirxss_irq_handler(int irq, void *dev_id)
 854{
 855        struct xsdirxss_state *state = (struct xsdirxss_state *)dev_id;
 856        struct xsdirxss_core *core = &state->core;
 857        u32 status;
 858
 859        status = xsdirxss_read(core, XSDIRX_ISR_REG);
 860        dev_dbg(core->dev, "interrupt status = 0x%08x\n", status);
 861
 862        if (!status)
 863                return IRQ_NONE;
 864
 865        if (status & XSDIRX_INTR_VIDLOCK_MASK) {
 866                u32 val1, val2;
 867
 868                dev_dbg(core->dev, "video lock interrupt\n");
 869                xsdirx_clearintr(core, XSDIRX_INTR_VIDLOCK_MASK);
 870
 871                val1 = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
 872                val2 = xsdirxss_read(core, XSDIRX_TS_DET_STAT_REG);
 873
 874                if ((val1 & XSDIRX_MODE_DET_STAT_MODE_LOCK_MASK) &&
 875                    (val2 & XSDIRX_TS_DET_STAT_LOCKED_MASK)) {
 876                        u32 mask = XSDIRX_RST_CTRL_RST_CRC_ERRCNT_MASK |
 877                                   XSDIRX_RST_CTRL_RST_EDH_ERRCNT_MASK;
 878
 879                        dev_dbg(core->dev, "mode & ts lock occurred\n");
 880
 881                        xsdirxss_set(core, XSDIRX_RST_CTRL_REG, mask);
 882                        xsdirxss_clr(core, XSDIRX_RST_CTRL_REG, mask);
 883
 884                        val1 = xsdirxss_read(core, XSDIRX_ST352_VALID_REG);
 885                        val2 = xsdirxss_read(core, XSDIRX_ST352_DS1_REG);
 886
 887                        dev_dbg(core->dev, "valid st352 mask = 0x%08x\n", val1);
 888                        dev_dbg(core->dev, "st352 payload = 0x%08x\n", val2);
 889
 890                        if (!xsdirx_get_stream_properties(state)) {
 891                                memset(&state->event, 0, sizeof(state->event));
 892                                state->event.type = V4L2_EVENT_SOURCE_CHANGE;
 893                                state->event.u.src_change.changes =
 894                                        V4L2_EVENT_SRC_CH_RESOLUTION;
 895                                v4l2_subdev_notify_event(&state->subdev,
 896                                                         &state->event);
 897
 898                                state->vidlocked = true;
 899                        } else {
 900                                dev_err(core->dev, "Unable to get stream properties!\n");
 901                                state->vidlocked = false;
 902                        }
 903                } else {
 904                        dev_dbg(core->dev, "video unlock before video lock!\n");
 905                        state->vidlocked = false;
 906                }
 907        }
 908
 909        if (status & XSDIRX_INTR_VIDUNLOCK_MASK) {
 910                dev_dbg(core->dev, "video unlock interrupt\n");
 911                xsdirx_clearintr(core, XSDIRX_INTR_VIDUNLOCK_MASK);
 912                xsdirx_streamdowncb(core);
 913
 914                memset(&state->event, 0, sizeof(state->event));
 915                state->event.type = V4L2_EVENT_XLNXSDIRX_VIDUNLOCK;
 916                v4l2_subdev_notify_event(&state->subdev, &state->event);
 917
 918                state->vidlocked = false;
 919        }
 920
 921        if (status & XSDIRX_INTR_UNDERFLOW_MASK) {
 922                dev_dbg(core->dev, "Video in to AXI4 Stream core underflow interrupt\n");
 923                xsdirx_clearintr(core, XSDIRX_INTR_UNDERFLOW_MASK);
 924
 925                memset(&state->event, 0, sizeof(state->event));
 926                state->event.type = V4L2_EVENT_XLNXSDIRX_UNDERFLOW;
 927                v4l2_subdev_notify_event(&state->subdev, &state->event);
 928        }
 929
 930        if (status & XSDIRX_INTR_OVERFLOW_MASK) {
 931                dev_dbg(core->dev, "Video in to AXI4 Stream core overflow interrupt\n");
 932                xsdirx_clearintr(core, XSDIRX_INTR_OVERFLOW_MASK);
 933
 934                memset(&state->event, 0, sizeof(state->event));
 935                state->event.type = V4L2_EVENT_XLNXSDIRX_OVERFLOW;
 936                v4l2_subdev_notify_event(&state->subdev, &state->event);
 937        }
 938        return IRQ_HANDLED;
 939}
 940
 941/**
 942 * xsdirxss_subscribe_event - Subscribe to video lock and unlock event
 943 * @sd: V4L2 Sub device
 944 * @fh: V4L2 File Handle
 945 * @sub: Subcribe event structure
 946 *
 947 * Return: 0 on success, errors otherwise
 948 */
 949static int xsdirxss_subscribe_event(struct v4l2_subdev *sd,
 950                                    struct v4l2_fh *fh,
 951                                    struct v4l2_event_subscription *sub)
 952{
 953        int ret;
 954        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
 955        struct xsdirxss_core *core = &xsdirxss->core;
 956
 957        switch (sub->type) {
 958        case V4L2_EVENT_XLNXSDIRX_VIDUNLOCK:
 959        case V4L2_EVENT_XLNXSDIRX_UNDERFLOW:
 960        case V4L2_EVENT_XLNXSDIRX_OVERFLOW:
 961                ret = v4l2_event_subscribe(fh, sub, XSDIRX_MAX_EVENTS, NULL);
 962                break;
 963        case V4L2_EVENT_SOURCE_CHANGE:
 964                ret = v4l2_src_change_event_subscribe(fh, sub);
 965                break;
 966        default:
 967                return -EINVAL;
 968        }
 969        dev_dbg(core->dev, "Event subscribed : 0x%08x\n", sub->type);
 970        return ret;
 971}
 972
 973/**
 974 * xsdirxss_unsubscribe_event - Unsubscribe from all events registered
 975 * @sd: V4L2 Sub device
 976 * @fh: V4L2 file handle
 977 * @sub: pointer to Event unsubscription structure
 978 *
 979 * Return: zero on success, else a negative error code.
 980 */
 981static int xsdirxss_unsubscribe_event(struct v4l2_subdev *sd,
 982                                      struct v4l2_fh *fh,
 983                                      struct v4l2_event_subscription *sub)
 984{
 985        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
 986        struct xsdirxss_core *core = &xsdirxss->core;
 987
 988        dev_dbg(core->dev, "Event unsubscribe : 0x%08x\n", sub->type);
 989        return v4l2_event_unsubscribe(fh, sub);
 990}
 991
 992/**
 993 * xsdirxss_s_ctrl - This is used to set the Xilinx SDI Rx V4L2 controls
 994 * @ctrl: V4L2 control to be set
 995 *
 996 * This function is used to set the V4L2 controls for the Xilinx SDI Rx
 997 * Subsystem.
 998 *
 999 * Return: 0 on success, errors otherwise
1000 */
1001static int xsdirxss_s_ctrl(struct v4l2_ctrl *ctrl)
1002{
1003        int ret = 0;
1004        struct xsdirxss_state *xsdirxss =
1005                container_of(ctrl->handler,
1006                             struct xsdirxss_state, ctrl_handler);
1007        struct xsdirxss_core *core = &xsdirxss->core;
1008
1009        dev_dbg(core->dev, "set ctrl id = 0x%08x val = 0x%08x\n",
1010                ctrl->id, ctrl->val);
1011
1012        if (xsdirxss->streaming) {
1013                dev_err(core->dev, "Cannot set controls while streaming\n");
1014                return -EINVAL;
1015        }
1016
1017        xsdirx_core_disable(core);
1018        switch (ctrl->id) {
1019        case V4L2_CID_XILINX_SDIRX_FRAMER:
1020                xsdirx_framer(core, ctrl->val);
1021                break;
1022        case V4L2_CID_XILINX_SDIRX_VIDLOCK_WINDOW:
1023                xsdirx_setvidlockwindow(core, ctrl->val);
1024                break;
1025        case V4L2_CID_XILINX_SDIRX_EDH_ERRCNT_ENABLE:
1026                xsdirx_setedherrcnttrigger(core, ctrl->val);
1027                break;
1028        case V4L2_CID_XILINX_SDIRX_SEARCH_MODES:
1029                if (ctrl->val) {
1030                        if (core->mode == XSDIRXSS_SDI_STD_3G) {
1031                                dev_dbg(core->dev, "Upto 3G supported\n");
1032                                ctrl->val &= ~(BIT(XSDIRX_MODE_6G_OFFSET) |
1033                                               BIT(XSDIRX_MODE_12GI_OFFSET) |
1034                                               BIT(XSDIRX_MODE_12GF_OFFSET));
1035                        }
1036
1037                        if (core->mode == XSDIRXSS_SDI_STD_6G) {
1038                                dev_dbg(core->dev, "Upto 6G supported\n");
1039                                ctrl->val &= ~(BIT(XSDIRX_MODE_12GI_OFFSET) |
1040                                               BIT(XSDIRX_MODE_12GF_OFFSET));
1041                        }
1042
1043                        ret = xsdirx_set_modedetect(core, ctrl->val);
1044                } else {
1045                        dev_err(core->dev, "Select at least one mode!\n");
1046                        return -EINVAL;
1047                }
1048                break;
1049        default:
1050                xsdirxss_set(core, XSDIRX_RST_CTRL_REG,
1051                             XSDIRX_RST_CTRL_SS_EN_MASK);
1052                return -EINVAL;
1053        }
1054        xsdirx_core_enable(core);
1055        return ret;
1056}
1057
1058/**
1059 * xsdirxss_g_volatile_ctrl - get the Xilinx SDI Rx controls
1060 * @ctrl: Pointer to V4L2 control
1061 *
1062 * Return: 0 on success, errors otherwise
1063 */
1064static int xsdirxss_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1065{
1066        u32 val;
1067        struct xsdirxss_state *xsdirxss =
1068                container_of(ctrl->handler,
1069                             struct xsdirxss_state, ctrl_handler);
1070        struct xsdirxss_core *core = &xsdirxss->core;
1071
1072        switch (ctrl->id) {
1073        case V4L2_CID_XILINX_SDIRX_MODE_DETECT:
1074                if (!xsdirxss->vidlocked) {
1075                        dev_err(core->dev, "Can't get values when video not locked!\n");
1076                        return -EINVAL;
1077                }
1078                val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1079                val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
1080
1081                switch (val) {
1082                case XSDIRX_MODE_SD_MASK:
1083                        ctrl->val = XSDIRX_MODE_SD_OFFSET;
1084                        break;
1085                case XSDIRX_MODE_HD_MASK:
1086                        ctrl->val = XSDIRX_MODE_HD_OFFSET;
1087                        break;
1088                case XSDIRX_MODE_3G_MASK:
1089                        ctrl->val = XSDIRX_MODE_3G_OFFSET;
1090                        break;
1091                case XSDIRX_MODE_6G_MASK:
1092                        ctrl->val = XSDIRX_MODE_6G_OFFSET;
1093                        break;
1094                case XSDIRX_MODE_12GI_MASK:
1095                        ctrl->val = XSDIRX_MODE_12GI_OFFSET;
1096                        break;
1097                case XSDIRX_MODE_12GF_MASK:
1098                        ctrl->val = XSDIRX_MODE_12GF_OFFSET;
1099                        break;
1100                }
1101                break;
1102        case V4L2_CID_XILINX_SDIRX_CRC:
1103                ctrl->val = xsdirxss_read(core, XSDIRX_CRC_ERRCNT_REG);
1104                xsdirxss_write(core, XSDIRX_CRC_ERRCNT_REG, 0xFFFF);
1105                break;
1106        case V4L2_CID_XILINX_SDIRX_EDH_ERRCNT:
1107                val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1108                val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
1109                if (val == XSDIRX_MODE_SD_MASK) {
1110                        ctrl->val = xsdirxss_read(core, XSDIRX_EDH_ERRCNT_REG);
1111                } else {
1112                        dev_dbg(core->dev, "%d - not in SD mode\n", ctrl->id);
1113                        return -EINVAL;
1114                }
1115                break;
1116        case V4L2_CID_XILINX_SDIRX_EDH_STATUS:
1117                val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1118                val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
1119                if (val == XSDIRX_MODE_SD_MASK) {
1120                        ctrl->val = xsdirxss_read(core, XSDIRX_EDH_STAT_REG);
1121                } else {
1122                        dev_dbg(core->dev, "%d - not in SD mode\n", ctrl->id);
1123                        return -EINVAL;
1124                }
1125                break;
1126        case V4L2_CID_XILINX_SDIRX_TS_IS_INTERLACED:
1127                if (!xsdirxss->vidlocked) {
1128                        dev_err(core->dev, "Can't get values when video not locked!\n");
1129                        return -EINVAL;
1130                }
1131                ctrl->val = xsdirxss->ts_is_interlaced;
1132                break;
1133        case V4L2_CID_XILINX_SDIRX_ACTIVE_STREAMS:
1134                if (!xsdirxss->vidlocked) {
1135                        dev_err(core->dev, "Can't get values when video not locked!\n");
1136                        return -EINVAL;
1137                }
1138                val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1139                val &= XSDIRX_MODE_DET_STAT_ACT_STREAM_MASK;
1140                val >>= XSDIRX_MODE_DET_STAT_ACT_STREAM_OFFSET;
1141                ctrl->val = 1 << val;
1142                break;
1143        case V4L2_CID_XILINX_SDIRX_IS_3GB:
1144                if (!xsdirxss->vidlocked) {
1145                        dev_err(core->dev, "Can't get values when video not locked!\n");
1146                        return -EINVAL;
1147                }
1148                val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1149                val &= XSDIRX_MODE_DET_STAT_LVLB_3G_MASK;
1150                ctrl->val = val ? true : false;
1151                break;
1152        default:
1153                dev_err(core->dev, "Get Invalid control id 0x%0x\n", ctrl->id);
1154                return -EINVAL;
1155        }
1156        dev_dbg(core->dev, "Get ctrl id = 0x%08x val = 0x%08x\n",
1157                ctrl->id, ctrl->val);
1158        return 0;
1159}
1160
1161/**
1162 * xsdirxss_log_status - Logs the status of the SDI Rx Subsystem
1163 * @sd: Pointer to V4L2 subdevice structure
1164 *
1165 * This function prints the current status of Xilinx SDI Rx Subsystem
1166 *
1167 * Return: 0 on success
1168 */
1169static int xsdirxss_log_status(struct v4l2_subdev *sd)
1170{
1171        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1172        struct xsdirxss_core *core = &xsdirxss->core;
1173        u32 data, i;
1174
1175        v4l2_info(sd, "***** SDI Rx subsystem reg dump start *****\n");
1176        for (i = 0; i < 0x28; i++) {
1177                data = xsdirxss_read(core, i * 4);
1178                v4l2_info(sd, "offset 0x%08x data 0x%08x\n",
1179                          i * 4, data);
1180        }
1181        v4l2_info(sd, "***** SDI Rx subsystem reg dump end *****\n");
1182        return 0;
1183}
1184
1185static void xsdirxss_start_stream(struct xsdirxss_state *xsdirxss)
1186{
1187        xsdirx_streamflow_control(&xsdirxss->core, true);
1188}
1189
1190static void xsdirxss_stop_stream(struct xsdirxss_state *xsdirxss)
1191{
1192        xsdirx_streamflow_control(&xsdirxss->core, false);
1193}
1194
1195/**
1196 * xsdirxss_g_frame_interval - Get the frame interval
1197 * @sd: V4L2 Sub device
1198 * @fi: Pointer to V4l2 Sub device frame interval structure
1199 *
1200 * This function is used to get the frame interval.
1201 * The frame rate can be integral or fractional.
1202 * Integral frame rate e.g. numerator = 1000, denominator = 24000 => 24 fps
1203 * Fractional frame rate e.g. numerator = 1001, denominator = 24000 => 23.97 fps
1204 *
1205 * Return: 0 on success
1206 */
1207static int xsdirxss_g_frame_interval(struct v4l2_subdev *sd,
1208                                     struct v4l2_subdev_frame_interval *fi)
1209{
1210        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1211        struct xsdirxss_core *core = &xsdirxss->core;
1212
1213        if (!xsdirxss->vidlocked) {
1214                dev_err(core->dev, "Video not locked!\n");
1215                return -EINVAL;
1216        }
1217
1218        fi->interval = xsdirxss->frame_interval;
1219
1220        dev_dbg(core->dev, "frame rate numerator = %d denominator = %d\n",
1221                xsdirxss->frame_interval.numerator,
1222                xsdirxss->frame_interval.denominator);
1223        return 0;
1224}
1225
1226/**
1227 * xsdirxss_s_stream - It is used to start/stop the streaming.
1228 * @sd: V4L2 Sub device
1229 * @enable: Flag (True / False)
1230 *
1231 * This function controls the start or stop of streaming for the
1232 * Xilinx SDI Rx Subsystem.
1233 *
1234 * Return: 0 on success, errors otherwise
1235 */
1236static int xsdirxss_s_stream(struct v4l2_subdev *sd, int enable)
1237{
1238        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1239        struct xsdirxss_core *core = &xsdirxss->core;
1240
1241        if (enable) {
1242                if (!xsdirxss->vidlocked) {
1243                        dev_dbg(core->dev, "Video is not locked\n");
1244                        return -EINVAL;
1245                }
1246                if (xsdirxss->streaming) {
1247                        dev_dbg(core->dev, "Already streaming\n");
1248                        return -EINVAL;
1249                }
1250
1251                xsdirxss_start_stream(xsdirxss);
1252                xsdirxss->streaming = true;
1253                dev_dbg(core->dev, "Streaming started\n");
1254        } else {
1255                if (!xsdirxss->streaming) {
1256                        dev_dbg(core->dev, "Stopped streaming already\n");
1257                        return -EINVAL;
1258                }
1259
1260                xsdirxss_stop_stream(xsdirxss);
1261                xsdirxss->streaming = false;
1262                dev_dbg(core->dev, "Streaming stopped\n");
1263        }
1264
1265        return 0;
1266}
1267
1268static struct v4l2_mbus_framefmt *
1269__xsdirxss_get_pad_format(struct xsdirxss_state *xsdirxss,
1270                          struct v4l2_subdev_pad_config *cfg,
1271                                unsigned int pad, u32 which)
1272{
1273        switch (which) {
1274        case V4L2_SUBDEV_FORMAT_TRY:
1275                return v4l2_subdev_get_try_format(&xsdirxss->subdev, cfg, pad);
1276        case V4L2_SUBDEV_FORMAT_ACTIVE:
1277                return &xsdirxss->formats[pad];
1278        default:
1279                return NULL;
1280        }
1281}
1282
1283/**
1284 * xsdirxss_get_format - Get the pad format
1285 * @sd: Pointer to V4L2 Sub device structure
1286 * @cfg: Pointer to sub device pad information structure
1287 * @fmt: Pointer to pad level media bus format
1288 *
1289 * This function is used to get the pad format information.
1290 *
1291 * Return: 0 on success
1292 */
1293static int xsdirxss_get_format(struct v4l2_subdev *sd,
1294                               struct v4l2_subdev_pad_config *cfg,
1295                                        struct v4l2_subdev_format *fmt)
1296{
1297        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1298        struct xsdirxss_core *core = &xsdirxss->core;
1299
1300        if (!xsdirxss->vidlocked) {
1301                dev_err(core->dev, "Video not locked!\n");
1302                return -EINVAL;
1303        }
1304
1305        fmt->format = *__xsdirxss_get_pad_format(xsdirxss, cfg,
1306                                                 fmt->pad, fmt->which);
1307
1308        dev_dbg(core->dev, "Stream width = %d height = %d Field = %d\n",
1309                fmt->format.width, fmt->format.height, fmt->format.field);
1310
1311        return 0;
1312}
1313
1314/**
1315 * xsdirxss_set_format - This is used to set the pad format
1316 * @sd: Pointer to V4L2 Sub device structure
1317 * @cfg: Pointer to sub device pad information structure
1318 * @fmt: Pointer to pad level media bus format
1319 *
1320 * This function is used to set the pad format.
1321 * Since the pad format is fixed in hardware, it can't be
1322 * modified on run time.
1323 *
1324 * Return: 0 on success
1325 */
1326static int xsdirxss_set_format(struct v4l2_subdev *sd,
1327                               struct v4l2_subdev_pad_config *cfg,
1328                                struct v4l2_subdev_format *fmt)
1329{
1330        struct v4l2_mbus_framefmt *__format;
1331        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1332
1333        dev_dbg(xsdirxss->core.dev,
1334                "set width %d height %d code %d field %d colorspace %d\n",
1335                fmt->format.width, fmt->format.height,
1336                fmt->format.code, fmt->format.field,
1337                fmt->format.colorspace);
1338
1339        __format = __xsdirxss_get_pad_format(xsdirxss, cfg,
1340                                             fmt->pad, fmt->which);
1341
1342        /* Currently reset the code to one fixed in hardware */
1343        /* TODO : Add checks for width height */
1344        fmt->format.code = __format->code;
1345
1346        return 0;
1347}
1348
1349/**
1350 * xsdirxss_open - Called on v4l2_open()
1351 * @sd: Pointer to V4L2 sub device structure
1352 * @fh: Pointer to V4L2 File handle
1353 *
1354 * This function is called on v4l2_open(). It sets the default format for pad.
1355 *
1356 * Return: 0 on success
1357 */
1358static int xsdirxss_open(struct v4l2_subdev *sd,
1359                         struct v4l2_subdev_fh *fh)
1360{
1361        struct v4l2_mbus_framefmt *format;
1362        struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1363
1364        format = v4l2_subdev_get_try_format(sd, fh->pad, 0);
1365        *format = xsdirxss->default_format;
1366
1367        return 0;
1368}
1369
1370/**
1371 * xsdirxss_close - Called on v4l2_close()
1372 * @sd: Pointer to V4L2 sub device structure
1373 * @fh: Pointer to V4L2 File handle
1374 *
1375 * This function is called on v4l2_close().
1376 *
1377 * Return: 0 on success
1378 */
1379static int xsdirxss_close(struct v4l2_subdev *sd,
1380                          struct v4l2_subdev_fh *fh)
1381{
1382        return 0;
1383}
1384
1385/* -----------------------------------------------------------------------------
1386 * Media Operations
1387 */
1388
1389static const struct media_entity_operations xsdirxss_media_ops = {
1390        .link_validate = v4l2_subdev_link_validate
1391};
1392
1393static const struct v4l2_ctrl_ops xsdirxss_ctrl_ops = {
1394        .g_volatile_ctrl = xsdirxss_g_volatile_ctrl,
1395        .s_ctrl = xsdirxss_s_ctrl
1396};
1397
1398static struct v4l2_ctrl_config xsdirxss_edh_ctrls[] = {
1399        {
1400                .ops    = &xsdirxss_ctrl_ops,
1401                .id     = V4L2_CID_XILINX_SDIRX_EDH_ERRCNT_ENABLE,
1402                .name   = "SDI Rx : EDH Error Count Enable",
1403                .type   = V4L2_CTRL_TYPE_BITMASK,
1404                .min    = 0,
1405                .max    = XSDIRX_EDH_ALLERR_MASK,
1406                .def    = 0,
1407        }, {
1408                .ops    = &xsdirxss_ctrl_ops,
1409                .id     = V4L2_CID_XILINX_SDIRX_EDH_ERRCNT,
1410                .name   = "SDI Rx : EDH Error Count",
1411                .type   = V4L2_CTRL_TYPE_INTEGER,
1412                .min    = 0,
1413                .max    = 0xFFFF,
1414                .step   = 1,
1415                .def    = 0,
1416                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
1417        }, {
1418                .ops    = &xsdirxss_ctrl_ops,
1419                .id     = V4L2_CID_XILINX_SDIRX_EDH_STATUS,
1420                .name   = "SDI Rx : EDH Status",
1421                .type   = V4L2_CTRL_TYPE_INTEGER,
1422                .min    = 0,
1423                .max    = 0xFFFFFFFF,
1424                .step   = 1,
1425                .def    = 0,
1426                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
1427        }
1428};
1429
1430static struct v4l2_ctrl_config xsdirxss_ctrls[] = {
1431        {
1432                .ops    = &xsdirxss_ctrl_ops,
1433                .id     = V4L2_CID_XILINX_SDIRX_FRAMER,
1434                .name   = "SDI Rx : Enable Framer",
1435                .type   = V4L2_CTRL_TYPE_BOOLEAN,
1436                .min    = false,
1437                .max    = true,
1438                .step   = 1,
1439                .def    = true,
1440        }, {
1441                .ops    = &xsdirxss_ctrl_ops,
1442                .id     = V4L2_CID_XILINX_SDIRX_VIDLOCK_WINDOW,
1443                .name   = "SDI Rx : Video Lock Window",
1444                .type   = V4L2_CTRL_TYPE_INTEGER,
1445                .min    = 0,
1446                .max    = 0xFFFFFFFF,
1447                .step   = 1,
1448                .def    = XSDIRX_DEFAULT_VIDEO_LOCK_WINDOW,
1449        }, {
1450                .ops    = &xsdirxss_ctrl_ops,
1451                .id     = V4L2_CID_XILINX_SDIRX_SEARCH_MODES,
1452                .name   = "SDI Rx : Modes search Mask",
1453                .type   = V4L2_CTRL_TYPE_BITMASK,
1454                .min    = 0,
1455                .max    = XSDIRX_DETECT_ALL_MODES,
1456                .def    = XSDIRX_DETECT_ALL_MODES,
1457        }, {
1458                .ops    = &xsdirxss_ctrl_ops,
1459                .id     = V4L2_CID_XILINX_SDIRX_MODE_DETECT,
1460                .name   = "SDI Rx : Mode Detect Status",
1461                .type   = V4L2_CTRL_TYPE_INTEGER,
1462                .min    = XSDIRX_MODE_SD_OFFSET,
1463                .max    = XSDIRX_MODE_12GF_OFFSET,
1464                .step   = 1,
1465                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
1466        }, {
1467                .ops    = &xsdirxss_ctrl_ops,
1468                .id     = V4L2_CID_XILINX_SDIRX_CRC,
1469                .name   = "SDI Rx : CRC Error status",
1470                .type   = V4L2_CTRL_TYPE_INTEGER,
1471                .min    = 0,
1472                .max    = 0xFFFFFFFF,
1473                .step   = 1,
1474                .def    = 0,
1475                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
1476        }, {
1477                .ops    = &xsdirxss_ctrl_ops,
1478                .id     = V4L2_CID_XILINX_SDIRX_TS_IS_INTERLACED,
1479                .name   = "SDI Rx : TS is Interlaced",
1480                .type   = V4L2_CTRL_TYPE_BOOLEAN,
1481                .min    = false,
1482                .max    = true,
1483                .def    = false,
1484                .step   = 1,
1485                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
1486        }, {
1487                .ops    = &xsdirxss_ctrl_ops,
1488                .id     = V4L2_CID_XILINX_SDIRX_ACTIVE_STREAMS,
1489                .name   = "SDI Rx : Active Streams",
1490                .type   = V4L2_CTRL_TYPE_INTEGER,
1491                .min    = 1,
1492                .max    = 16,
1493                .def    = 1,
1494                .step   = 1,
1495                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
1496        }, {
1497                .ops    = &xsdirxss_ctrl_ops,
1498                .id     = V4L2_CID_XILINX_SDIRX_IS_3GB,
1499                .name   = "SDI Rx : Is 3GB",
1500                .type   = V4L2_CTRL_TYPE_BOOLEAN,
1501                .min    = false,
1502                .max    = true,
1503                .def    = false,
1504                .step   = 1,
1505                .flags  = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
1506        }
1507};
1508
1509static const struct v4l2_subdev_core_ops xsdirxss_core_ops = {
1510        .log_status = xsdirxss_log_status,
1511        .subscribe_event = xsdirxss_subscribe_event,
1512        .unsubscribe_event = xsdirxss_unsubscribe_event
1513};
1514
1515static struct v4l2_subdev_video_ops xsdirxss_video_ops = {
1516        .g_frame_interval = xsdirxss_g_frame_interval,
1517        .s_stream = xsdirxss_s_stream
1518};
1519
1520static struct v4l2_subdev_pad_ops xsdirxss_pad_ops = {
1521        .get_fmt = xsdirxss_get_format,
1522        .set_fmt = xsdirxss_set_format,
1523};
1524
1525static struct v4l2_subdev_ops xsdirxss_ops = {
1526        .core = &xsdirxss_core_ops,
1527        .video = &xsdirxss_video_ops,
1528        .pad = &xsdirxss_pad_ops
1529};
1530
1531static const struct v4l2_subdev_internal_ops xsdirxss_internal_ops = {
1532        .open = xsdirxss_open,
1533        .close = xsdirxss_close
1534};
1535
1536/* -----------------------------------------------------------------------------
1537 * Platform Device Driver
1538 */
1539
1540static int xsdirxss_parse_of(struct xsdirxss_state *xsdirxss)
1541{
1542        struct device_node *node = xsdirxss->core.dev->of_node;
1543        struct device_node *ports = NULL;
1544        struct device_node *port = NULL;
1545        unsigned int nports = 0;
1546        struct xsdirxss_core *core = &xsdirxss->core;
1547        int ret;
1548        const char *sdi_std;
1549
1550        core->include_edh = of_property_read_bool(node, "xlnx,include-edh");
1551        dev_dbg(core->dev, "EDH property = %s\n",
1552                core->include_edh ? "Present" : "Absent");
1553
1554        ret = of_property_read_string(node, "xlnx,line-rate",
1555                                      &sdi_std);
1556        if (ret < 0) {
1557                dev_err(core->dev, "xlnx,line-rate property not found\n");
1558                return ret;
1559        }
1560
1561        if (!strncmp(sdi_std, "12G_SDI_8DS", XSDIRX_MAX_STR_LENGTH)) {
1562                core->mode = XSDIRXSS_SDI_STD_12G_8DS;
1563        } else if (!strncmp(sdi_std, "6G_SDI", XSDIRX_MAX_STR_LENGTH)) {
1564                core->mode = XSDIRXSS_SDI_STD_6G;
1565        } else if (!strncmp(sdi_std, "3G_SDI", XSDIRX_MAX_STR_LENGTH)) {
1566                core->mode = XSDIRXSS_SDI_STD_3G;
1567        } else {
1568                dev_err(core->dev, "Invalid Line Rate\n");
1569                return -EINVAL;
1570        }
1571        dev_dbg(core->dev, "SDI Rx Line Rate = %s, mode = %d\n", sdi_std,
1572                core->mode);
1573
1574        ports = of_get_child_by_name(node, "ports");
1575        if (!ports)
1576                ports = node;
1577
1578        for_each_child_of_node(ports, port) {
1579                const struct xvip_video_format *format;
1580                struct device_node *endpoint;
1581
1582                if (!port->name || of_node_cmp(port->name, "port"))
1583                        continue;
1584
1585                format = xvip_of_get_format(port);
1586                if (IS_ERR(format)) {
1587                        dev_err(core->dev, "invalid format in DT");
1588                        return PTR_ERR(format);
1589                }
1590
1591                dev_dbg(core->dev, "vf_code = %d bpc = %d bpp = %d\n",
1592                        format->vf_code, format->width, format->bpp);
1593
1594                if (format->vf_code != XVIP_VF_YUV_422 &&
1595                    format->vf_code != XVIP_VF_YUV_420) {
1596                        dev_err(core->dev, "Incorrect UG934 video format set.\n");
1597                        return -EINVAL;
1598                }
1599                xsdirxss->vip_format = format;
1600
1601                endpoint = of_get_next_child(port, NULL);
1602                if (!endpoint) {
1603                        dev_err(core->dev, "No port at\n");
1604                        return -EINVAL;
1605                }
1606
1607                /* Count the number of ports. */
1608                nports++;
1609        }
1610
1611        if (nports != 1) {
1612                dev_err(core->dev, "invalid number of ports %u\n", nports);
1613                return -EINVAL;
1614        }
1615
1616        /* Register interrupt handler */
1617        core->irq = irq_of_parse_and_map(node, 0);
1618
1619        ret = devm_request_irq(core->dev, core->irq, xsdirxss_irq_handler,
1620                               IRQF_SHARED, "xilinx-sdirxss", xsdirxss);
1621        if (ret) {
1622                dev_err(core->dev, "Err = %d Interrupt handler reg failed!\n",
1623                        ret);
1624                return ret;
1625        }
1626
1627        return 0;
1628}
1629
1630static int xsdirxss_probe(struct platform_device *pdev)
1631{
1632        struct v4l2_subdev *subdev;
1633        struct xsdirxss_state *xsdirxss;
1634        struct xsdirxss_core *core;
1635        struct resource *res;
1636        int ret;
1637        unsigned int num_ctrls, num_edh_ctrls = 0, i;
1638
1639        xsdirxss = devm_kzalloc(&pdev->dev, sizeof(*xsdirxss), GFP_KERNEL);
1640        if (!xsdirxss)
1641                return -ENOMEM;
1642
1643        xsdirxss->core.dev = &pdev->dev;
1644        core = &xsdirxss->core;
1645
1646        core->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
1647        if (IS_ERR(core->axi_clk)) {
1648                ret = PTR_ERR(core->axi_clk);
1649                dev_err(&pdev->dev, "failed to get s_axi_clk (%d)\n", ret);
1650                return ret;
1651        }
1652
1653        core->sdirx_clk = devm_clk_get(&pdev->dev, "sdi_rx_clk");
1654        if (IS_ERR(core->sdirx_clk)) {
1655                ret = PTR_ERR(core->sdirx_clk);
1656                dev_err(&pdev->dev, "failed to get sdi_rx_clk (%d)\n", ret);
1657                return ret;
1658        }
1659
1660        core->vidout_clk = devm_clk_get(&pdev->dev, "video_out_clk");
1661        if (IS_ERR(core->vidout_clk)) {
1662                ret = PTR_ERR(core->vidout_clk);
1663                dev_err(&pdev->dev, "failed to get video_out_aclk (%d)\n", ret);
1664                return ret;
1665        }
1666
1667        ret = clk_prepare_enable(core->axi_clk);
1668        if (ret) {
1669                dev_err(&pdev->dev, "failed to enable axi_clk (%d)\n", ret);
1670                return ret;
1671        }
1672
1673        ret = clk_prepare_enable(core->sdirx_clk);
1674        if (ret) {
1675                dev_err(&pdev->dev, "failed to enable sdirx_clk (%d)\n", ret);
1676                goto rx_clk_err;
1677        }
1678
1679        ret = clk_prepare_enable(core->vidout_clk);
1680        if (ret) {
1681                dev_err(&pdev->dev, "failed to enable vidout_clk (%d)\n", ret);
1682                goto vidout_clk_err;
1683        }
1684
1685        ret = xsdirxss_parse_of(xsdirxss);
1686        if (ret < 0)
1687                goto clk_err;
1688
1689        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1690        xsdirxss->core.iomem = devm_ioremap_resource(xsdirxss->core.dev, res);
1691        if (IS_ERR(xsdirxss->core.iomem)) {
1692                ret = PTR_ERR(xsdirxss->core.iomem);
1693                goto clk_err;
1694        }
1695
1696        /* Reset the core */
1697        xsdirx_streamflow_control(core, false);
1698        xsdirx_core_disable(core);
1699        xsdirx_clearintr(core, XSDIRX_INTR_ALL_MASK);
1700        xsdirx_disableintr(core, XSDIRX_INTR_ALL_MASK);
1701        xsdirx_enableintr(core, XSDIRX_INTR_ALL_MASK);
1702        xsdirx_globalintr(core, true);
1703        xsdirxss_write(core, XSDIRX_CRC_ERRCNT_REG, 0xFFFF);
1704
1705        /* Initialize V4L2 subdevice and media entity */
1706        xsdirxss->pads[0].flags = MEDIA_PAD_FL_SOURCE;
1707
1708        /* Initialize the default format */
1709        xsdirxss->default_format.code = xsdirxss->vip_format->code;
1710        xsdirxss->default_format.field = V4L2_FIELD_NONE;
1711        xsdirxss->default_format.colorspace = V4L2_COLORSPACE_DEFAULT;
1712        xsdirxss->default_format.width = XSDIRX_DEFAULT_WIDTH;
1713        xsdirxss->default_format.height = XSDIRX_DEFAULT_HEIGHT;
1714
1715        xsdirxss->formats[0] = xsdirxss->default_format;
1716
1717        /* Initialize V4L2 subdevice and media entity */
1718        subdev = &xsdirxss->subdev;
1719        v4l2_subdev_init(subdev, &xsdirxss_ops);
1720
1721        subdev->dev = &pdev->dev;
1722        subdev->internal_ops = &xsdirxss_internal_ops;
1723        strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
1724
1725        subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1726
1727        subdev->entity.ops = &xsdirxss_media_ops;
1728
1729        v4l2_set_subdevdata(subdev, xsdirxss);
1730
1731        ret = media_entity_pads_init(&subdev->entity, 1, xsdirxss->pads);
1732        if (ret < 0)
1733                goto error;
1734
1735        /* Initialise and register the controls */
1736        num_ctrls = ARRAY_SIZE(xsdirxss_ctrls);
1737
1738        if (xsdirxss->core.include_edh)
1739                num_edh_ctrls = ARRAY_SIZE(xsdirxss_edh_ctrls);
1740
1741        v4l2_ctrl_handler_init(&xsdirxss->ctrl_handler,
1742                               (num_ctrls + num_edh_ctrls));
1743
1744        for (i = 0; i < num_ctrls; i++) {
1745                struct v4l2_ctrl *ctrl;
1746
1747                dev_dbg(xsdirxss->core.dev, "%d %s ctrl = 0x%x\n",
1748                        i, xsdirxss_ctrls[i].name, xsdirxss_ctrls[i].id);
1749
1750                ctrl = v4l2_ctrl_new_custom(&xsdirxss->ctrl_handler,
1751                                            &xsdirxss_ctrls[i], NULL);
1752                if (!ctrl) {
1753                        dev_dbg(xsdirxss->core.dev, "Failed to add %s ctrl\n",
1754                                xsdirxss_ctrls[i].name);
1755                        goto error;
1756                }
1757        }
1758
1759        if (xsdirxss->core.include_edh) {
1760                for (i = 0; i < num_edh_ctrls; i++) {
1761                        struct v4l2_ctrl *ctrl;
1762
1763                        dev_dbg(xsdirxss->core.dev, "%d %s ctrl = 0x%x\n",
1764                                i, xsdirxss_edh_ctrls[i].name,
1765                                xsdirxss_edh_ctrls[i].id);
1766
1767                        ctrl = v4l2_ctrl_new_custom(&xsdirxss->ctrl_handler,
1768                                                    &xsdirxss_edh_ctrls[i],
1769                                                    NULL);
1770                        if (!ctrl) {
1771                                dev_dbg(xsdirxss->core.dev, "Failed to add %s ctrl\n",
1772                                        xsdirxss_edh_ctrls[i].name);
1773                                goto error;
1774                        }
1775                }
1776        } else {
1777                dev_dbg(xsdirxss->core.dev, "Not registering the EDH controls as EDH is disabled in IP\n");
1778        }
1779
1780        if (xsdirxss->ctrl_handler.error) {
1781                dev_err(&pdev->dev, "failed to add controls\n");
1782                ret = xsdirxss->ctrl_handler.error;
1783                goto error;
1784        }
1785
1786        subdev->ctrl_handler = &xsdirxss->ctrl_handler;
1787
1788        ret = v4l2_ctrl_handler_setup(&xsdirxss->ctrl_handler);
1789        if (ret < 0) {
1790                dev_err(&pdev->dev, "failed to set controls\n");
1791                goto error;
1792        }
1793
1794        platform_set_drvdata(pdev, xsdirxss);
1795
1796        ret = v4l2_async_register_subdev(subdev);
1797        if (ret < 0) {
1798                dev_err(&pdev->dev, "failed to register subdev\n");
1799                goto error;
1800        }
1801
1802        xsdirxss->streaming = false;
1803
1804        dev_info(xsdirxss->core.dev, "Xilinx SDI Rx Subsystem device found!\n");
1805
1806        xsdirx_core_enable(core);
1807
1808        return 0;
1809error:
1810        v4l2_ctrl_handler_free(&xsdirxss->ctrl_handler);
1811        media_entity_cleanup(&subdev->entity);
1812
1813clk_err:
1814        clk_disable_unprepare(core->vidout_clk);
1815vidout_clk_err:
1816        clk_disable_unprepare(core->sdirx_clk);
1817rx_clk_err:
1818        clk_disable_unprepare(core->axi_clk);
1819        return ret;
1820}
1821
1822static int xsdirxss_remove(struct platform_device *pdev)
1823{
1824        struct xsdirxss_state *xsdirxss = platform_get_drvdata(pdev);
1825        struct v4l2_subdev *subdev = &xsdirxss->subdev;
1826
1827        v4l2_async_unregister_subdev(subdev);
1828        v4l2_ctrl_handler_free(&xsdirxss->ctrl_handler);
1829        media_entity_cleanup(&subdev->entity);
1830        clk_disable_unprepare(xsdirxss->core.vidout_clk);
1831        clk_disable_unprepare(xsdirxss->core.sdirx_clk);
1832        clk_disable_unprepare(xsdirxss->core.axi_clk);
1833        return 0;
1834}
1835
1836static const struct of_device_id xsdirxss_of_id_table[] = {
1837        { .compatible = "xlnx,v-smpte-uhdsdi-rx-ss" },
1838        { }
1839};
1840MODULE_DEVICE_TABLE(of, xsdirxss_of_id_table);
1841
1842static struct platform_driver xsdirxss_driver = {
1843        .driver = {
1844                .name           = "xilinx-sdirxss",
1845                .of_match_table = xsdirxss_of_id_table,
1846        },
1847        .probe                  = xsdirxss_probe,
1848        .remove                 = xsdirxss_remove,
1849};
1850
1851module_platform_driver(xsdirxss_driver);
1852
1853MODULE_AUTHOR("Vishal Sagar <vsagar@xilinx.com>");
1854MODULE_DESCRIPTION("Xilinx SDI Rx Subsystem Driver");
1855MODULE_LICENSE("GPL v2");
1856