xref: /OK3568_Linux_fs/kernel/drivers/media/platform/xilinx/xilinx-vip.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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