aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/s5p-fimc/fimc-core.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/s5p-fimc/fimc-core.h')
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h377
1 files changed, 298 insertions, 79 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index 6b3e0cd73cdd..3e1078516560 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -11,10 +11,14 @@
11#ifndef FIMC_CORE_H_ 11#ifndef FIMC_CORE_H_
12#define FIMC_CORE_H_ 12#define FIMC_CORE_H_
13 13
14/*#define DEBUG*/
15
14#include <linux/types.h> 16#include <linux/types.h>
15#include <media/videobuf-core.h> 17#include <media/videobuf-core.h>
16#include <media/v4l2-device.h> 18#include <media/v4l2-device.h>
17#include <media/v4l2-mem2mem.h> 19#include <media/v4l2-mem2mem.h>
20#include <media/v4l2-mediabus.h>
21#include <media/s3c_fimc.h>
18#include <linux/videodev2.h> 22#include <linux/videodev2.h>
19#include "regs-fimc.h" 23#include "regs-fimc.h"
20 24
@@ -28,47 +32,72 @@
28#define dbg(fmt, args...) 32#define dbg(fmt, args...)
29#endif 33#endif
30 34
35/* Time to wait for next frame VSYNC interrupt while stopping operation. */
36#define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000)
31#define NUM_FIMC_CLOCKS 2 37#define NUM_FIMC_CLOCKS 2
32#define MODULE_NAME "s5p-fimc" 38#define MODULE_NAME "s5p-fimc"
33#define FIMC_MAX_DEVS 3 39#define FIMC_MAX_DEVS 4
34#define FIMC_MAX_OUT_BUFS 4 40#define FIMC_MAX_OUT_BUFS 4
35#define SCALER_MAX_HRATIO 64 41#define SCALER_MAX_HRATIO 64
36#define SCALER_MAX_VRATIO 64 42#define SCALER_MAX_VRATIO 64
43#define DMA_MIN_SIZE 8
37 44
38enum { 45/* FIMC device state flags */
46enum fimc_dev_flags {
47 /* for m2m node */
39 ST_IDLE, 48 ST_IDLE,
40 ST_OUTDMA_RUN, 49 ST_OUTDMA_RUN,
41 ST_M2M_PEND, 50 ST_M2M_PEND,
51 /* for capture node */
52 ST_CAPT_PEND,
53 ST_CAPT_RUN,
54 ST_CAPT_STREAM,
55 ST_CAPT_SHUT,
42}; 56};
43 57
44#define fimc_m2m_active(dev) test_bit(ST_OUTDMA_RUN, &(dev)->state) 58#define fimc_m2m_active(dev) test_bit(ST_OUTDMA_RUN, &(dev)->state)
45#define fimc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state) 59#define fimc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state)
46 60
61#define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state)
62#define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state)
63
64#define fimc_capture_active(dev) \
65 (test_bit(ST_CAPT_RUN, &(dev)->state) || \
66 test_bit(ST_CAPT_PEND, &(dev)->state))
67
68#define fimc_capture_streaming(dev) \
69 test_bit(ST_CAPT_STREAM, &(dev)->state)
70
71#define fimc_buf_finish(dev, vid_buf) do { \
72 spin_lock(&(dev)->irqlock); \
73 (vid_buf)->vb.state = VIDEOBUF_DONE; \
74 spin_unlock(&(dev)->irqlock); \
75 wake_up(&(vid_buf)->vb.done); \
76} while (0)
77
47enum fimc_datapath { 78enum fimc_datapath {
48 FIMC_ITU_CAM_A, 79 FIMC_CAMERA,
49 FIMC_ITU_CAM_B,
50 FIMC_MIPI_CAM,
51 FIMC_DMA, 80 FIMC_DMA,
52 FIMC_LCDFIFO, 81 FIMC_LCDFIFO,
53 FIMC_WRITEBACK 82 FIMC_WRITEBACK
54}; 83};
55 84
56enum fimc_color_fmt { 85enum fimc_color_fmt {
57 S5P_FIMC_RGB565, 86 S5P_FIMC_RGB565 = 0x10,
58 S5P_FIMC_RGB666, 87 S5P_FIMC_RGB666,
59 S5P_FIMC_RGB888, 88 S5P_FIMC_RGB888,
60 S5P_FIMC_YCBCR420, 89 S5P_FIMC_RGB30_LOCAL,
90 S5P_FIMC_YCBCR420 = 0x20,
61 S5P_FIMC_YCBCR422, 91 S5P_FIMC_YCBCR422,
62 S5P_FIMC_YCBYCR422, 92 S5P_FIMC_YCBYCR422,
63 S5P_FIMC_YCRYCB422, 93 S5P_FIMC_YCRYCB422,
64 S5P_FIMC_CBYCRY422, 94 S5P_FIMC_CBYCRY422,
65 S5P_FIMC_CRYCBY422, 95 S5P_FIMC_CRYCBY422,
66 S5P_FIMC_RGB30_LOCAL,
67 S5P_FIMC_YCBCR444_LOCAL, 96 S5P_FIMC_YCBCR444_LOCAL,
68 S5P_FIMC_MAX_COLOR = S5P_FIMC_YCBCR444_LOCAL,
69 S5P_FIMC_COLOR_MASK = 0x0F,
70}; 97};
71 98
99#define fimc_fmt_is_rgb(x) ((x) & 0x10)
100
72/* Y/Cb/Cr components order at DMA output for 1 plane YCbCr 4:2:2 formats. */ 101/* Y/Cb/Cr components order at DMA output for 1 plane YCbCr 4:2:2 formats. */
73#define S5P_FIMC_OUT_CRYCBY S5P_CIOCTRL_ORDER422_CRYCBY 102#define S5P_FIMC_OUT_CRYCBY S5P_CIOCTRL_ORDER422_CRYCBY
74#define S5P_FIMC_OUT_CBYCRY S5P_CIOCTRL_ORDER422_YCRYCB 103#define S5P_FIMC_OUT_CBYCRY S5P_CIOCTRL_ORDER422_YCRYCB
@@ -93,11 +122,13 @@ enum fimc_color_fmt {
93#define S5P_FIMC_EFFECT_SIKHOUETTE S5P_CIIMGEFF_FIN_SILHOUETTE 122#define S5P_FIMC_EFFECT_SIKHOUETTE S5P_CIIMGEFF_FIN_SILHOUETTE
94 123
95/* The hardware context state. */ 124/* The hardware context state. */
96#define FIMC_PARAMS (1 << 0) 125#define FIMC_PARAMS (1 << 0)
97#define FIMC_SRC_ADDR (1 << 1) 126#define FIMC_SRC_ADDR (1 << 1)
98#define FIMC_DST_ADDR (1 << 2) 127#define FIMC_DST_ADDR (1 << 2)
99#define FIMC_SRC_FMT (1 << 3) 128#define FIMC_SRC_FMT (1 << 3)
100#define FIMC_DST_FMT (1 << 4) 129#define FIMC_DST_FMT (1 << 4)
130#define FIMC_CTX_M2M (1 << 5)
131#define FIMC_CTX_CAP (1 << 6)
101 132
102/* Image conversion flags */ 133/* Image conversion flags */
103#define FIMC_IN_DMA_ACCESS_TILED (1 << 0) 134#define FIMC_IN_DMA_ACCESS_TILED (1 << 0)
@@ -106,7 +137,9 @@ enum fimc_color_fmt {
106#define FIMC_OUT_DMA_ACCESS_LINEAR (0 << 1) 137#define FIMC_OUT_DMA_ACCESS_LINEAR (0 << 1)
107#define FIMC_SCAN_MODE_PROGRESSIVE (0 << 2) 138#define FIMC_SCAN_MODE_PROGRESSIVE (0 << 2)
108#define FIMC_SCAN_MODE_INTERLACED (1 << 2) 139#define FIMC_SCAN_MODE_INTERLACED (1 << 2)
109/* YCbCr data dynamic range for RGB-YUV color conversion. Y/Cb/Cr: (0 ~ 255) */ 140/*
141 * YCbCr data dynamic range for RGB-YUV color conversion.
142 * Y/Cb/Cr: (0 ~ 255) */
110#define FIMC_COLOR_RANGE_WIDE (0 << 3) 143#define FIMC_COLOR_RANGE_WIDE (0 << 3)
111/* Y (16 ~ 235), Cb/Cr (16 ~ 240) */ 144/* Y (16 ~ 235), Cb/Cr (16 ~ 240) */
112#define FIMC_COLOR_RANGE_NARROW (1 << 3) 145#define FIMC_COLOR_RANGE_NARROW (1 << 3)
@@ -118,20 +151,25 @@ enum fimc_color_fmt {
118 151
119/** 152/**
120 * struct fimc_fmt - the driver's internal color format data 153 * struct fimc_fmt - the driver's internal color format data
154 * @mbus_code: Media Bus pixel code, -1 if not applicable
121 * @name: format description 155 * @name: format description
122 * @fourcc: the fourcc code for this format 156 * @fourcc: the fourcc code for this format, 0 if not applicable
123 * @color: the corresponding fimc_color_fmt 157 * @color: the corresponding fimc_color_fmt
124 * @depth: number of bits per pixel 158 * @depth: driver's private 'number of bits per pixel'
125 * @buff_cnt: number of physically non-contiguous data planes 159 * @buff_cnt: number of physically non-contiguous data planes
126 * @planes_cnt: number of physically contiguous data planes 160 * @planes_cnt: number of physically contiguous data planes
127 */ 161 */
128struct fimc_fmt { 162struct fimc_fmt {
163 enum v4l2_mbus_pixelcode mbus_code;
129 char *name; 164 char *name;
130 u32 fourcc; 165 u32 fourcc;
131 u32 color; 166 u32 color;
132 u32 depth;
133 u16 buff_cnt; 167 u16 buff_cnt;
134 u16 planes_cnt; 168 u16 planes_cnt;
169 u16 depth;
170 u16 flags;
171#define FMT_FLAGS_CAM (1 << 0)
172#define FMT_FLAGS_M2M (1 << 1)
135}; 173};
136 174
137/** 175/**
@@ -167,37 +205,37 @@ struct fimc_effect {
167/** 205/**
168 * struct fimc_scaler - the configuration data for FIMC inetrnal scaler 206 * struct fimc_scaler - the configuration data for FIMC inetrnal scaler
169 * 207 *
170 * @enabled: the flag set when the scaler is used 208 * @scaleup_h: flag indicating scaling up horizontally
209 * @scaleup_v: flag indicating scaling up vertically
210 * @copy_mode: flag indicating transparent DMA transfer (no scaling
211 * and color format conversion)
212 * @enabled: flag indicating if the scaler is used
171 * @hfactor: horizontal shift factor 213 * @hfactor: horizontal shift factor
172 * @vfactor: vertical shift factor 214 * @vfactor: vertical shift factor
173 * @pre_hratio: horizontal ratio of the prescaler 215 * @pre_hratio: horizontal ratio of the prescaler
174 * @pre_vratio: vertical ratio of the prescaler 216 * @pre_vratio: vertical ratio of the prescaler
175 * @pre_dst_width: the prescaler's destination width 217 * @pre_dst_width: the prescaler's destination width
176 * @pre_dst_height: the prescaler's destination height 218 * @pre_dst_height: the prescaler's destination height
177 * @scaleup_h: flag indicating scaling up horizontally
178 * @scaleup_v: flag indicating scaling up vertically
179 * @main_hratio: the main scaler's horizontal ratio 219 * @main_hratio: the main scaler's horizontal ratio
180 * @main_vratio: the main scaler's vertical ratio 220 * @main_vratio: the main scaler's vertical ratio
181 * @real_width: source width - offset 221 * @real_width: source pixel (width - offset)
182 * @real_height: source height - offset 222 * @real_height: source pixel (height - offset)
183 * @copy_mode: flag set if one-to-one mode is used, i.e. no scaling
184 * and color format conversion
185 */ 223 */
186struct fimc_scaler { 224struct fimc_scaler {
187 u32 enabled; 225 unsigned int scaleup_h:1;
226 unsigned int scaleup_v:1;
227 unsigned int copy_mode:1;
228 unsigned int enabled:1;
188 u32 hfactor; 229 u32 hfactor;
189 u32 vfactor; 230 u32 vfactor;
190 u32 pre_hratio; 231 u32 pre_hratio;
191 u32 pre_vratio; 232 u32 pre_vratio;
192 u32 pre_dst_width; 233 u32 pre_dst_width;
193 u32 pre_dst_height; 234 u32 pre_dst_height;
194 u32 scaleup_h;
195 u32 scaleup_v;
196 u32 main_hratio; 235 u32 main_hratio;
197 u32 main_vratio; 236 u32 main_vratio;
198 u32 real_width; 237 u32 real_width;
199 u32 real_height; 238 u32 real_height;
200 u32 copy_mode;
201}; 239};
202 240
203/** 241/**
@@ -215,15 +253,18 @@ struct fimc_addr {
215 253
216/** 254/**
217 * struct fimc_vid_buffer - the driver's video buffer 255 * struct fimc_vid_buffer - the driver's video buffer
218 * @vb: v4l videobuf buffer 256 * @vb: v4l videobuf buffer
257 * @paddr: precalculated physical address set
258 * @index: buffer index for the output DMA engine
219 */ 259 */
220struct fimc_vid_buffer { 260struct fimc_vid_buffer {
221 struct videobuf_buffer vb; 261 struct videobuf_buffer vb;
262 struct fimc_addr paddr;
263 int index;
222}; 264};
223 265
224/** 266/**
225 * struct fimc_frame - input/output frame format properties 267 * struct fimc_frame - source/target frame properties
226 *
227 * @f_width: image full width (virtual screen size) 268 * @f_width: image full width (virtual screen size)
228 * @f_height: image full height (virtual screen size) 269 * @f_height: image full height (virtual screen size)
229 * @o_width: original image width as set by S_FMT 270 * @o_width: original image width as set by S_FMT
@@ -270,67 +311,119 @@ struct fimc_m2m_device {
270}; 311};
271 312
272/** 313/**
314 * struct fimc_vid_cap - camera capture device information
315 * @ctx: hardware context data
316 * @vfd: video device node for camera capture mode
317 * @v4l2_dev: v4l2_device struct to manage subdevs
318 * @sd: pointer to camera sensor subdevice currently in use
319 * @fmt: Media Bus format configured at selected image sensor
320 * @pending_buf_q: the pending buffer queue head
321 * @active_buf_q: the queue head of buffers scheduled in hardware
322 * @vbq: the capture am video buffer queue
323 * @active_buf_cnt: number of video buffers scheduled in hardware
324 * @buf_index: index for managing the output DMA buffers
325 * @frame_count: the frame counter for statistics
326 * @reqbufs_count: the number of buffers requested in REQBUFS ioctl
327 * @input_index: input (camera sensor) index
328 * @refcnt: driver's private reference counter
329 */
330struct fimc_vid_cap {
331 struct fimc_ctx *ctx;
332 struct video_device *vfd;
333 struct v4l2_device v4l2_dev;
334 struct v4l2_subdev *sd;
335 struct v4l2_mbus_framefmt fmt;
336 struct list_head pending_buf_q;
337 struct list_head active_buf_q;
338 struct videobuf_queue vbq;
339 int active_buf_cnt;
340 int buf_index;
341 unsigned int frame_count;
342 unsigned int reqbufs_count;
343 int input_index;
344 int refcnt;
345};
346
347/**
348 * struct fimc_pix_limit - image pixel size limits in various IP configurations
349 *
350 * @scaler_en_w: max input pixel width when the scaler is enabled
351 * @scaler_dis_w: max input pixel width when the scaler is disabled
352 * @in_rot_en_h: max input width with the input rotator is on
353 * @in_rot_dis_w: max input width with the input rotator is off
354 * @out_rot_en_w: max output width with the output rotator on
355 * @out_rot_dis_w: max output width with the output rotator off
356 */
357struct fimc_pix_limit {
358 u16 scaler_en_w;
359 u16 scaler_dis_w;
360 u16 in_rot_en_h;
361 u16 in_rot_dis_w;
362 u16 out_rot_en_w;
363 u16 out_rot_dis_w;
364};
365
366/**
273 * struct samsung_fimc_variant - camera interface variant information 367 * struct samsung_fimc_variant - camera interface variant information
274 * 368 *
275 * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes 369 * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes
276 * @has_inp_rot: set if has input rotator 370 * @has_inp_rot: set if has input rotator
277 * @has_out_rot: set if has output rotator 371 * @has_out_rot: set if has output rotator
372 * @pix_limit: pixel size constraints for the scaler
278 * @min_inp_pixsize: minimum input pixel size 373 * @min_inp_pixsize: minimum input pixel size
279 * @min_out_pixsize: minimum output pixel size 374 * @min_out_pixsize: minimum output pixel size
280 * @scaler_en_w: maximum input pixel width when the scaler is enabled 375 * @hor_offs_align: horizontal pixel offset aligment
281 * @scaler_dis_w: maximum input pixel width when the scaler is disabled 376 * @out_buf_count: the number of buffers in output DMA sequence
282 * @in_rot_en_h: maximum input width when the input rotator is used
283 * @in_rot_dis_w: maximum input width when the input rotator is used
284 * @out_rot_en_w: maximum output width for the output rotator enabled
285 * @out_rot_dis_w: maximum output width for the output rotator enabled
286 */ 377 */
287struct samsung_fimc_variant { 378struct samsung_fimc_variant {
288 unsigned int pix_hoff:1; 379 unsigned int pix_hoff:1;
289 unsigned int has_inp_rot:1; 380 unsigned int has_inp_rot:1;
290 unsigned int has_out_rot:1; 381 unsigned int has_out_rot:1;
291 382 struct fimc_pix_limit *pix_limit;
292 u16 min_inp_pixsize; 383 u16 min_inp_pixsize;
293 u16 min_out_pixsize; 384 u16 min_out_pixsize;
294 u16 scaler_en_w; 385 u16 hor_offs_align;
295 u16 scaler_dis_w; 386 u16 out_buf_count;
296 u16 in_rot_en_h;
297 u16 in_rot_dis_w;
298 u16 out_rot_en_w;
299 u16 out_rot_dis_w;
300}; 387};
301 388
302/** 389/**
303 * struct samsung_fimc_driverdata - per-device type driver data for init time. 390 * struct samsung_fimc_driverdata - per device type driver data for init time.
304 * 391 *
305 * @variant: the variant information for this driver. 392 * @variant: the variant information for this driver.
306 * @dev_cnt: number of fimc sub-devices available in SoC 393 * @dev_cnt: number of fimc sub-devices available in SoC
394 * @lclk_frequency: fimc bus clock frequency
307 */ 395 */
308struct samsung_fimc_driverdata { 396struct samsung_fimc_driverdata {
309 struct samsung_fimc_variant *variant[FIMC_MAX_DEVS]; 397 struct samsung_fimc_variant *variant[FIMC_MAX_DEVS];
310 int devs_cnt; 398 unsigned long lclk_frequency;
399 int num_entities;
311}; 400};
312 401
313struct fimc_ctx; 402struct fimc_ctx;
314 403
315/** 404/**
316 * struct fimc_subdev - abstraction for a FIMC entity 405 * struct fimc_dev - abstraction for FIMC entity
317 * 406 *
318 * @slock: the spinlock protecting this data structure 407 * @slock: the spinlock protecting this data structure
319 * @lock: the mutex protecting this data structure 408 * @lock: the mutex protecting this data structure
320 * @pdev: pointer to the FIMC platform device 409 * @pdev: pointer to the FIMC platform device
410 * @pdata: pointer to the device platform data
321 * @id: FIMC device index (0..2) 411 * @id: FIMC device index (0..2)
322 * @clock[]: the clocks required for FIMC operation 412 * @clock[]: the clocks required for FIMC operation
323 * @regs: the mapped hardware registers 413 * @regs: the mapped hardware registers
324 * @regs_res: the resource claimed for IO registers 414 * @regs_res: the resource claimed for IO registers
325 * @irq: interrupt number of the FIMC subdevice 415 * @irq: interrupt number of the FIMC subdevice
326 * @irqlock: spinlock protecting videbuffer queue 416 * @irqlock: spinlock protecting videobuffer queue
417 * @irq_queue:
327 * @m2m: memory-to-memory V4L2 device information 418 * @m2m: memory-to-memory V4L2 device information
328 * @state: the FIMC device state flags 419 * @vid_cap: camera capture device information
420 * @state: flags used to synchronize m2m and capture mode operation
329 */ 421 */
330struct fimc_dev { 422struct fimc_dev {
331 spinlock_t slock; 423 spinlock_t slock;
332 struct mutex lock; 424 struct mutex lock;
333 struct platform_device *pdev; 425 struct platform_device *pdev;
426 struct s3c_platform_fimc *pdata;
334 struct samsung_fimc_variant *variant; 427 struct samsung_fimc_variant *variant;
335 int id; 428 int id;
336 struct clk *clock[NUM_FIMC_CLOCKS]; 429 struct clk *clock[NUM_FIMC_CLOCKS];
@@ -338,8 +431,9 @@ struct fimc_dev {
338 struct resource *regs_res; 431 struct resource *regs_res;
339 int irq; 432 int irq;
340 spinlock_t irqlock; 433 spinlock_t irqlock;
341 struct workqueue_struct *work_queue; 434 wait_queue_head_t irq_queue;
342 struct fimc_m2m_device m2m; 435 struct fimc_m2m_device m2m;
436 struct fimc_vid_cap vid_cap;
343 unsigned long state; 437 unsigned long state;
344}; 438};
345 439
@@ -359,7 +453,7 @@ struct fimc_dev {
359 * @effect: image effect 453 * @effect: image effect
360 * @rotation: image clockwise rotation in degrees 454 * @rotation: image clockwise rotation in degrees
361 * @flip: image flip mode 455 * @flip: image flip mode
362 * @flags: an additional flags for image conversion 456 * @flags: additional flags for image conversion
363 * @state: flags to keep track of user configuration 457 * @state: flags to keep track of user configuration
364 * @fimc_dev: the FIMC device this context applies to 458 * @fimc_dev: the FIMC device this context applies to
365 * @m2m_ctx: memory-to-memory device context 459 * @m2m_ctx: memory-to-memory device context
@@ -384,6 +478,7 @@ struct fimc_ctx {
384 struct v4l2_m2m_ctx *m2m_ctx; 478 struct v4l2_m2m_ctx *m2m_ctx;
385}; 479};
386 480
481extern struct videobuf_queue_ops fimc_qops;
387 482
388static inline int tiled_fmt(struct fimc_fmt *fmt) 483static inline int tiled_fmt(struct fimc_fmt *fmt)
389{ 484{
@@ -397,18 +492,24 @@ static inline void fimc_hw_clear_irq(struct fimc_dev *dev)
397 writel(cfg, dev->regs + S5P_CIGCTRL); 492 writel(cfg, dev->regs + S5P_CIGCTRL);
398} 493}
399 494
400static inline void fimc_hw_start_scaler(struct fimc_dev *dev) 495static inline void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on)
401{ 496{
402 u32 cfg = readl(dev->regs + S5P_CISCCTRL); 497 u32 cfg = readl(dev->regs + S5P_CISCCTRL);
403 cfg |= S5P_CISCCTRL_SCALERSTART; 498 if (on)
499 cfg |= S5P_CISCCTRL_SCALERSTART;
500 else
501 cfg &= ~S5P_CISCCTRL_SCALERSTART;
404 writel(cfg, dev->regs + S5P_CISCCTRL); 502 writel(cfg, dev->regs + S5P_CISCCTRL);
405} 503}
406 504
407static inline void fimc_hw_stop_scaler(struct fimc_dev *dev) 505static inline void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on)
408{ 506{
409 u32 cfg = readl(dev->regs + S5P_CISCCTRL); 507 u32 cfg = readl(dev->regs + S5P_MSCTRL);
410 cfg &= ~S5P_CISCCTRL_SCALERSTART; 508 if (on)
411 writel(cfg, dev->regs + S5P_CISCCTRL); 509 cfg |= S5P_MSCTRL_ENVID;
510 else
511 cfg &= ~S5P_MSCTRL_ENVID;
512 writel(cfg, dev->regs + S5P_MSCTRL);
412} 513}
413 514
414static inline void fimc_hw_dis_capture(struct fimc_dev *dev) 515static inline void fimc_hw_dis_capture(struct fimc_dev *dev)
@@ -418,27 +519,30 @@ static inline void fimc_hw_dis_capture(struct fimc_dev *dev)
418 writel(cfg, dev->regs + S5P_CIIMGCPT); 519 writel(cfg, dev->regs + S5P_CIIMGCPT);
419} 520}
420 521
421static inline void fimc_hw_start_in_dma(struct fimc_dev *dev) 522/**
422{ 523 * fimc_hw_set_dma_seq - configure output DMA buffer sequence
423 u32 cfg = readl(dev->regs + S5P_MSCTRL); 524 * @mask: each bit corresponds to one of 32 output buffer registers set
424 cfg |= S5P_MSCTRL_ENVID; 525 * 1 to include buffer in the sequence, 0 to disable
425 writel(cfg, dev->regs + S5P_MSCTRL); 526 *
426} 527 * This function mask output DMA ring buffers, i.e. it allows to configure
427 528 * which of the output buffer address registers will be used by the DMA
428static inline void fimc_hw_stop_in_dma(struct fimc_dev *dev) 529 * engine.
530 */
531static inline void fimc_hw_set_dma_seq(struct fimc_dev *dev, u32 mask)
429{ 532{
430 u32 cfg = readl(dev->regs + S5P_MSCTRL); 533 writel(mask, dev->regs + S5P_CIFCNTSEQ);
431 cfg &= ~S5P_MSCTRL_ENVID;
432 writel(cfg, dev->regs + S5P_MSCTRL);
433} 534}
434 535
435static inline struct fimc_frame *ctx_m2m_get_frame(struct fimc_ctx *ctx, 536static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
436 enum v4l2_buf_type type) 537 enum v4l2_buf_type type)
437{ 538{
438 struct fimc_frame *frame; 539 struct fimc_frame *frame;
439 540
440 if (V4L2_BUF_TYPE_VIDEO_OUTPUT == type) { 541 if (V4L2_BUF_TYPE_VIDEO_OUTPUT == type) {
441 frame = &ctx->s_frame; 542 if (ctx->state & FIMC_CTX_M2M)
543 frame = &ctx->s_frame;
544 else
545 return ERR_PTR(-EINVAL);
442 } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE == type) { 546 } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE == type) {
443 frame = &ctx->d_frame; 547 frame = &ctx->d_frame;
444 } else { 548 } else {
@@ -450,22 +554,137 @@ static inline struct fimc_frame *ctx_m2m_get_frame(struct fimc_ctx *ctx,
450 return frame; 554 return frame;
451} 555}
452 556
557static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
558{
559 u32 reg = readl(dev->regs + S5P_CISTATUS);
560 return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
561 S5P_CISTATUS_FRAMECNT_SHIFT;
562}
563
453/* -----------------------------------------------------*/ 564/* -----------------------------------------------------*/
454/* fimc-reg.c */ 565/* fimc-reg.c */
455void fimc_hw_reset(struct fimc_dev *dev); 566void fimc_hw_reset(struct fimc_dev *fimc);
456void fimc_hw_set_rotation(struct fimc_ctx *ctx); 567void fimc_hw_set_rotation(struct fimc_ctx *ctx);
457void fimc_hw_set_target_format(struct fimc_ctx *ctx); 568void fimc_hw_set_target_format(struct fimc_ctx *ctx);
458void fimc_hw_set_out_dma(struct fimc_ctx *ctx); 569void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
459void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable); 570void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
460void fimc_hw_en_irq(struct fimc_dev *dev, int enable); 571void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
461void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
462void fimc_hw_set_scaler(struct fimc_ctx *ctx); 572void fimc_hw_set_scaler(struct fimc_ctx *ctx);
463void fimc_hw_en_capture(struct fimc_ctx *ctx); 573void fimc_hw_en_capture(struct fimc_ctx *ctx);
464void fimc_hw_set_effect(struct fimc_ctx *ctx); 574void fimc_hw_set_effect(struct fimc_ctx *ctx);
465void fimc_hw_set_in_dma(struct fimc_ctx *ctx); 575void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
466void fimc_hw_set_input_path(struct fimc_ctx *ctx); 576void fimc_hw_set_input_path(struct fimc_ctx *ctx);
467void fimc_hw_set_output_path(struct fimc_ctx *ctx); 577void fimc_hw_set_output_path(struct fimc_ctx *ctx);
468void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr); 578void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr);
469void fimc_hw_set_output_addr(struct fimc_dev *dev, struct fimc_addr *paddr); 579void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr,
580 int index);
581int fimc_hw_set_camera_source(struct fimc_dev *fimc,
582 struct s3c_fimc_isp_info *cam);
583int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f);
584int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
585 struct s3c_fimc_isp_info *cam);
586int fimc_hw_set_camera_type(struct fimc_dev *fimc,
587 struct s3c_fimc_isp_info *cam);
588
589/* -----------------------------------------------------*/
590/* fimc-core.c */
591int fimc_vidioc_enum_fmt(struct file *file, void *priv,
592 struct v4l2_fmtdesc *f);
593int fimc_vidioc_g_fmt(struct file *file, void *priv,
594 struct v4l2_format *f);
595int fimc_vidioc_try_fmt(struct file *file, void *priv,
596 struct v4l2_format *f);
597int fimc_vidioc_g_crop(struct file *file, void *fh,
598 struct v4l2_crop *cr);
599int fimc_vidioc_cropcap(struct file *file, void *fh,
600 struct v4l2_cropcap *cr);
601int fimc_vidioc_queryctrl(struct file *file, void *priv,
602 struct v4l2_queryctrl *qc);
603int fimc_vidioc_g_ctrl(struct file *file, void *priv,
604 struct v4l2_control *ctrl);
605
606int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr);
607int check_ctrl_val(struct fimc_ctx *ctx, struct v4l2_control *ctrl);
608int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl);
609
610struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask);
611struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f,
612 unsigned int mask);
613
614int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f);
615int fimc_set_scaler_info(struct fimc_ctx *ctx);
616int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags);
617int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf,
618 struct fimc_frame *frame, struct fimc_addr *paddr);
619
620/* -----------------------------------------------------*/
621/* fimc-capture.c */
622int fimc_register_capture_device(struct fimc_dev *fimc);
623void fimc_unregister_capture_device(struct fimc_dev *fimc);
624int fimc_sensor_sd_init(struct fimc_dev *fimc, int index);
625int fimc_vid_cap_buf_queue(struct fimc_dev *fimc,
626 struct fimc_vid_buffer *fimc_vb);
627
628/* Locking: the caller holds fimc->slock */
629static inline void fimc_activate_capture(struct fimc_ctx *ctx)
630{
631 fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled);
632 fimc_hw_en_capture(ctx);
633}
634
635static inline void fimc_deactivate_capture(struct fimc_dev *fimc)
636{
637 fimc_hw_en_lastirq(fimc, true);
638 fimc_hw_dis_capture(fimc);
639 fimc_hw_enable_scaler(fimc, false);
640 fimc_hw_en_lastirq(fimc, false);
641}
642
643/*
644 * Add video buffer to the active buffers queue.
645 * The caller holds irqlock spinlock.
646 */
647static inline void active_queue_add(struct fimc_vid_cap *vid_cap,
648 struct fimc_vid_buffer *buf)
649{
650 buf->vb.state = VIDEOBUF_ACTIVE;
651 list_add_tail(&buf->vb.queue, &vid_cap->active_buf_q);
652 vid_cap->active_buf_cnt++;
653}
654
655/*
656 * Pop a video buffer from the capture active buffers queue
657 * Locking: Need to be called with dev->slock held.
658 */
659static inline struct fimc_vid_buffer *
660active_queue_pop(struct fimc_vid_cap *vid_cap)
661{
662 struct fimc_vid_buffer *buf;
663 buf = list_entry(vid_cap->active_buf_q.next,
664 struct fimc_vid_buffer, vb.queue);
665 list_del(&buf->vb.queue);
666 vid_cap->active_buf_cnt--;
667 return buf;
668}
669
670/* Add video buffer to the capture pending buffers queue */
671static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap,
672 struct fimc_vid_buffer *buf)
673{
674 buf->vb.state = VIDEOBUF_QUEUED;
675 list_add_tail(&buf->vb.queue, &vid_cap->pending_buf_q);
676}
677
678/* Add video buffer to the capture pending buffers queue */
679static inline struct fimc_vid_buffer *
680pending_queue_pop(struct fimc_vid_cap *vid_cap)
681{
682 struct fimc_vid_buffer *buf;
683 buf = list_entry(vid_cap->pending_buf_q.next,
684 struct fimc_vid_buffer, vb.queue);
685 list_del(&buf->vb.queue);
686 return buf;
687}
688
470 689
471#endif /* FIMC_CORE_H_ */ 690#endif /* FIMC_CORE_H_ */