2 * Xilinx SDI Rx Subsystem
4 * Copyright (C) 2017 Xilinx, Inc.
6 * Contacts: Vishal Sagar <vsagar@xilinx.com>
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.
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.
18 #include <dt-bindings/media/xilinx-vip.h>
19 #include <linux/bitops.h>
20 #include <linux/compiler.h>
21 #include <linux/delay.h>
22 #include <linux/device.h>
23 #include <linux/interrupt.h>
25 #include <linux/kernel.h>
26 #include <linux/module.h>
28 #include <linux/of_irq.h>
29 #include <linux/platform_device.h>
31 #include <linux/slab.h>
32 #include <linux/spinlock.h>
33 #include <linux/spinlock_types.h>
34 #include <linux/types.h>
35 #include <linux/v4l2-subdev.h>
36 #include <linux/xilinx-sdirxss.h>
37 #include <linux/xilinx-v4l2-controls.h>
38 #include <media/media-entity.h>
39 #include <media/v4l2-common.h>
40 #include <media/v4l2-ctrls.h>
41 #include <media/v4l2-event.h>
42 #include <media/v4l2-of.h>
43 #include <media/v4l2-subdev.h>
44 #include "xilinx-vip.h"
47 * SDI Rx register map, bitmask and offsets
49 #define XSDIRX_RST_CTRL_REG 0x00
50 #define XSDIRX_MDL_CTRL_REG 0x04
51 #define XSDIRX_GLBL_IER_REG 0x0C
52 #define XSDIRX_ISR_REG 0x10
53 #define XSDIRX_IER_REG 0x14
54 #define XSDIRX_ST352_VALID_REG 0x18
55 #define XSDIRX_ST352_DS1_REG 0x1C
56 #define XSDIRX_ST352_DS3_REG 0x20
57 #define XSDIRX_ST352_DS5_REG 0x24
58 #define XSDIRX_ST352_DS7_REG 0x28
59 #define XSDIRX_ST352_DS9_REG 0x2C
60 #define XSDIRX_ST352_DS11_REG 0x30
61 #define XSDIRX_ST352_DS13_REG 0x34
62 #define XSDIRX_ST352_DS15_REG 0x38
63 #define XSDIRX_VERSION_REG 0x3C
64 #define XSDIRX_SS_CONFIG_REG 0x40
65 #define XSDIRX_MODE_DET_STAT_REG 0x44
66 #define XSDIRX_TS_DET_STAT_REG 0x48
67 #define XSDIRX_EDH_STAT_REG 0x4C
68 #define XSDIRX_EDH_ERRCNT_EN_REG 0x50
69 #define XSDIRX_EDH_ERRCNT_REG 0x54
70 #define XSDIRX_CRC_ERRCNT_REG 0x58
71 #define XSDIRX_VID_LOCK_WINDOW_REG 0x5C
72 #define XSDIRX_SB_RX_STS_REG 0x60
74 #define XSDIRX_RST_CTRL_SS_EN_MASK BIT(0)
75 #define XSDIRX_RST_CTRL_SRST_MASK BIT(1)
76 #define XSDIRX_RST_CTRL_RST_CRC_ERRCNT_MASK BIT(2)
77 #define XSDIRX_RST_CTRL_RST_EDH_ERRCNT_MASK BIT(3)
78 #define XSDIRX_RST_CTRL_SDIRX_BRIDGE_ENB_MASK BIT(8)
79 #define XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK BIT(9)
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)
91 #define XSDIRX_MDL_CTRL_FORCED_MODE_OFFSET 16
92 #define XSDIRX_MDL_CTRL_FORCED_MODE_MASK GENMASK(18, 16)
94 #define XSDIRX_GLBL_INTR_EN_MASK BIT(0)
96 #define XSDIRX_INTR_VIDLOCK_MASK BIT(0)
97 #define XSDIRX_INTR_VIDUNLOCK_MASK BIT(1)
98 #define XSDIRX_INTR_OVERFLOW_MASK BIT(9)
99 #define XSDIRX_INTR_UNDERFLOW_MASK BIT(10)
101 #define XSDIRX_INTR_ALL_MASK (XSDIRX_INTR_VIDLOCK_MASK |\
102 XSDIRX_INTR_VIDUNLOCK_MASK |\
103 XSDIRX_INTR_OVERFLOW_MASK |\
104 XSDIRX_INTR_UNDERFLOW_MASK)
106 #define XSDIRX_ST352_VALID_DS1_MASK BIT(0)
107 #define XSDIRX_ST352_VALID_DS3_MASK BIT(1)
108 #define XSDIRX_ST352_VALID_DS5_MASK BIT(2)
109 #define XSDIRX_ST352_VALID_DS7_MASK BIT(3)
110 #define XSDIRX_ST352_VALID_DS9_MASK BIT(4)
111 #define XSDIRX_ST352_VALID_DS11_MASK BIT(5)
112 #define XSDIRX_ST352_VALID_DS13_MASK BIT(6)
113 #define XSDIRX_ST352_VALID_DS15_MASK BIT(7)
115 #define XSDIRX_MODE_DET_STAT_RX_MODE_MASK GENMASK(2, 0)
116 #define XSDIRX_MODE_DET_STAT_MODE_LOCK_MASK BIT(3)
117 #define XSDIRX_MODE_DET_STAT_ACT_STREAM_MASK GENMASK(6, 4)
118 #define XSDIRX_MODE_DET_STAT_LVLB_3G_MASK BIT(7)
120 #define XSDIRX_ACTIVE_STREAMS_1 0x0
121 #define XSDIRX_ACTIVE_STREAMS_2 0x1
122 #define XSDIRX_ACTIVE_STREAMS_4 0x2
123 #define XSDIRX_ACTIVE_STREAMS_8 0x3
124 #define XSDIRX_ACTIVE_STREAMS_16 0x4
126 #define XSDIRX_TS_DET_STAT_LOCKED_MASK BIT(0)
127 #define XSDIRX_TS_DET_STAT_SCAN_MASK BIT(1)
128 #define XSDIRX_TS_DET_STAT_SCAN_OFFSET (1)
129 #define XSDIRX_TS_DET_STAT_FAMILY_MASK GENMASK(7, 4)
130 #define XSDIRX_TS_DET_STAT_FAMILY_OFFSET (4)
131 #define XSDIRX_TS_DET_STAT_RATE_MASK GENMASK(11, 8)
132 #define XSDIRX_TS_DET_STAT_RATE_OFFSET (8)
134 #define XSDIRX_TS_DET_STAT_RATE_NONE 0x0
135 #define XSDIRX_TS_DET_STAT_RATE_23_98HZ 0x2
136 #define XSDIRX_TS_DET_STAT_RATE_24HZ 0x3
137 #define XSDIRX_TS_DET_STAT_RATE_47_95HZ 0x4
138 #define XSDIRX_TS_DET_STAT_RATE_25HZ 0x5
139 #define XSDIRX_TS_DET_STAT_RATE_29_97HZ 0x6
140 #define XSDIRX_TS_DET_STAT_RATE_30HZ 0x7
141 #define XSDIRX_TS_DET_STAT_RATE_48HZ 0x8
142 #define XSDIRX_TS_DET_STAT_RATE_50HZ 0x9
143 #define XSDIRX_TS_DET_STAT_RATE_59_94HZ 0xA
144 #define XSDIRX_TS_DET_STAT_RATE_60HZ 0xB
146 #define XSDIRX_EDH_STAT_EDH_AP_MASK BIT(0)
147 #define XSDIRX_EDH_STAT_EDH_FF_MASK BIT(1)
148 #define XSDIRX_EDH_STAT_EDH_ANC_MASK BIT(2)
149 #define XSDIRX_EDH_STAT_AP_FLAG_MASK GENMASK(8, 4)
150 #define XSDIRX_EDH_STAT_FF_FLAG_MASK GENMASK(13, 9)
151 #define XSDIRX_EDH_STAT_ANC_FLAG_MASK GENMASK(18, 14)
152 #define XSDIRX_EDH_STAT_PKT_FLAG_MASK GENMASK(22, 19)
154 #define XSDIRX_EDH_ERRCNT_COUNT_MASK GENMASK(15, 0)
156 #define XSDIRX_CRC_ERRCNT_COUNT_MASK GENMASK(31, 16)
157 #define XSDIRX_CRC_ERRCNT_DS_CRC_MASK GENMASK(15, 0)
159 #define XSDIRX_VERSION_REV_MASK GENMASK(7, 0)
160 #define XSDIRX_VERSION_PATCHID_MASK GENMASK(11, 8)
161 #define XSDIRX_VERSION_VER_REV_MASK GENMASK(15, 12)
162 #define XSDIRX_VERSION_VER_MIN_MASK GENMASK(23, 16)
163 #define XSDIRX_VERSION_VER_MAJ_MASK GENMASK(31, 24)
165 #define XSDIRX_SS_CONFIG_EDH_INCLUDED_MASK BIT(1)
167 #define XSDIRX_STAT_SB_RX_TDATA_CHANGE_DONE_MASK BIT(0)
168 #define XSDIRX_STAT_SB_RX_TDATA_CHANGE_FAIL_MASK BIT(1)
169 #define XSDIRX_STAT_SB_RX_TDATA_GT_RESETDONE_MASK BIT(2)
170 #define XSDIRX_STAT_SB_RX_TDATA_GT_BITRATE_MASK BIT(3)
172 #define XSDIRX_VID_LOCK_WINDOW_VAL_MASK GENMASK(15, 0)
174 /* Number of media pads */
175 #define XSDIRX_MEDIA_PADS (1)
177 #define XSDIRX_DEFAULT_WIDTH (1920)
178 #define XSDIRX_DEFAULT_HEIGHT (1080)
180 #define XSDIRX_MAX_STR_LENGTH 16
182 #define XSDIRXSS_SDI_STD_3G 0
183 #define XSDIRXSS_SDI_STD_6G 1
184 #define XSDIRXSS_SDI_STD_12G_8DS 2
186 #define XSDIRX_DEFAULT_VIDEO_LOCK_WINDOW 0x3000
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
196 * Maximum number of events per file handle.
198 #define XSDIRX_MAX_EVENTS (128)
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
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
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
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
243 #define XST352_BYTE3_ACT_LUMA_COUNT_MASK BIT(22)
244 #define XST352_BYTE3_ACT_LUMA_COUNT_OFFSET 22
247 * enum sdi_family_enc - SDI Transport Video Format Detected with Active Pixels
248 * @XSDIRX_SMPTE_ST_274: SMPTE ST 274 detected with AP 1920x1080
249 * @XSDIRX_SMPTE_ST_296: SMPTE ST 296 detected with AP 1280x720
250 * @XSDIRX_SMPTE_ST_2048_2: SMPTE ST 2048-2 detected with AP 2048x1080
251 * @XSDIRX_SMPTE_ST_295: SMPTE ST 295 detected with AP 1920x1080
252 * @XSDIRX_NTSC: NTSC encoding detected with AP 720x480
253 * @XSDIRX_PAL: PAL encoding detected with AP 720x576
254 * @XSDIRX_TS_UNKNOWN: Unknown SMPTE Transport family type
256 enum sdi_family_enc {
257 XSDIRX_SMPTE_ST_274 = 0,
258 XSDIRX_SMPTE_ST_296 = 1,
259 XSDIRX_SMPTE_ST_2048_2 = 2,
260 XSDIRX_SMPTE_ST_295 = 3,
263 XSDIRX_TS_UNKNOWN = 15
267 * struct xsdirxss_core - Core configuration SDI Rx Subsystem device structure
268 * @dev: Platform structure
269 * @iomem: Base address of subsystem
270 * @irq: requested irq number
271 * @include_edh: EDH processor presence
272 * @mode: 3G/6G/12G mode
274 struct xsdirxss_core {
283 * struct xsdirxss_state - SDI Rx Subsystem device structure
284 * @core: Core structure for MIPI SDI Rx Subsystem
285 * @subdev: The v4l2 subdev structure
286 * @ctrl_handler: control handler
287 * @event: Holds the video unlock event
288 * @formats: Active V4L2 formats on each pad
289 * @default_format: default V4L2 media bus format
290 * @vip_format: format information corresponding to the active format
292 * @streaming: Flag for storing streaming state
293 * @vidlocked: Flag indicating SDI Rx has locked onto video stream
295 * This structure contains the device driver related parameters
297 struct xsdirxss_state {
298 struct xsdirxss_core core;
299 struct v4l2_subdev subdev;
300 struct v4l2_ctrl_handler ctrl_handler;
301 struct v4l2_event event;
302 struct v4l2_mbus_framefmt formats[XSDIRX_MEDIA_PADS];
303 struct v4l2_mbus_framefmt default_format;
304 const struct xvip_video_format *vip_format;
305 struct media_pad pads[XSDIRX_MEDIA_PADS];
310 static inline struct xsdirxss_state *
311 to_xsdirxssstate(struct v4l2_subdev *subdev)
313 return container_of(subdev, struct xsdirxss_state, subdev);
317 * Register related operations
319 static inline u32 xsdirxss_read(struct xsdirxss_core *xsdirxss, u32 addr)
321 return ioread32(xsdirxss->iomem + addr);
324 static inline void xsdirxss_write(struct xsdirxss_core *xsdirxss, u32 addr,
327 iowrite32(value, xsdirxss->iomem + addr);
330 static inline void xsdirxss_clr(struct xsdirxss_core *xsdirxss, u32 addr,
333 xsdirxss_write(xsdirxss, addr, xsdirxss_read(xsdirxss, addr) & ~clr);
336 static inline void xsdirxss_set(struct xsdirxss_core *xsdirxss, u32 addr,
339 xsdirxss_write(xsdirxss, addr, xsdirxss_read(xsdirxss, addr) | set);
342 static void xsdirx_core_disable(struct xsdirxss_core *core)
344 xsdirxss_clr(core, XSDIRX_RST_CTRL_REG, XSDIRX_RST_CTRL_SS_EN_MASK);
347 static void xsdirx_core_enable(struct xsdirxss_core *core)
349 xsdirxss_set(core, XSDIRX_RST_CTRL_REG, XSDIRX_RST_CTRL_SS_EN_MASK);
352 static int xsdirx_set_modedetect(struct xsdirxss_core *core, u16 mask)
356 mask &= XSDIRX_DETECT_ALL_MODES;
358 dev_err(core->dev, "Invalid bit mask = 0x%08x\n", mask);
362 dev_dbg(core->dev, "mask = 0x%x\n", mask);
364 val = xsdirxss_read(core, XSDIRX_MDL_CTRL_REG);
365 val &= ~(XSDIRX_MDL_CTRL_MODE_DET_EN_MASK);
366 val &= ~(XSDIRX_MDL_CTRL_MODE_AUTO_DET_MASK);
367 val &= ~(XSDIRX_MDL_CTRL_FORCED_MODE_MASK);
369 if (hweight16(mask) > 1) {
370 /* Multi mode detection as more than 1 bit set in mask */
371 dev_dbg(core->dev, "Detect multiple modes\n");
372 for (i = 0; i < XSDIRX_MODE_NUM_SUPPORTED; i++) {
373 switch (mask & (1 << i)) {
374 case BIT(XSDIRX_MODE_SD_OFFSET):
375 val |= XSDIRX_MDL_CTRL_MODE_SD_EN_MASK;
377 case BIT(XSDIRX_MODE_HD_OFFSET):
378 val |= XSDIRX_MDL_CTRL_MODE_HD_EN_MASK;
380 case BIT(XSDIRX_MODE_3G_OFFSET):
381 val |= XSDIRX_MDL_CTRL_MODE_3G_EN_MASK;
383 case BIT(XSDIRX_MODE_6G_OFFSET):
384 val |= XSDIRX_MDL_CTRL_MODE_6G_EN_MASK;
386 case BIT(XSDIRX_MODE_12GI_OFFSET):
387 val |= XSDIRX_MDL_CTRL_MODE_12GI_EN_MASK;
389 case BIT(XSDIRX_MODE_12GF_OFFSET):
390 val |= XSDIRX_MDL_CTRL_MODE_12GF_EN_MASK;
394 val |= XSDIRX_MDL_CTRL_MODE_DET_EN_MASK;
397 u32 forced_mode_mask = 0;
399 dev_dbg(core->dev, "Detect fixed mode\n");
401 /* Find offset of first bit set */
402 switch (__ffs(mask)) {
403 case XSDIRX_MODE_SD_OFFSET:
404 forced_mode_mask = XSDIRX_MODE_SD_MASK;
406 case XSDIRX_MODE_HD_OFFSET:
407 forced_mode_mask = XSDIRX_MODE_HD_MASK;
409 case XSDIRX_MODE_3G_OFFSET:
410 forced_mode_mask = XSDIRX_MODE_3G_MASK;
412 case XSDIRX_MODE_6G_OFFSET:
413 forced_mode_mask = XSDIRX_MODE_6G_MASK;
415 case XSDIRX_MODE_12GI_OFFSET:
416 forced_mode_mask = XSDIRX_MODE_12GI_MASK;
418 case XSDIRX_MODE_12GF_OFFSET:
419 forced_mode_mask = XSDIRX_MODE_12GF_MASK;
422 dev_dbg(core->dev, "Forced Mode Mask : 0x%x\n",
424 val |= forced_mode_mask << XSDIRX_MDL_CTRL_FORCED_MODE_OFFSET;
427 dev_dbg(core->dev, "Modes to be detected : sdi ctrl reg = 0x%08x\n",
429 xsdirxss_write(core, XSDIRX_MDL_CTRL_REG, val);
434 static void xsdirx_framer(struct xsdirxss_core *core, bool flag)
437 xsdirxss_set(core, XSDIRX_MDL_CTRL_REG,
438 XSDIRX_MDL_CTRL_FRM_EN_MASK);
440 xsdirxss_clr(core, XSDIRX_MDL_CTRL_REG,
441 XSDIRX_MDL_CTRL_FRM_EN_MASK);
444 static void xsdirx_setedherrcnttrigger(struct xsdirxss_core *core, u32 enable)
446 u32 val = xsdirxss_read(core, XSDIRX_EDH_ERRCNT_EN_REG);
448 val = enable & XSDIRX_EDH_ALLERR_MASK;
450 xsdirxss_write(core, XSDIRX_EDH_ERRCNT_EN_REG, val);
453 static void xsdirx_setvidlockwindow(struct xsdirxss_core *core, u32 val)
456 * The video lock window is the amount of time for which the
457 * the mode and transport stream should be locked to get the
458 * video lock interrupt.
460 xsdirxss_write(core, XSDIRX_VID_LOCK_WINDOW_REG,
461 val & XSDIRX_VID_LOCK_WINDOW_VAL_MASK);
464 static void xsdirx_disableintr(struct xsdirxss_core *core, u32 mask)
466 xsdirxss_clr(core, XSDIRX_IER_REG, mask);
469 static void xsdirx_enableintr(struct xsdirxss_core *core, u32 mask)
471 xsdirxss_set(core, XSDIRX_IER_REG, mask);
474 static void xsdirx_globalintr(struct xsdirxss_core *core, bool flag)
477 xsdirxss_set(core, XSDIRX_GLBL_IER_REG,
478 XSDIRX_GLBL_INTR_EN_MASK);
480 xsdirxss_clr(core, XSDIRX_GLBL_IER_REG,
481 XSDIRX_GLBL_INTR_EN_MASK);
484 static void xsdirx_clearintr(struct xsdirxss_core *core, u32 mask)
486 xsdirxss_set(core, XSDIRX_ISR_REG, mask);
489 static void xsdirx_vid_bridge_control(struct xsdirxss_core *core, bool enable)
492 xsdirxss_set(core, XSDIRX_RST_CTRL_REG,
493 XSDIRX_RST_CTRL_SDIRX_BRIDGE_ENB_MASK);
495 xsdirxss_clr(core, XSDIRX_RST_CTRL_REG,
496 XSDIRX_RST_CTRL_SDIRX_BRIDGE_ENB_MASK);
499 static void xsdirx_axis4_bridge_control(struct xsdirxss_core *core, bool enable)
502 xsdirxss_set(core, XSDIRX_RST_CTRL_REG,
503 XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK);
505 xsdirxss_clr(core, XSDIRX_RST_CTRL_REG,
506 XSDIRX_RST_CTRL_VIDIN_AXI4S_MOD_ENB_MASK);
509 static void xsdirx_streamflow_control(struct xsdirxss_core *core, bool enable)
511 /* The sdi to native bridge is followed by native to axis4 bridge */
513 xsdirx_axis4_bridge_control(core, enable);
514 xsdirx_vid_bridge_control(core, enable);
516 xsdirx_vid_bridge_control(core, enable);
517 xsdirx_axis4_bridge_control(core, enable);
521 static void xsdirx_streamdowncb(struct xsdirxss_core *core)
523 xsdirx_streamflow_control(core, false);
527 * xsdirx_get_stream_properties - Get SDI Rx stream properties
528 * @state: pointer to driver state
530 * This function decodes the stream's ST352 payload (if available) to get
531 * stream properties like width, height, picture type (interlaced/progressive),
534 * Return: 0 for success else errors
536 static int xsdirx_get_stream_properties(struct xsdirxss_state *state)
538 struct xsdirxss_core *core = &state->core;
539 u32 mode, payload = 0, val, family, valid, trate, tscan;
540 u8 byte1 = 0, active_luma = 0, pic_type = 0;
541 struct v4l2_mbus_framefmt *format = &state->formats[0];
543 mode = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
544 mode &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
546 valid = xsdirxss_read(core, XSDIRX_ST352_VALID_REG);
548 if ((mode >= XSDIRX_MODE_3G_MASK) && !valid) {
549 dev_err(core->dev, "No valid ST352 payload present even for 3G mode and above\n");
553 if (valid & XSDIRX_ST352_VALID_DS1_MASK) {
554 payload = xsdirxss_read(core, XSDIRX_ST352_DS1_REG);
555 byte1 = (payload >> XST352_PAYLOAD_BYTE1_SHIFT) &
556 XST352_PAYLOAD_BYTE_MASK;
557 active_luma = (payload & XST352_BYTE3_ACT_LUMA_COUNT_MASK) >>
558 XST352_BYTE3_ACT_LUMA_COUNT_OFFSET;
559 pic_type = (payload & XST352_BYTE2_PIC_TYPE_MASK) >>
560 XST352_BYTE2_PIC_TYPE_OFFSET;
562 dev_dbg(core->dev, "No ST352 payload available : Mode = %d\n",
566 val = xsdirxss_read(core, XSDIRX_TS_DET_STAT_REG);
567 family = (val & XSDIRX_TS_DET_STAT_FAMILY_MASK) >>
568 XSDIRX_TS_DET_STAT_FAMILY_OFFSET;
569 trate = (val & XSDIRX_TS_DET_STAT_RATE_MASK) >>
570 XSDIRX_TS_DET_STAT_RATE_OFFSET;
571 tscan = (val & XSDIRX_TS_DET_STAT_SCAN_MASK) >>
572 XSDIRX_TS_DET_STAT_SCAN_OFFSET;
575 case XSDIRX_MODE_HD_MASK:
577 /* No payload obtained */
578 dev_dbg(core->dev, "frame rate : %d, tscan = %d\n",
581 * NOTE : A progressive segmented frame pSF will be
582 * reported incorrectly as Interlaced as we rely on IP's
583 * transport scan locked bit.
585 dev_warn(core->dev, "pSF will be incorrectly reported as Interlaced\n");
588 case XSDIRX_TS_DET_STAT_RATE_23_98HZ:
589 case XSDIRX_TS_DET_STAT_RATE_24HZ:
590 case XSDIRX_TS_DET_STAT_RATE_25HZ:
591 case XSDIRX_TS_DET_STAT_RATE_29_97HZ:
592 case XSDIRX_TS_DET_STAT_RATE_30HZ:
593 if (family == XSDIRX_SMPTE_ST_296) {
594 format->width = 1280;
595 format->height = 720;
596 format->field = V4L2_FIELD_NONE;
597 } else if (family == XSDIRX_SMPTE_ST_2048_2) {
598 format->width = 2048;
599 format->height = 1080;
601 format->field = V4L2_FIELD_NONE;
604 V4L2_FIELD_INTERLACED;
606 format->width = 1920;
607 format->height = 1080;
609 format->field = V4L2_FIELD_NONE;
612 V4L2_FIELD_INTERLACED;
615 case XSDIRX_TS_DET_STAT_RATE_50HZ:
616 case XSDIRX_TS_DET_STAT_RATE_59_94HZ:
617 case XSDIRX_TS_DET_STAT_RATE_60HZ:
618 if (family == XSDIRX_SMPTE_ST_274) {
619 format->width = 1920;
620 format->height = 1080;
622 format->width = 1280;
623 format->height = 720;
625 format->field = V4L2_FIELD_NONE;
628 format->width = 1920;
629 format->height = 1080;
630 format->field = V4L2_FIELD_NONE;
633 dev_dbg(core->dev, "Got the payload\n");
635 case XST352_BYTE1_ST292_1x720L_1_5G:
636 /* SMPTE ST 292-1 for 720 line payloads */
637 format->width = 1280;
638 format->height = 720;
640 case XST352_BYTE1_ST292_1x1080L_1_5G:
641 /* SMPTE ST 292-1 for 1080 line payloads */
642 format->height = 1080;
644 format->width = 2048;
646 format->width = 1920;
649 dev_dbg(core->dev, "Unknown HD Mode SMPTE standard\n");
654 case XSDIRX_MODE_SD_MASK:
655 format->field = V4L2_FIELD_INTERLACED;
660 format->height = 480;
664 format->height = 576;
667 dev_dbg(core->dev, "Unknown SD Mode SMPTE standard\n");
671 case XSDIRX_MODE_3G_MASK:
673 case XST352_BYTE1_ST425_2008_750L_3GB:
674 /* Sec 4.1.6.1 SMPTE 425-2008 */
675 case XST352_BYTE1_ST372_2x720L_3GB:
676 /* Table 13 SMPTE 425-2008 */
677 format->width = 1280;
678 format->height = 720;
680 case XST352_BYTE1_ST425_2008_1125L_3GA:
681 /* ST352 Table SMPTE 425-1 */
682 case XST352_BYTE1_ST372_DL_3GB:
683 /* Table 13 SMPTE 425-2008 */
684 case XST352_BYTE1_ST372_2x1080L_3GB:
685 /* Table 13 SMPTE 425-2008 */
686 format->height = 1080;
688 format->width = 2048;
690 format->width = 1920;
693 dev_dbg(core->dev, "Unknown 3G Mode SMPTE standard\n");
697 case XSDIRX_MODE_6G_MASK:
699 case XST352_BYTE1_ST2081_10_DL_2160L_6G:
701 case XST352_BYTE1_ST2081_10_2160L_6G:
702 /* Table 3 SMPTE ST 2081-10 */
703 format->height = 2160;
705 format->width = 4096;
707 format->width = 3840;
710 dev_dbg(core->dev, "Unknown 6G Mode SMPTE standard\n");
714 case XSDIRX_MODE_12GI_MASK:
715 case XSDIRX_MODE_12GF_MASK:
717 case XST352_BYTE1_ST2082_10_2160L_12G:
718 /* Section 4.3.1 SMPTE ST 2082-10 */
719 format->height = 2160;
721 format->width = 4096;
723 format->width = 3840;
726 dev_dbg(core->dev, "Unknown 12G Mode SMPTE standard\n");
731 dev_err(core->dev, "Invalid Mode\n");
737 format->field = V4L2_FIELD_NONE;
739 format->field = V4L2_FIELD_INTERLACED;
742 dev_dbg(core->dev, "Stream width = %d height = %d Field = %d payload = 0x%08x ts = 0x%08x\n",
743 format->width, format->height, format->field, payload, val);
749 * xsdirxss_irq_handler - Interrupt handler for SDI Rx
751 * @dev_id: Pointer to device state
753 * The SDI Rx interrupts are cleared by first setting and then clearing the bits
754 * in the interrupt clear register. The interrupt status register is read only.
756 * Return: IRQ_HANDLED after handling interrupts
758 static irqreturn_t xsdirxss_irq_handler(int irq, void *dev_id)
760 struct xsdirxss_state *state = (struct xsdirxss_state *)dev_id;
761 struct xsdirxss_core *core = &state->core;
764 status = xsdirxss_read(core, XSDIRX_ISR_REG);
765 dev_dbg(core->dev, "interrupt status = 0x%08x\n", status);
770 if (status & XSDIRX_INTR_VIDLOCK_MASK) {
773 dev_dbg(core->dev, "video lock interrupt\n");
774 xsdirx_clearintr(core, XSDIRX_INTR_VIDLOCK_MASK);
776 val1 = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
777 val2 = xsdirxss_read(core, XSDIRX_TS_DET_STAT_REG);
779 if ((val1 & XSDIRX_MODE_DET_STAT_MODE_LOCK_MASK) &&
780 (val2 & XSDIRX_TS_DET_STAT_LOCKED_MASK)) {
781 u32 mask = XSDIRX_RST_CTRL_RST_CRC_ERRCNT_MASK |
782 XSDIRX_RST_CTRL_RST_EDH_ERRCNT_MASK;
784 dev_dbg(core->dev, "mode & ts lock occurred\n");
786 xsdirxss_set(core, XSDIRX_RST_CTRL_REG, mask);
787 xsdirxss_clr(core, XSDIRX_RST_CTRL_REG, mask);
789 val1 = xsdirxss_read(core, XSDIRX_ST352_VALID_REG);
790 val2 = xsdirxss_read(core, XSDIRX_ST352_DS1_REG);
792 dev_dbg(core->dev, "valid st352 mask = 0x%08x\n", val1);
793 dev_dbg(core->dev, "st352 payload = 0x%08x\n", val2);
795 if (!xsdirx_get_stream_properties(state)) {
796 memset(&state->event, 0, sizeof(state->event));
797 state->event.type = V4L2_EVENT_SOURCE_CHANGE;
798 state->event.u.src_change.changes =
799 V4L2_EVENT_SRC_CH_RESOLUTION;
800 v4l2_subdev_notify_event(&state->subdev,
803 state->vidlocked = true;
805 dev_err(core->dev, "Unable to get stream properties!\n");
806 state->vidlocked = false;
809 dev_dbg(core->dev, "video unlock before video lock!\n");
810 state->vidlocked = false;
814 if (status & XSDIRX_INTR_VIDUNLOCK_MASK) {
815 dev_dbg(core->dev, "video unlock interrupt\n");
816 xsdirx_clearintr(core, XSDIRX_INTR_VIDUNLOCK_MASK);
817 xsdirx_streamdowncb(core);
819 memset(&state->event, 0, sizeof(state->event));
820 state->event.type = V4L2_EVENT_XLNXSDIRX_VIDUNLOCK;
821 v4l2_subdev_notify_event(&state->subdev, &state->event);
823 state->vidlocked = false;
826 if (status & XSDIRX_INTR_UNDERFLOW_MASK) {
827 dev_dbg(core->dev, "Video in to AXI4 Stream core underflow interrupt\n");
828 xsdirx_clearintr(core, XSDIRX_INTR_UNDERFLOW_MASK);
830 memset(&state->event, 0, sizeof(state->event));
831 state->event.type = V4L2_EVENT_XLNXSDIRX_UNDERFLOW;
832 v4l2_subdev_notify_event(&state->subdev, &state->event);
835 if (status & XSDIRX_INTR_OVERFLOW_MASK) {
836 dev_dbg(core->dev, "Video in to AXI4 Stream core overflow interrupt\n");
837 xsdirx_clearintr(core, XSDIRX_INTR_OVERFLOW_MASK);
839 memset(&state->event, 0, sizeof(state->event));
840 state->event.type = V4L2_EVENT_XLNXSDIRX_OVERFLOW;
841 v4l2_subdev_notify_event(&state->subdev, &state->event);
847 * xsdirxss_subscribe_event - Subscribe to video lock and unlock event
848 * @sd: V4L2 Sub device
849 * @fh: V4L2 File Handle
850 * @sub: Subcribe event structure
852 * Return: 0 on success, errors otherwise
854 static int xsdirxss_subscribe_event(struct v4l2_subdev *sd,
856 struct v4l2_event_subscription *sub)
859 struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
860 struct xsdirxss_core *core = &xsdirxss->core;
863 case V4L2_EVENT_XLNXSDIRX_VIDUNLOCK:
864 case V4L2_EVENT_XLNXSDIRX_UNDERFLOW:
865 case V4L2_EVENT_XLNXSDIRX_OVERFLOW:
866 ret = v4l2_event_subscribe(fh, sub, XSDIRX_MAX_EVENTS, NULL);
868 case V4L2_EVENT_SOURCE_CHANGE:
869 ret = v4l2_src_change_event_subscribe(fh, sub);
874 dev_dbg(core->dev, "Event subscribed : 0x%08x\n", sub->type);
879 * xsdirxss_unsubscribe_event - Unsubscribe from all events registered
880 * @sd: V4L2 Sub device
881 * @fh: V4L2 file handle
882 * @sub: pointer to Event unsubscription structure
884 * Return: zero on success, else a negative error code.
886 static int xsdirxss_unsubscribe_event(struct v4l2_subdev *sd,
888 struct v4l2_event_subscription *sub)
890 struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
891 struct xsdirxss_core *core = &xsdirxss->core;
893 dev_dbg(core->dev, "Event unsubscribe : 0x%08x\n", sub->type);
894 return v4l2_event_unsubscribe(fh, sub);
898 * xsdirxss_s_ctrl - This is used to set the Xilinx SDI Rx V4L2 controls
899 * @ctrl: V4L2 control to be set
901 * This function is used to set the V4L2 controls for the Xilinx SDI Rx
904 * Return: 0 on success, errors otherwise
906 static int xsdirxss_s_ctrl(struct v4l2_ctrl *ctrl)
909 struct xsdirxss_state *xsdirxss =
910 container_of(ctrl->handler,
911 struct xsdirxss_state, ctrl_handler);
912 struct xsdirxss_core *core = &xsdirxss->core;
914 dev_dbg(core->dev, "set ctrl id = 0x%08x val = 0x%08x\n",
915 ctrl->id, ctrl->val);
917 if (xsdirxss->streaming) {
918 dev_err(core->dev, "Cannot set controls while streaming\n");
922 xsdirx_core_disable(core);
924 case V4L2_CID_XILINX_SDIRX_FRAMER:
925 xsdirx_framer(core, ctrl->val);
927 case V4L2_CID_XILINX_SDIRX_VIDLOCK_WINDOW:
928 xsdirx_setvidlockwindow(core, ctrl->val);
930 case V4L2_CID_XILINX_SDIRX_EDH_ERRCNT_ENABLE:
931 xsdirx_setedherrcnttrigger(core, ctrl->val);
933 case V4L2_CID_XILINX_SDIRX_SEARCH_MODES:
935 if (core->mode == XSDIRXSS_SDI_STD_3G) {
936 dev_dbg(core->dev, "Upto 3G supported\n");
937 ctrl->val &= ~(BIT(XSDIRX_MODE_6G_OFFSET) |
938 BIT(XSDIRX_MODE_12GI_OFFSET) |
939 BIT(XSDIRX_MODE_12GF_OFFSET));
942 if (core->mode == XSDIRXSS_SDI_STD_6G) {
943 dev_dbg(core->dev, "Upto 6G supported\n");
944 ctrl->val &= ~(BIT(XSDIRX_MODE_12GI_OFFSET) |
945 BIT(XSDIRX_MODE_12GF_OFFSET));
948 ret = xsdirx_set_modedetect(core, ctrl->val);
950 dev_err(core->dev, "Select at least one mode!\n");
955 xsdirxss_set(core, XSDIRX_RST_CTRL_REG,
956 XSDIRX_RST_CTRL_SS_EN_MASK);
959 xsdirx_core_enable(core);
964 * xsdirxss_g_volatile_ctrl - get the Xilinx SDI Rx controls
965 * @ctrl: Pointer to V4L2 control
967 * Return: 0 on success, errors otherwise
969 static int xsdirxss_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
972 struct xsdirxss_state *xsdirxss =
973 container_of(ctrl->handler,
974 struct xsdirxss_state, ctrl_handler);
975 struct xsdirxss_core *core = &xsdirxss->core;
978 case V4L2_CID_XILINX_SDIRX_MODE_DETECT:
979 if (!xsdirxss->vidlocked) {
980 dev_err(core->dev, "Can't get values when video not locked!\n");
983 val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
984 val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
987 case XSDIRX_MODE_SD_MASK:
988 ctrl->val = XSDIRX_MODE_SD_OFFSET;
990 case XSDIRX_MODE_HD_MASK:
991 ctrl->val = XSDIRX_MODE_HD_OFFSET;
993 case XSDIRX_MODE_3G_MASK:
994 ctrl->val = XSDIRX_MODE_3G_OFFSET;
996 case XSDIRX_MODE_6G_MASK:
997 ctrl->val = XSDIRX_MODE_6G_OFFSET;
999 case XSDIRX_MODE_12GI_MASK:
1000 ctrl->val = XSDIRX_MODE_12GI_OFFSET;
1002 case XSDIRX_MODE_12GF_MASK:
1003 ctrl->val = XSDIRX_MODE_12GF_OFFSET;
1007 case V4L2_CID_XILINX_SDIRX_CRC:
1008 ctrl->val = xsdirxss_read(core, XSDIRX_CRC_ERRCNT_REG);
1009 xsdirxss_write(core, XSDIRX_CRC_ERRCNT_REG, 0xFFFF);
1011 case V4L2_CID_XILINX_SDIRX_EDH_ERRCNT:
1012 val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1013 val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
1014 if (val == XSDIRX_MODE_SD_MASK) {
1015 ctrl->val = xsdirxss_read(core, XSDIRX_EDH_ERRCNT_REG);
1017 dev_dbg(core->dev, "%d - not in SD mode\n", ctrl->id);
1021 case V4L2_CID_XILINX_SDIRX_EDH_STATUS:
1022 val = xsdirxss_read(core, XSDIRX_MODE_DET_STAT_REG);
1023 val &= XSDIRX_MODE_DET_STAT_RX_MODE_MASK;
1024 if (val == XSDIRX_MODE_SD_MASK) {
1025 ctrl->val = xsdirxss_read(core, XSDIRX_EDH_STAT_REG);
1027 dev_dbg(core->dev, "%d - not in SD mode\n", ctrl->id);
1032 dev_err(core->dev, "Get Invalid control id 0x%0x\n", ctrl->id);
1035 dev_dbg(core->dev, "Get ctrl id = 0x%08x val = 0x%08x\n",
1036 ctrl->id, ctrl->val);
1041 * xsdirxss_log_status - Logs the status of the SDI Rx Subsystem
1042 * @sd: Pointer to V4L2 subdevice structure
1044 * This function prints the current status of Xilinx SDI Rx Subsystem
1046 * Return: 0 on success
1048 static int xsdirxss_log_status(struct v4l2_subdev *sd)
1050 struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1051 struct xsdirxss_core *core = &xsdirxss->core;
1054 v4l2_info(sd, "***** SDI Rx subsystem reg dump start *****\n");
1055 for (i = 0; i < 0x28; i++) {
1056 data = xsdirxss_read(core, i * 4);
1057 v4l2_info(sd, "offset 0x%08x data 0x%08x\n",
1060 v4l2_info(sd, "***** SDI Rx subsystem reg dump end *****\n");
1064 static void xsdirxss_start_stream(struct xsdirxss_state *xsdirxss)
1066 xsdirx_streamflow_control(&xsdirxss->core, true);
1069 static void xsdirxss_stop_stream(struct xsdirxss_state *xsdirxss)
1071 xsdirx_streamflow_control(&xsdirxss->core, false);
1075 * xsdirxss_s_stream - It is used to start/stop the streaming.
1076 * @sd: V4L2 Sub device
1077 * @enable: Flag (True / False)
1079 * This function controls the start or stop of streaming for the
1080 * Xilinx SDI Rx Subsystem.
1082 * Return: 0 on success, errors otherwise
1084 static int xsdirxss_s_stream(struct v4l2_subdev *sd, int enable)
1086 struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1087 struct xsdirxss_core *core = &xsdirxss->core;
1090 if (!xsdirxss->vidlocked) {
1091 dev_dbg(core->dev, "Video is not locked\n");
1094 if (xsdirxss->streaming) {
1095 dev_dbg(core->dev, "Already streaming\n");
1099 xsdirxss_start_stream(xsdirxss);
1100 xsdirxss->streaming = true;
1101 dev_dbg(core->dev, "Streaming started\n");
1103 if (!xsdirxss->streaming) {
1104 dev_dbg(core->dev, "Stopped streaming already\n");
1108 xsdirxss_stop_stream(xsdirxss);
1109 xsdirxss->streaming = false;
1110 dev_dbg(core->dev, "Streaming stopped\n");
1116 static struct v4l2_mbus_framefmt *
1117 __xsdirxss_get_pad_format(struct xsdirxss_state *xsdirxss,
1118 struct v4l2_subdev_pad_config *cfg,
1119 unsigned int pad, u32 which)
1122 case V4L2_SUBDEV_FORMAT_TRY:
1123 return v4l2_subdev_get_try_format(&xsdirxss->subdev, cfg, pad);
1124 case V4L2_SUBDEV_FORMAT_ACTIVE:
1125 return &xsdirxss->formats[pad];
1132 * xsdirxss_get_format - Get the pad format
1133 * @sd: Pointer to V4L2 Sub device structure
1134 * @cfg: Pointer to sub device pad information structure
1135 * @fmt: Pointer to pad level media bus format
1137 * This function is used to get the pad format information.
1139 * Return: 0 on success
1141 static int xsdirxss_get_format(struct v4l2_subdev *sd,
1142 struct v4l2_subdev_pad_config *cfg,
1143 struct v4l2_subdev_format *fmt)
1145 struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1146 struct xsdirxss_core *core = &xsdirxss->core;
1148 if (!xsdirxss->vidlocked) {
1149 dev_err(core->dev, "Video not locked!\n");
1153 fmt->format = *__xsdirxss_get_pad_format(xsdirxss, cfg,
1154 fmt->pad, fmt->which);
1156 dev_dbg(core->dev, "Stream width = %d height = %d Field = %d\n",
1157 fmt->format.width, fmt->format.height, fmt->format.field);
1163 * xsdirxss_set_format - This is used to set the pad format
1164 * @sd: Pointer to V4L2 Sub device structure
1165 * @cfg: Pointer to sub device pad information structure
1166 * @fmt: Pointer to pad level media bus format
1168 * This function is used to set the pad format.
1169 * Since the pad format is fixed in hardware, it can't be
1170 * modified on run time.
1172 * Return: 0 on success
1174 static int xsdirxss_set_format(struct v4l2_subdev *sd,
1175 struct v4l2_subdev_pad_config *cfg,
1176 struct v4l2_subdev_format *fmt)
1178 struct v4l2_mbus_framefmt *__format;
1179 struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1181 dev_dbg(xsdirxss->core.dev,
1182 "set width %d height %d code %d field %d colorspace %d\n",
1183 fmt->format.width, fmt->format.height,
1184 fmt->format.code, fmt->format.field,
1185 fmt->format.colorspace);
1187 __format = __xsdirxss_get_pad_format(xsdirxss, cfg,
1188 fmt->pad, fmt->which);
1190 /* Currently reset the code to one fixed in hardware */
1191 /* TODO : Add checks for width height */
1192 fmt->format.code = __format->code;
1198 * xsdirxss_open - Called on v4l2_open()
1199 * @sd: Pointer to V4L2 sub device structure
1200 * @fh: Pointer to V4L2 File handle
1202 * This function is called on v4l2_open(). It sets the default format for pad.
1204 * Return: 0 on success
1206 static int xsdirxss_open(struct v4l2_subdev *sd,
1207 struct v4l2_subdev_fh *fh)
1209 struct v4l2_mbus_framefmt *format;
1210 struct xsdirxss_state *xsdirxss = to_xsdirxssstate(sd);
1212 format = v4l2_subdev_get_try_format(sd, fh->pad, 0);
1213 *format = xsdirxss->default_format;
1219 * xsdirxss_close - Called on v4l2_close()
1220 * @sd: Pointer to V4L2 sub device structure
1221 * @fh: Pointer to V4L2 File handle
1223 * This function is called on v4l2_close().
1225 * Return: 0 on success
1227 static int xsdirxss_close(struct v4l2_subdev *sd,
1228 struct v4l2_subdev_fh *fh)
1233 /* -----------------------------------------------------------------------------
1237 static const struct media_entity_operations xsdirxss_media_ops = {
1238 .link_validate = v4l2_subdev_link_validate
1241 static const struct v4l2_ctrl_ops xsdirxss_ctrl_ops = {
1242 .g_volatile_ctrl = xsdirxss_g_volatile_ctrl,
1243 .s_ctrl = xsdirxss_s_ctrl
1246 static struct v4l2_ctrl_config xsdirxss_edh_ctrls[] = {
1248 .ops = &xsdirxss_ctrl_ops,
1249 .id = V4L2_CID_XILINX_SDIRX_EDH_ERRCNT_ENABLE,
1250 .name = "SDI Rx : EDH Error Count Enable",
1251 .type = V4L2_CTRL_TYPE_BITMASK,
1253 .max = XSDIRX_EDH_ALLERR_MASK,
1256 .ops = &xsdirxss_ctrl_ops,
1257 .id = V4L2_CID_XILINX_SDIRX_EDH_ERRCNT,
1258 .name = "SDI Rx : EDH Error Count",
1259 .type = V4L2_CTRL_TYPE_INTEGER,
1264 .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
1266 .ops = &xsdirxss_ctrl_ops,
1267 .id = V4L2_CID_XILINX_SDIRX_EDH_STATUS,
1268 .name = "SDI Rx : EDH Status",
1269 .type = V4L2_CTRL_TYPE_INTEGER,
1274 .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
1278 static struct v4l2_ctrl_config xsdirxss_ctrls[] = {
1280 .ops = &xsdirxss_ctrl_ops,
1281 .id = V4L2_CID_XILINX_SDIRX_FRAMER,
1282 .name = "SDI Rx : Enable Framer",
1283 .type = V4L2_CTRL_TYPE_BOOLEAN,
1289 .ops = &xsdirxss_ctrl_ops,
1290 .id = V4L2_CID_XILINX_SDIRX_VIDLOCK_WINDOW,
1291 .name = "SDI Rx : Video Lock Window",
1292 .type = V4L2_CTRL_TYPE_INTEGER,
1296 .def = XSDIRX_DEFAULT_VIDEO_LOCK_WINDOW,
1298 .ops = &xsdirxss_ctrl_ops,
1299 .id = V4L2_CID_XILINX_SDIRX_SEARCH_MODES,
1300 .name = "SDI Rx : Modes search Mask",
1301 .type = V4L2_CTRL_TYPE_BITMASK,
1303 .max = XSDIRX_DETECT_ALL_MODES,
1304 .def = XSDIRX_DETECT_ALL_MODES,
1306 .ops = &xsdirxss_ctrl_ops,
1307 .id = V4L2_CID_XILINX_SDIRX_MODE_DETECT,
1308 .name = "SDI Rx : Mode Detect Status",
1309 .type = V4L2_CTRL_TYPE_INTEGER,
1310 .min = XSDIRX_MODE_SD_OFFSET,
1311 .max = XSDIRX_MODE_12GF_OFFSET,
1313 .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
1315 .ops = &xsdirxss_ctrl_ops,
1316 .id = V4L2_CID_XILINX_SDIRX_CRC,
1317 .name = "SDI Rx : CRC Error status",
1318 .type = V4L2_CTRL_TYPE_INTEGER,
1323 .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
1327 static const struct v4l2_subdev_core_ops xsdirxss_core_ops = {
1328 .log_status = xsdirxss_log_status,
1329 .subscribe_event = xsdirxss_subscribe_event,
1330 .unsubscribe_event = xsdirxss_unsubscribe_event
1333 static struct v4l2_subdev_video_ops xsdirxss_video_ops = {
1334 .s_stream = xsdirxss_s_stream
1337 static struct v4l2_subdev_pad_ops xsdirxss_pad_ops = {
1338 .get_fmt = xsdirxss_get_format,
1339 .set_fmt = xsdirxss_set_format,
1342 static struct v4l2_subdev_ops xsdirxss_ops = {
1343 .core = &xsdirxss_core_ops,
1344 .video = &xsdirxss_video_ops,
1345 .pad = &xsdirxss_pad_ops
1348 static const struct v4l2_subdev_internal_ops xsdirxss_internal_ops = {
1349 .open = xsdirxss_open,
1350 .close = xsdirxss_close
1353 /* -----------------------------------------------------------------------------
1354 * Platform Device Driver
1357 static int xsdirxss_parse_of(struct xsdirxss_state *xsdirxss)
1359 struct device_node *node = xsdirxss->core.dev->of_node;
1360 struct device_node *ports = NULL;
1361 struct device_node *port = NULL;
1362 unsigned int nports = 0;
1363 struct xsdirxss_core *core = &xsdirxss->core;
1365 const char *sdi_std;
1367 core->include_edh = of_property_read_bool(node, "xlnx,include-edh");
1368 dev_dbg(core->dev, "EDH property = %s\n",
1369 core->include_edh ? "Present" : "Absent");
1371 ret = of_property_read_string(node, "xlnx,line-rate",
1374 dev_err(core->dev, "xlnx,line-rate property not found\n");
1378 if (!strncmp(sdi_std, "12G_SDI_8DS", XSDIRX_MAX_STR_LENGTH)) {
1379 core->mode = XSDIRXSS_SDI_STD_12G_8DS;
1380 } else if (!strncmp(sdi_std, "6G_SDI", XSDIRX_MAX_STR_LENGTH)) {
1381 core->mode = XSDIRXSS_SDI_STD_6G;
1382 } else if (!strncmp(sdi_std, "3G_SDI", XSDIRX_MAX_STR_LENGTH)) {
1383 core->mode = XSDIRXSS_SDI_STD_3G;
1385 dev_err(core->dev, "Invalid Line Rate\n");
1388 dev_dbg(core->dev, "SDI Rx Line Rate = %s, mode = %d\n", sdi_std,
1391 ports = of_get_child_by_name(node, "ports");
1395 for_each_child_of_node(ports, port) {
1396 const struct xvip_video_format *format;
1397 struct device_node *endpoint;
1399 if (!port->name || of_node_cmp(port->name, "port"))
1402 format = xvip_of_get_format(port);
1403 if (IS_ERR(format)) {
1404 dev_err(core->dev, "invalid format in DT");
1405 return PTR_ERR(format);
1408 dev_dbg(core->dev, "vf_code = %d bpc = %d bpp = %d\n",
1409 format->vf_code, format->width, format->bpp);
1411 if (format->vf_code != XVIP_VF_YUV_422) {
1412 dev_err(core->dev, "Incorrect UG934 video format set. Accepts only YUV422\n");
1415 xsdirxss->vip_format = format;
1417 endpoint = of_get_next_child(port, NULL);
1419 dev_err(core->dev, "No port at\n");
1423 /* Count the number of ports. */
1428 dev_err(core->dev, "invalid number of ports %u\n", nports);
1432 /* Register interrupt handler */
1433 core->irq = irq_of_parse_and_map(node, 0);
1435 ret = devm_request_irq(core->dev, core->irq, xsdirxss_irq_handler,
1436 IRQF_SHARED, "xilinx-sdirxss", xsdirxss);
1438 dev_err(core->dev, "Err = %d Interrupt handler reg failed!\n",
1446 static int xsdirxss_probe(struct platform_device *pdev)
1448 struct v4l2_subdev *subdev;
1449 struct xsdirxss_state *xsdirxss;
1450 struct xsdirxss_core *core;
1451 struct resource *res;
1453 unsigned int num_ctrls, num_edh_ctrls = 0, i;
1455 xsdirxss = devm_kzalloc(&pdev->dev, sizeof(*xsdirxss), GFP_KERNEL);
1459 xsdirxss->core.dev = &pdev->dev;
1460 core = &xsdirxss->core;
1462 ret = xsdirxss_parse_of(xsdirxss);
1466 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1467 xsdirxss->core.iomem = devm_ioremap_resource(xsdirxss->core.dev, res);
1468 if (IS_ERR(xsdirxss->core.iomem))
1469 return PTR_ERR(xsdirxss->core.iomem);
1471 /* Reset the core */
1472 xsdirx_streamflow_control(core, false);
1473 xsdirx_core_disable(core);
1474 xsdirx_clearintr(core, XSDIRX_INTR_ALL_MASK);
1475 xsdirx_disableintr(core, XSDIRX_INTR_ALL_MASK);
1476 xsdirx_enableintr(core, XSDIRX_INTR_ALL_MASK);
1477 xsdirx_globalintr(core, true);
1478 xsdirxss_write(core, XSDIRX_CRC_ERRCNT_REG, 0xFFFF);
1480 /* Initialize V4L2 subdevice and media entity */
1481 xsdirxss->pads[0].flags = MEDIA_PAD_FL_SOURCE;
1483 /* Initialize the default format */
1484 xsdirxss->default_format.code = xsdirxss->vip_format->code;
1485 xsdirxss->default_format.field = V4L2_FIELD_NONE;
1486 xsdirxss->default_format.colorspace = V4L2_COLORSPACE_DEFAULT;
1487 xsdirxss->default_format.width = XSDIRX_DEFAULT_WIDTH;
1488 xsdirxss->default_format.height = XSDIRX_DEFAULT_HEIGHT;
1490 xsdirxss->formats[0] = xsdirxss->default_format;
1492 /* Initialize V4L2 subdevice and media entity */
1493 subdev = &xsdirxss->subdev;
1494 v4l2_subdev_init(subdev, &xsdirxss_ops);
1496 subdev->dev = &pdev->dev;
1497 subdev->internal_ops = &xsdirxss_internal_ops;
1498 strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
1500 subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1502 subdev->entity.ops = &xsdirxss_media_ops;
1504 v4l2_set_subdevdata(subdev, xsdirxss);
1506 ret = media_entity_pads_init(&subdev->entity, 1, xsdirxss->pads);
1510 /* Initialise and register the controls */
1511 num_ctrls = ARRAY_SIZE(xsdirxss_ctrls);
1513 if (xsdirxss->core.include_edh)
1514 num_edh_ctrls = ARRAY_SIZE(xsdirxss_edh_ctrls);
1516 v4l2_ctrl_handler_init(&xsdirxss->ctrl_handler,
1517 (num_ctrls + num_edh_ctrls));
1519 for (i = 0; i < num_ctrls; i++) {
1520 struct v4l2_ctrl *ctrl;
1522 dev_dbg(xsdirxss->core.dev, "%d %s ctrl = 0x%x\n",
1523 i, xsdirxss_ctrls[i].name, xsdirxss_ctrls[i].id);
1525 ctrl = v4l2_ctrl_new_custom(&xsdirxss->ctrl_handler,
1526 &xsdirxss_ctrls[i], NULL);
1528 dev_dbg(xsdirxss->core.dev, "Failed to add %s ctrl\n",
1529 xsdirxss_ctrls[i].name);
1534 if (xsdirxss->core.include_edh) {
1535 for (i = 0; i < num_edh_ctrls; i++) {
1536 struct v4l2_ctrl *ctrl;
1538 dev_dbg(xsdirxss->core.dev, "%d %s ctrl = 0x%x\n",
1539 i, xsdirxss_edh_ctrls[i].name,
1540 xsdirxss_edh_ctrls[i].id);
1542 ctrl = v4l2_ctrl_new_custom(&xsdirxss->ctrl_handler,
1543 &xsdirxss_edh_ctrls[i],
1546 dev_dbg(xsdirxss->core.dev, "Failed to add %s ctrl\n",
1547 xsdirxss_edh_ctrls[i].name);
1552 dev_dbg(xsdirxss->core.dev, "Not registering the EDH controls as EDH is disabled in IP\n");
1555 if (xsdirxss->ctrl_handler.error) {
1556 dev_err(&pdev->dev, "failed to add controls\n");
1557 ret = xsdirxss->ctrl_handler.error;
1561 subdev->ctrl_handler = &xsdirxss->ctrl_handler;
1563 ret = v4l2_ctrl_handler_setup(&xsdirxss->ctrl_handler);
1565 dev_err(&pdev->dev, "failed to set controls\n");
1569 platform_set_drvdata(pdev, xsdirxss);
1571 ret = v4l2_async_register_subdev(subdev);
1573 dev_err(&pdev->dev, "failed to register subdev\n");
1577 xsdirxss->streaming = false;
1579 dev_info(xsdirxss->core.dev, "Xilinx SDI Rx Subsystem device found!\n");
1581 xsdirx_core_enable(core);
1585 v4l2_ctrl_handler_free(&xsdirxss->ctrl_handler);
1586 media_entity_cleanup(&subdev->entity);
1591 static int xsdirxss_remove(struct platform_device *pdev)
1593 struct xsdirxss_state *xsdirxss = platform_get_drvdata(pdev);
1594 struct v4l2_subdev *subdev = &xsdirxss->subdev;
1596 v4l2_async_unregister_subdev(subdev);
1597 v4l2_ctrl_handler_free(&xsdirxss->ctrl_handler);
1598 media_entity_cleanup(&subdev->entity);
1603 static const struct of_device_id xsdirxss_of_id_table[] = {
1604 { .compatible = "xlnx,v-smpte-uhdsdi-rx-ss" },
1607 MODULE_DEVICE_TABLE(of, xsdirxss_of_id_table);
1609 static struct platform_driver xsdirxss_driver = {
1611 .name = "xilinx-sdirxss",
1612 .of_match_table = xsdirxss_of_id_table,
1614 .probe = xsdirxss_probe,
1615 .remove = xsdirxss_remove,
1618 module_platform_driver(xsdirxss_driver);
1620 MODULE_AUTHOR("Vishal Sagar <vsagar@xilinx.com>");
1621 MODULE_DESCRIPTION("Xilinx SDI Rx Subsystem Driver");
1622 MODULE_LICENSE("GPL v2");