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