1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Xilinx Video IP Core
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2013-2015 Ideas on Board
6*4882a593Smuzhiyun * Copyright (C) 2013-2015 Xilinx, Inc.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
9*4882a593Smuzhiyun * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #ifndef __XILINX_VIP_H__
13*4882a593Smuzhiyun #define __XILINX_VIP_H__
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #include <linux/bitops.h>
16*4882a593Smuzhiyun #include <linux/io.h>
17*4882a593Smuzhiyun #include <media/v4l2-subdev.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun struct clk;
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun /*
22*4882a593Smuzhiyun * Minimum and maximum width and height common to most video IP cores. IP
23*4882a593Smuzhiyun * cores with different requirements must define their own values.
24*4882a593Smuzhiyun */
25*4882a593Smuzhiyun #define XVIP_MIN_WIDTH 32
26*4882a593Smuzhiyun #define XVIP_MAX_WIDTH 7680
27*4882a593Smuzhiyun #define XVIP_MIN_HEIGHT 32
28*4882a593Smuzhiyun #define XVIP_MAX_HEIGHT 7680
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun /*
31*4882a593Smuzhiyun * Pad IDs. IP cores with with multiple inputs or outputs should define
32*4882a593Smuzhiyun * their own values.
33*4882a593Smuzhiyun */
34*4882a593Smuzhiyun #define XVIP_PAD_SINK 0
35*4882a593Smuzhiyun #define XVIP_PAD_SOURCE 1
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /* Xilinx Video IP Control Registers */
38*4882a593Smuzhiyun #define XVIP_CTRL_CONTROL 0x0000
39*4882a593Smuzhiyun #define XVIP_CTRL_CONTROL_SW_ENABLE BIT(0)
40*4882a593Smuzhiyun #define XVIP_CTRL_CONTROL_REG_UPDATE BIT(1)
41*4882a593Smuzhiyun #define XVIP_CTRL_CONTROL_BYPASS BIT(4)
42*4882a593Smuzhiyun #define XVIP_CTRL_CONTROL_TEST_PATTERN BIT(5)
43*4882a593Smuzhiyun #define XVIP_CTRL_CONTROL_FRAME_SYNC_RESET BIT(30)
44*4882a593Smuzhiyun #define XVIP_CTRL_CONTROL_SW_RESET BIT(31)
45*4882a593Smuzhiyun #define XVIP_CTRL_STATUS 0x0004
46*4882a593Smuzhiyun #define XVIP_CTRL_STATUS_PROC_STARTED BIT(0)
47*4882a593Smuzhiyun #define XVIP_CTRL_STATUS_EOF BIT(1)
48*4882a593Smuzhiyun #define XVIP_CTRL_ERROR 0x0008
49*4882a593Smuzhiyun #define XVIP_CTRL_ERROR_SLAVE_EOL_EARLY BIT(0)
50*4882a593Smuzhiyun #define XVIP_CTRL_ERROR_SLAVE_EOL_LATE BIT(1)
51*4882a593Smuzhiyun #define XVIP_CTRL_ERROR_SLAVE_SOF_EARLY BIT(2)
52*4882a593Smuzhiyun #define XVIP_CTRL_ERROR_SLAVE_SOF_LATE BIT(3)
53*4882a593Smuzhiyun #define XVIP_CTRL_IRQ_ENABLE 0x000c
54*4882a593Smuzhiyun #define XVIP_CTRL_IRQ_ENABLE_PROC_STARTED BIT(0)
55*4882a593Smuzhiyun #define XVIP_CTRL_IRQ_EOF BIT(1)
56*4882a593Smuzhiyun #define XVIP_CTRL_VERSION 0x0010
57*4882a593Smuzhiyun #define XVIP_CTRL_VERSION_MAJOR_MASK (0xff << 24)
58*4882a593Smuzhiyun #define XVIP_CTRL_VERSION_MAJOR_SHIFT 24
59*4882a593Smuzhiyun #define XVIP_CTRL_VERSION_MINOR_MASK (0xff << 16)
60*4882a593Smuzhiyun #define XVIP_CTRL_VERSION_MINOR_SHIFT 16
61*4882a593Smuzhiyun #define XVIP_CTRL_VERSION_REVISION_MASK (0xf << 12)
62*4882a593Smuzhiyun #define XVIP_CTRL_VERSION_REVISION_SHIFT 12
63*4882a593Smuzhiyun #define XVIP_CTRL_VERSION_PATCH_MASK (0xf << 8)
64*4882a593Smuzhiyun #define XVIP_CTRL_VERSION_PATCH_SHIFT 8
65*4882a593Smuzhiyun #define XVIP_CTRL_VERSION_INTERNAL_MASK (0xff << 0)
66*4882a593Smuzhiyun #define XVIP_CTRL_VERSION_INTERNAL_SHIFT 0
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun /* Xilinx Video IP Timing Registers */
69*4882a593Smuzhiyun #define XVIP_ACTIVE_SIZE 0x0020
70*4882a593Smuzhiyun #define XVIP_ACTIVE_VSIZE_MASK (0x7ff << 16)
71*4882a593Smuzhiyun #define XVIP_ACTIVE_VSIZE_SHIFT 16
72*4882a593Smuzhiyun #define XVIP_ACTIVE_HSIZE_MASK (0x7ff << 0)
73*4882a593Smuzhiyun #define XVIP_ACTIVE_HSIZE_SHIFT 0
74*4882a593Smuzhiyun #define XVIP_ENCODING 0x0028
75*4882a593Smuzhiyun #define XVIP_ENCODING_NBITS_8 (0 << 4)
76*4882a593Smuzhiyun #define XVIP_ENCODING_NBITS_10 (1 << 4)
77*4882a593Smuzhiyun #define XVIP_ENCODING_NBITS_12 (2 << 4)
78*4882a593Smuzhiyun #define XVIP_ENCODING_NBITS_16 (3 << 4)
79*4882a593Smuzhiyun #define XVIP_ENCODING_NBITS_MASK (3 << 4)
80*4882a593Smuzhiyun #define XVIP_ENCODING_NBITS_SHIFT 4
81*4882a593Smuzhiyun #define XVIP_ENCODING_VIDEO_FORMAT_YUV422 (0 << 0)
82*4882a593Smuzhiyun #define XVIP_ENCODING_VIDEO_FORMAT_YUV444 (1 << 0)
83*4882a593Smuzhiyun #define XVIP_ENCODING_VIDEO_FORMAT_RGB (2 << 0)
84*4882a593Smuzhiyun #define XVIP_ENCODING_VIDEO_FORMAT_YUV420 (3 << 0)
85*4882a593Smuzhiyun #define XVIP_ENCODING_VIDEO_FORMAT_MASK (3 << 0)
86*4882a593Smuzhiyun #define XVIP_ENCODING_VIDEO_FORMAT_SHIFT 0
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun /**
89*4882a593Smuzhiyun * struct xvip_device - Xilinx Video IP device structure
90*4882a593Smuzhiyun * @subdev: V4L2 subdevice
91*4882a593Smuzhiyun * @dev: (OF) device
92*4882a593Smuzhiyun * @iomem: device I/O register space remapped to kernel virtual memory
93*4882a593Smuzhiyun * @clk: video core clock
94*4882a593Smuzhiyun * @saved_ctrl: saved control register for resume / suspend
95*4882a593Smuzhiyun */
96*4882a593Smuzhiyun struct xvip_device {
97*4882a593Smuzhiyun struct v4l2_subdev subdev;
98*4882a593Smuzhiyun struct device *dev;
99*4882a593Smuzhiyun void __iomem *iomem;
100*4882a593Smuzhiyun struct clk *clk;
101*4882a593Smuzhiyun u32 saved_ctrl;
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun /**
105*4882a593Smuzhiyun * struct xvip_video_format - Xilinx Video IP video format description
106*4882a593Smuzhiyun * @vf_code: AXI4 video format code
107*4882a593Smuzhiyun * @width: AXI4 format width in bits per component
108*4882a593Smuzhiyun * @pattern: CFA pattern for Mono/Sensor formats
109*4882a593Smuzhiyun * @code: media bus format code
110*4882a593Smuzhiyun * @bpp: bytes per pixel (when stored in memory)
111*4882a593Smuzhiyun * @fourcc: V4L2 pixel format FCC identifier
112*4882a593Smuzhiyun */
113*4882a593Smuzhiyun struct xvip_video_format {
114*4882a593Smuzhiyun unsigned int vf_code;
115*4882a593Smuzhiyun unsigned int width;
116*4882a593Smuzhiyun const char *pattern;
117*4882a593Smuzhiyun unsigned int code;
118*4882a593Smuzhiyun unsigned int bpp;
119*4882a593Smuzhiyun u32 fourcc;
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun const struct xvip_video_format *xvip_get_format_by_code(unsigned int code);
123*4882a593Smuzhiyun const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc);
124*4882a593Smuzhiyun const struct xvip_video_format *xvip_of_get_format(struct device_node *node);
125*4882a593Smuzhiyun void xvip_set_format_size(struct v4l2_mbus_framefmt *format,
126*4882a593Smuzhiyun const struct v4l2_subdev_format *fmt);
127*4882a593Smuzhiyun int xvip_enum_mbus_code(struct v4l2_subdev *subdev,
128*4882a593Smuzhiyun struct v4l2_subdev_pad_config *cfg,
129*4882a593Smuzhiyun struct v4l2_subdev_mbus_code_enum *code);
130*4882a593Smuzhiyun int xvip_enum_frame_size(struct v4l2_subdev *subdev,
131*4882a593Smuzhiyun struct v4l2_subdev_pad_config *cfg,
132*4882a593Smuzhiyun struct v4l2_subdev_frame_size_enum *fse);
133*4882a593Smuzhiyun
xvip_read(struct xvip_device * xvip,u32 addr)134*4882a593Smuzhiyun static inline u32 xvip_read(struct xvip_device *xvip, u32 addr)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun return ioread32(xvip->iomem + addr);
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun
xvip_write(struct xvip_device * xvip,u32 addr,u32 value)139*4882a593Smuzhiyun static inline void xvip_write(struct xvip_device *xvip, u32 addr, u32 value)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun iowrite32(value, xvip->iomem + addr);
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun
xvip_clr(struct xvip_device * xvip,u32 addr,u32 clr)144*4882a593Smuzhiyun static inline void xvip_clr(struct xvip_device *xvip, u32 addr, u32 clr)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun xvip_write(xvip, addr, xvip_read(xvip, addr) & ~clr);
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
xvip_set(struct xvip_device * xvip,u32 addr,u32 set)149*4882a593Smuzhiyun static inline void xvip_set(struct xvip_device *xvip, u32 addr, u32 set)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun xvip_write(xvip, addr, xvip_read(xvip, addr) | set);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun void xvip_clr_or_set(struct xvip_device *xvip, u32 addr, u32 mask, bool set);
155*4882a593Smuzhiyun void xvip_clr_and_set(struct xvip_device *xvip, u32 addr, u32 clr, u32 set);
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun int xvip_init_resources(struct xvip_device *xvip);
158*4882a593Smuzhiyun void xvip_cleanup_resources(struct xvip_device *xvip);
159*4882a593Smuzhiyun
xvip_reset(struct xvip_device * xvip)160*4882a593Smuzhiyun static inline void xvip_reset(struct xvip_device *xvip)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun xvip_write(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_RESET);
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
xvip_start(struct xvip_device * xvip)165*4882a593Smuzhiyun static inline void xvip_start(struct xvip_device *xvip)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun xvip_set(xvip, XVIP_CTRL_CONTROL,
168*4882a593Smuzhiyun XVIP_CTRL_CONTROL_SW_ENABLE | XVIP_CTRL_CONTROL_REG_UPDATE);
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun
xvip_stop(struct xvip_device * xvip)171*4882a593Smuzhiyun static inline void xvip_stop(struct xvip_device *xvip)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_ENABLE);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
xvip_resume(struct xvip_device * xvip)176*4882a593Smuzhiyun static inline void xvip_resume(struct xvip_device *xvip)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun xvip_write(xvip, XVIP_CTRL_CONTROL,
179*4882a593Smuzhiyun xvip->saved_ctrl | XVIP_CTRL_CONTROL_SW_ENABLE);
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
xvip_suspend(struct xvip_device * xvip)182*4882a593Smuzhiyun static inline void xvip_suspend(struct xvip_device *xvip)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun xvip->saved_ctrl = xvip_read(xvip, XVIP_CTRL_CONTROL);
185*4882a593Smuzhiyun xvip_write(xvip, XVIP_CTRL_CONTROL,
186*4882a593Smuzhiyun xvip->saved_ctrl & ~XVIP_CTRL_CONTROL_SW_ENABLE);
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun
xvip_set_frame_size(struct xvip_device * xvip,const struct v4l2_mbus_framefmt * format)189*4882a593Smuzhiyun static inline void xvip_set_frame_size(struct xvip_device *xvip,
190*4882a593Smuzhiyun const struct v4l2_mbus_framefmt *format)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun xvip_write(xvip, XVIP_ACTIVE_SIZE,
193*4882a593Smuzhiyun (format->height << XVIP_ACTIVE_VSIZE_SHIFT) |
194*4882a593Smuzhiyun (format->width << XVIP_ACTIVE_HSIZE_SHIFT));
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun
xvip_get_frame_size(struct xvip_device * xvip,struct v4l2_mbus_framefmt * format)197*4882a593Smuzhiyun static inline void xvip_get_frame_size(struct xvip_device *xvip,
198*4882a593Smuzhiyun struct v4l2_mbus_framefmt *format)
199*4882a593Smuzhiyun {
200*4882a593Smuzhiyun u32 reg;
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun reg = xvip_read(xvip, XVIP_ACTIVE_SIZE);
203*4882a593Smuzhiyun format->width = (reg & XVIP_ACTIVE_HSIZE_MASK) >>
204*4882a593Smuzhiyun XVIP_ACTIVE_HSIZE_SHIFT;
205*4882a593Smuzhiyun format->height = (reg & XVIP_ACTIVE_VSIZE_MASK) >>
206*4882a593Smuzhiyun XVIP_ACTIVE_VSIZE_SHIFT;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
xvip_enable_reg_update(struct xvip_device * xvip)209*4882a593Smuzhiyun static inline void xvip_enable_reg_update(struct xvip_device *xvip)
210*4882a593Smuzhiyun {
211*4882a593Smuzhiyun xvip_set(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE);
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
xvip_disable_reg_update(struct xvip_device * xvip)214*4882a593Smuzhiyun static inline void xvip_disable_reg_update(struct xvip_device *xvip)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE);
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
xvip_print_version(struct xvip_device * xvip)219*4882a593Smuzhiyun static inline void xvip_print_version(struct xvip_device *xvip)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun u32 version;
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun version = xvip_read(xvip, XVIP_CTRL_VERSION);
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun dev_info(xvip->dev, "device found, version %u.%02x%x\n",
226*4882a593Smuzhiyun ((version & XVIP_CTRL_VERSION_MAJOR_MASK) >>
227*4882a593Smuzhiyun XVIP_CTRL_VERSION_MAJOR_SHIFT),
228*4882a593Smuzhiyun ((version & XVIP_CTRL_VERSION_MINOR_MASK) >>
229*4882a593Smuzhiyun XVIP_CTRL_VERSION_MINOR_SHIFT),
230*4882a593Smuzhiyun ((version & XVIP_CTRL_VERSION_REVISION_MASK) >>
231*4882a593Smuzhiyun XVIP_CTRL_VERSION_REVISION_SHIFT));
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun #endif /* __XILINX_VIP_H__ */
235