1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * ispvideo.h |
4 | * |
5 | * TI OMAP3 ISP - Generic video node |
6 | * |
7 | * Copyright (C) 2009-2010 Nokia Corporation |
8 | * |
9 | * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
10 | * Sakari Ailus <sakari.ailus@iki.fi> |
11 | */ |
12 | |
13 | #ifndef OMAP3_ISP_VIDEO_H |
14 | #define OMAP3_ISP_VIDEO_H |
15 | |
16 | #include <linux/v4l2-mediabus.h> |
17 | #include <media/media-entity.h> |
18 | #include <media/v4l2-dev.h> |
19 | #include <media/v4l2-fh.h> |
20 | #include <media/videobuf2-v4l2.h> |
21 | |
22 | #define ISP_VIDEO_DRIVER_NAME "ispvideo" |
23 | #define ISP_VIDEO_DRIVER_VERSION "0.0.2" |
24 | |
25 | struct isp_device; |
26 | struct isp_video; |
27 | struct v4l2_mbus_framefmt; |
28 | struct v4l2_pix_format; |
29 | |
30 | /* |
31 | * struct isp_format_info - ISP media bus format information |
32 | * @code: V4L2 media bus format code |
33 | * @truncated: V4L2 media bus format code for the same format truncated to 10 |
34 | * bits. Identical to @code if the format is 10 bits wide or less. |
35 | * @uncompressed: V4L2 media bus format code for the corresponding uncompressed |
36 | * format. Identical to @code if the format is not DPCM compressed. |
37 | * @flavor: V4L2 media bus format code for the same pixel layout but |
38 | * shifted to be 8 bits per pixel. =0 if format is not shiftable. |
39 | * @pixelformat: V4L2 pixel format FCC identifier |
40 | * @width: Bits per pixel (when transferred over a bus) |
41 | * @bpp: Bytes per pixel (when stored in memory) |
42 | */ |
43 | struct isp_format_info { |
44 | u32 code; |
45 | u32 truncated; |
46 | u32 uncompressed; |
47 | u32 flavor; |
48 | u32 pixelformat; |
49 | unsigned int width; |
50 | unsigned int bpp; |
51 | }; |
52 | |
53 | enum isp_pipeline_stream_state { |
54 | ISP_PIPELINE_STREAM_STOPPED = 0, |
55 | ISP_PIPELINE_STREAM_CONTINUOUS = 1, |
56 | ISP_PIPELINE_STREAM_SINGLESHOT = 2, |
57 | }; |
58 | |
59 | enum isp_pipeline_state { |
60 | /* The stream has been started on the input video node. */ |
61 | ISP_PIPELINE_STREAM_INPUT = 1, |
62 | /* The stream has been started on the output video node. */ |
63 | ISP_PIPELINE_STREAM_OUTPUT = 2, |
64 | /* At least one buffer is queued on the input video node. */ |
65 | ISP_PIPELINE_QUEUE_INPUT = 4, |
66 | /* At least one buffer is queued on the output video node. */ |
67 | ISP_PIPELINE_QUEUE_OUTPUT = 8, |
68 | /* The input entity is idle, ready to be started. */ |
69 | ISP_PIPELINE_IDLE_INPUT = 16, |
70 | /* The output entity is idle, ready to be started. */ |
71 | ISP_PIPELINE_IDLE_OUTPUT = 32, |
72 | /* The pipeline is currently streaming. */ |
73 | ISP_PIPELINE_STREAM = 64, |
74 | }; |
75 | |
76 | /* |
77 | * struct isp_pipeline - An ISP hardware pipeline |
78 | * @field: The field being processed by the pipeline |
79 | * @error: A hardware error occurred during capture |
80 | * @ent_enum: Entities in the pipeline |
81 | */ |
82 | struct isp_pipeline { |
83 | struct media_pipeline pipe; |
84 | spinlock_t lock; /* Pipeline state and queue flags */ |
85 | unsigned int state; |
86 | enum isp_pipeline_stream_state stream_state; |
87 | struct isp_video *input; |
88 | struct isp_video *output; |
89 | struct media_entity_enum ent_enum; |
90 | unsigned long l3_ick; |
91 | unsigned int max_rate; |
92 | enum v4l2_field field; |
93 | atomic_t frame_number; |
94 | bool do_propagation; /* of frame number */ |
95 | bool error; |
96 | struct v4l2_fract max_timeperframe; |
97 | struct v4l2_subdev *external; |
98 | unsigned int external_rate; |
99 | unsigned int external_width; |
100 | }; |
101 | |
102 | static inline struct isp_pipeline *to_isp_pipeline(struct media_entity *entity) |
103 | { |
104 | struct media_pipeline *pipe = media_entity_pipeline(entity); |
105 | |
106 | if (!pipe) |
107 | return NULL; |
108 | |
109 | return container_of(pipe, struct isp_pipeline, pipe); |
110 | } |
111 | |
112 | static inline int isp_pipeline_ready(struct isp_pipeline *pipe) |
113 | { |
114 | return pipe->state == (ISP_PIPELINE_STREAM_INPUT | |
115 | ISP_PIPELINE_STREAM_OUTPUT | |
116 | ISP_PIPELINE_QUEUE_INPUT | |
117 | ISP_PIPELINE_QUEUE_OUTPUT | |
118 | ISP_PIPELINE_IDLE_INPUT | |
119 | ISP_PIPELINE_IDLE_OUTPUT); |
120 | } |
121 | |
122 | /** |
123 | * struct isp_buffer - ISP video buffer |
124 | * @vb: videobuf2 buffer |
125 | * @irqlist: List head for insertion into IRQ queue |
126 | * @dma: DMA address |
127 | */ |
128 | struct isp_buffer { |
129 | struct vb2_v4l2_buffer vb; |
130 | struct list_head irqlist; |
131 | dma_addr_t dma; |
132 | }; |
133 | |
134 | #define to_isp_buffer(buf) container_of(buf, struct isp_buffer, vb) |
135 | |
136 | enum isp_video_dmaqueue_flags { |
137 | /* Set if DMA queue becomes empty when ISP_PIPELINE_STREAM_CONTINUOUS */ |
138 | ISP_VIDEO_DMAQUEUE_UNDERRUN = (1 << 0), |
139 | /* Set when queuing buffer to an empty DMA queue */ |
140 | ISP_VIDEO_DMAQUEUE_QUEUED = (1 << 1), |
141 | }; |
142 | |
143 | #define isp_video_dmaqueue_flags_clr(video) \ |
144 | ({ (video)->dmaqueue_flags = 0; }) |
145 | |
146 | /* |
147 | * struct isp_video_operations - ISP video operations |
148 | * @queue: Resume streaming when a buffer is queued. Called on VIDIOC_QBUF |
149 | * if there was no buffer previously queued. |
150 | */ |
151 | struct isp_video_operations { |
152 | int(*queue)(struct isp_video *video, struct isp_buffer *buffer); |
153 | }; |
154 | |
155 | struct isp_video { |
156 | struct video_device video; |
157 | enum v4l2_buf_type type; |
158 | struct media_pad pad; |
159 | |
160 | struct mutex mutex; /* format and crop settings */ |
161 | atomic_t active; |
162 | |
163 | struct isp_device *isp; |
164 | |
165 | unsigned int capture_mem; |
166 | unsigned int bpl_alignment; /* alignment value */ |
167 | unsigned int bpl_zero_padding; /* whether the alignment is optional */ |
168 | unsigned int bpl_max; /* maximum bytes per line value */ |
169 | unsigned int bpl_value; /* bytes per line value */ |
170 | unsigned int bpl_padding; /* padding at end of line */ |
171 | |
172 | /* Pipeline state */ |
173 | struct isp_pipeline pipe; |
174 | struct mutex stream_lock; /* pipeline and stream states */ |
175 | bool error; |
176 | |
177 | /* Video buffers queue */ |
178 | struct vb2_queue *queue; |
179 | struct mutex queue_lock; /* protects the queue */ |
180 | spinlock_t irqlock; /* protects dmaqueue */ |
181 | struct list_head dmaqueue; |
182 | enum isp_video_dmaqueue_flags dmaqueue_flags; |
183 | |
184 | const struct isp_video_operations *ops; |
185 | }; |
186 | |
187 | #define to_isp_video(vdev) container_of(vdev, struct isp_video, video) |
188 | |
189 | struct isp_video_fh { |
190 | struct v4l2_fh vfh; |
191 | struct isp_video *video; |
192 | struct vb2_queue queue; |
193 | struct v4l2_format format; |
194 | struct v4l2_fract timeperframe; |
195 | }; |
196 | |
197 | #define to_isp_video_fh(fh) container_of(fh, struct isp_video_fh, vfh) |
198 | #define isp_video_queue_to_isp_video_fh(q) \ |
199 | container_of(q, struct isp_video_fh, queue) |
200 | |
201 | int omap3isp_video_init(struct isp_video *video, const char *name); |
202 | void omap3isp_video_cleanup(struct isp_video *video); |
203 | int omap3isp_video_register(struct isp_video *video, |
204 | struct v4l2_device *vdev); |
205 | void omap3isp_video_unregister(struct isp_video *video); |
206 | struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video); |
207 | void omap3isp_video_cancel_stream(struct isp_video *video); |
208 | void omap3isp_video_resume(struct isp_video *video, int continuous); |
209 | struct media_pad *omap3isp_video_remote_pad(struct isp_video *video); |
210 | |
211 | const struct isp_format_info * |
212 | omap3isp_video_format_info(u32 code); |
213 | |
214 | #endif /* OMAP3_ISP_VIDEO_H */ |
215 | |