[media] s5p-fimc: Do not lock both buffer queues in s_fmt
[deliverable/linux.git] / drivers / media / video / s5p-fimc / fimc-core.h
CommitLineData
5fd8f738
SN
1/*
2 * Copyright (c) 2010 Samsung Electronics
3 *
4 * Sylwester Nawrocki, <s.nawrocki@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef FIMC_CORE_H_
12#define FIMC_CORE_H_
13
14#include <linux/types.h>
15#include <media/videobuf-core.h>
16#include <media/v4l2-device.h>
17#include <media/v4l2-mem2mem.h>
18#include <linux/videodev2.h>
19#include "regs-fimc.h"
20
21#define err(fmt, args...) \
22 printk(KERN_ERR "%s:%d: " fmt "\n", __func__, __LINE__, ##args)
23
24#ifdef DEBUG
25#define dbg(fmt, args...) \
26 printk(KERN_DEBUG "%s:%d: " fmt "\n", __func__, __LINE__, ##args)
27#else
28#define dbg(fmt, args...)
29#endif
30
5fd8f738
SN
31#define NUM_FIMC_CLOCKS 2
32#define MODULE_NAME "s5p-fimc"
33#define FIMC_MAX_DEVS 3
34#define FIMC_MAX_OUT_BUFS 4
35#define SCALER_MAX_HRATIO 64
36#define SCALER_MAX_VRATIO 64
548aafcd 37#define DMA_MIN_SIZE 8
5fd8f738
SN
38
39enum {
40 ST_IDLE,
41 ST_OUTDMA_RUN,
42 ST_M2M_PEND,
43};
44
45#define fimc_m2m_active(dev) test_bit(ST_OUTDMA_RUN, &(dev)->state)
46#define fimc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state)
47
48enum fimc_datapath {
49 FIMC_ITU_CAM_A,
50 FIMC_ITU_CAM_B,
51 FIMC_MIPI_CAM,
52 FIMC_DMA,
53 FIMC_LCDFIFO,
54 FIMC_WRITEBACK
55};
56
57enum fimc_color_fmt {
548aafcd 58 S5P_FIMC_RGB565 = 0x10,
5fd8f738
SN
59 S5P_FIMC_RGB666,
60 S5P_FIMC_RGB888,
548aafcd
SN
61 S5P_FIMC_RGB30_LOCAL,
62 S5P_FIMC_YCBCR420 = 0x20,
5fd8f738
SN
63 S5P_FIMC_YCBCR422,
64 S5P_FIMC_YCBYCR422,
65 S5P_FIMC_YCRYCB422,
66 S5P_FIMC_CBYCRY422,
67 S5P_FIMC_CRYCBY422,
5fd8f738 68 S5P_FIMC_YCBCR444_LOCAL,
5fd8f738
SN
69};
70
548aafcd
SN
71#define fimc_fmt_is_rgb(x) ((x) & 0x10)
72
5fd8f738
SN
73/* Y/Cb/Cr components order at DMA output for 1 plane YCbCr 4:2:2 formats. */
74#define S5P_FIMC_OUT_CRYCBY S5P_CIOCTRL_ORDER422_CRYCBY
75#define S5P_FIMC_OUT_CBYCRY S5P_CIOCTRL_ORDER422_YCRYCB
76#define S5P_FIMC_OUT_YCRYCB S5P_CIOCTRL_ORDER422_CBYCRY
77#define S5P_FIMC_OUT_YCBYCR S5P_CIOCTRL_ORDER422_YCBYCR
78
79/* Input Y/Cb/Cr components order for 1 plane YCbCr 4:2:2 color formats. */
80#define S5P_FIMC_IN_CRYCBY S5P_MSCTRL_ORDER422_CRYCBY
81#define S5P_FIMC_IN_CBYCRY S5P_MSCTRL_ORDER422_YCRYCB
82#define S5P_FIMC_IN_YCRYCB S5P_MSCTRL_ORDER422_CBYCRY
83#define S5P_FIMC_IN_YCBYCR S5P_MSCTRL_ORDER422_YCBYCR
84
85/* Cb/Cr chrominance components order for 2 plane Y/CbCr 4:2:2 formats. */
86#define S5P_FIMC_LSB_CRCB S5P_CIOCTRL_ORDER422_2P_LSB_CRCB
87
88/* The embedded image effect selection */
89#define S5P_FIMC_EFFECT_ORIGINAL S5P_CIIMGEFF_FIN_BYPASS
90#define S5P_FIMC_EFFECT_ARBITRARY S5P_CIIMGEFF_FIN_ARBITRARY
91#define S5P_FIMC_EFFECT_NEGATIVE S5P_CIIMGEFF_FIN_NEGATIVE
92#define S5P_FIMC_EFFECT_ARTFREEZE S5P_CIIMGEFF_FIN_ARTFREEZE
93#define S5P_FIMC_EFFECT_EMBOSSING S5P_CIIMGEFF_FIN_EMBOSSING
94#define S5P_FIMC_EFFECT_SIKHOUETTE S5P_CIIMGEFF_FIN_SILHOUETTE
95
96/* The hardware context state. */
548aafcd
SN
97#define FIMC_PARAMS (1 << 0)
98#define FIMC_SRC_ADDR (1 << 1)
99#define FIMC_DST_ADDR (1 << 2)
100#define FIMC_SRC_FMT (1 << 3)
101#define FIMC_DST_FMT (1 << 4)
102#define FIMC_CTX_M2M (1 << 5)
103#define FIMC_CTX_CAP (1 << 6)
5fd8f738
SN
104
105/* Image conversion flags */
106#define FIMC_IN_DMA_ACCESS_TILED (1 << 0)
107#define FIMC_IN_DMA_ACCESS_LINEAR (0 << 0)
108#define FIMC_OUT_DMA_ACCESS_TILED (1 << 1)
109#define FIMC_OUT_DMA_ACCESS_LINEAR (0 << 1)
110#define FIMC_SCAN_MODE_PROGRESSIVE (0 << 2)
111#define FIMC_SCAN_MODE_INTERLACED (1 << 2)
548aafcd
SN
112/*
113 * YCbCr data dynamic range for RGB-YUV color conversion.
114 * Y/Cb/Cr: (0 ~ 255) */
5fd8f738
SN
115#define FIMC_COLOR_RANGE_WIDE (0 << 3)
116/* Y (16 ~ 235), Cb/Cr (16 ~ 240) */
117#define FIMC_COLOR_RANGE_NARROW (1 << 3)
118
119#define FLIP_NONE 0
120#define FLIP_X_AXIS 1
121#define FLIP_Y_AXIS 2
122#define FLIP_XY_AXIS (FLIP_X_AXIS | FLIP_Y_AXIS)
123
124/**
125 * struct fimc_fmt - the driver's internal color format data
126 * @name: format description
127 * @fourcc: the fourcc code for this format
128 * @color: the corresponding fimc_color_fmt
129 * @depth: number of bits per pixel
130 * @buff_cnt: number of physically non-contiguous data planes
131 * @planes_cnt: number of physically contiguous data planes
132 */
133struct fimc_fmt {
134 char *name;
135 u32 fourcc;
136 u32 color;
137 u32 depth;
138 u16 buff_cnt;
139 u16 planes_cnt;
140};
141
142/**
143 * struct fimc_dma_offset - pixel offset information for DMA
144 * @y_h: y value horizontal offset
145 * @y_v: y value vertical offset
146 * @cb_h: cb value horizontal offset
147 * @cb_v: cb value vertical offset
148 * @cr_h: cr value horizontal offset
149 * @cr_v: cr value vertical offset
150 */
151struct fimc_dma_offset {
152 int y_h;
153 int y_v;
154 int cb_h;
155 int cb_v;
156 int cr_h;
157 int cr_v;
158};
159
160/**
161 * struct fimc_effect - the configuration data for the "Arbitrary" image effect
162 * @type: effect type
163 * @pat_cb: cr value when type is "arbitrary"
164 * @pat_cr: cr value when type is "arbitrary"
165 */
166struct fimc_effect {
167 u32 type;
168 u8 pat_cb;
169 u8 pat_cr;
170};
171
172/**
173 * struct fimc_scaler - the configuration data for FIMC inetrnal scaler
174 *
548aafcd
SN
175 * @scaleup_h: flag indicating scaling up horizontally
176 * @scaleup_v: flag indicating scaling up vertically
177 * @copy_mode: flag indicating transparent DMA transfer (no scaling
178 * and color format conversion)
179 * @enabled: flag indicating if the scaler is used
5fd8f738
SN
180 * @hfactor: horizontal shift factor
181 * @vfactor: vertical shift factor
182 * @pre_hratio: horizontal ratio of the prescaler
183 * @pre_vratio: vertical ratio of the prescaler
184 * @pre_dst_width: the prescaler's destination width
185 * @pre_dst_height: the prescaler's destination height
5fd8f738
SN
186 * @main_hratio: the main scaler's horizontal ratio
187 * @main_vratio: the main scaler's vertical ratio
548aafcd
SN
188 * @real_width: source pixel (width - offset)
189 * @real_height: source pixel (height - offset)
5fd8f738
SN
190 */
191struct fimc_scaler {
548aafcd
SN
192 int scaleup_h:1;
193 int scaleup_v:1;
194 int copy_mode:1;
195 int enabled:1;
5fd8f738
SN
196 u32 hfactor;
197 u32 vfactor;
198 u32 pre_hratio;
199 u32 pre_vratio;
200 u32 pre_dst_width;
201 u32 pre_dst_height;
5fd8f738
SN
202 u32 main_hratio;
203 u32 main_vratio;
204 u32 real_width;
205 u32 real_height;
5fd8f738
SN
206};
207
208/**
209 * struct fimc_addr - the FIMC physical address set for DMA
210 *
211 * @y: luminance plane physical address
212 * @cb: Cb plane physical address
213 * @cr: Cr plane physical address
214 */
215struct fimc_addr {
216 u32 y;
217 u32 cb;
218 u32 cr;
219};
220
221/**
222 * struct fimc_vid_buffer - the driver's video buffer
223 * @vb: v4l videobuf buffer
224 */
225struct fimc_vid_buffer {
226 struct videobuf_buffer vb;
227};
228
229/**
548aafcd 230 * struct fimc_frame - source/target frame properties
5fd8f738
SN
231 * @f_width: image full width (virtual screen size)
232 * @f_height: image full height (virtual screen size)
233 * @o_width: original image width as set by S_FMT
234 * @o_height: original image height as set by S_FMT
235 * @offs_h: image horizontal pixel offset
236 * @offs_v: image vertical pixel offset
237 * @width: image pixel width
238 * @height: image pixel weight
239 * @paddr: image frame buffer physical addresses
240 * @buf_cnt: number of buffers depending on a color format
241 * @size: image size in bytes
242 * @color: color format
243 * @dma_offset: DMA offset in bytes
244 */
245struct fimc_frame {
246 u32 f_width;
247 u32 f_height;
248 u32 o_width;
249 u32 o_height;
250 u32 offs_h;
251 u32 offs_v;
252 u32 width;
253 u32 height;
254 u32 size;
255 struct fimc_addr paddr;
256 struct fimc_dma_offset dma_offset;
257 struct fimc_fmt *fmt;
258};
259
260/**
261 * struct fimc_m2m_device - v4l2 memory-to-memory device data
262 * @vfd: the video device node for v4l2 m2m mode
263 * @v4l2_dev: v4l2 device for m2m mode
264 * @m2m_dev: v4l2 memory-to-memory device data
265 * @ctx: hardware context data
266 * @refcnt: the reference counter
267 */
268struct fimc_m2m_device {
269 struct video_device *vfd;
270 struct v4l2_device v4l2_dev;
271 struct v4l2_m2m_dev *m2m_dev;
272 struct fimc_ctx *ctx;
273 int refcnt;
274};
275
276/**
277 * struct samsung_fimc_variant - camera interface variant information
278 *
279 * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes
280 * @has_inp_rot: set if has input rotator
281 * @has_out_rot: set if has output rotator
282 * @min_inp_pixsize: minimum input pixel size
283 * @min_out_pixsize: minimum output pixel size
284 * @scaler_en_w: maximum input pixel width when the scaler is enabled
285 * @scaler_dis_w: maximum input pixel width when the scaler is disabled
548aafcd
SN
286 * @in_rot_en_h: maximum input width when the input rotator is enabled
287 * @in_rot_dis_w: maximum input width when the input rotator is disabled
288 * @out_rot_en_w: maximum target width when the output rotator enabled
289 * @out_rot_dis_w: maximum target width when the output rotator disnabled
5fd8f738
SN
290 */
291struct samsung_fimc_variant {
292 unsigned int pix_hoff:1;
293 unsigned int has_inp_rot:1;
294 unsigned int has_out_rot:1;
295
296 u16 min_inp_pixsize;
297 u16 min_out_pixsize;
298 u16 scaler_en_w;
299 u16 scaler_dis_w;
300 u16 in_rot_en_h;
301 u16 in_rot_dis_w;
302 u16 out_rot_en_w;
303 u16 out_rot_dis_w;
304};
305
306/**
548aafcd 307 * struct samsung_fimc_driverdata - per device type driver data for init time.
5fd8f738
SN
308 *
309 * @variant: the variant information for this driver.
310 * @dev_cnt: number of fimc sub-devices available in SoC
311 */
312struct samsung_fimc_driverdata {
313 struct samsung_fimc_variant *variant[FIMC_MAX_DEVS];
314 int devs_cnt;
315};
316
317struct fimc_ctx;
318
319/**
548aafcd 320 * struct fimc_dev - abstraction for FIMC entity
5fd8f738
SN
321 *
322 * @slock: the spinlock protecting this data structure
323 * @lock: the mutex protecting this data structure
324 * @pdev: pointer to the FIMC platform device
325 * @id: FIMC device index (0..2)
326 * @clock[]: the clocks required for FIMC operation
327 * @regs: the mapped hardware registers
328 * @regs_res: the resource claimed for IO registers
329 * @irq: interrupt number of the FIMC subdevice
548aafcd 330 * @irqlock: spinlock protecting videobuffer queue
5fd8f738
SN
331 * @m2m: memory-to-memory V4L2 device information
332 * @state: the FIMC device state flags
333 */
334struct fimc_dev {
335 spinlock_t slock;
336 struct mutex lock;
337 struct platform_device *pdev;
338 struct samsung_fimc_variant *variant;
339 int id;
340 struct clk *clock[NUM_FIMC_CLOCKS];
341 void __iomem *regs;
342 struct resource *regs_res;
343 int irq;
344 spinlock_t irqlock;
5fd8f738
SN
345 struct fimc_m2m_device m2m;
346 unsigned long state;
347};
348
349/**
350 * fimc_ctx - the device context data
351 *
352 * @lock: mutex protecting this data structure
353 * @s_frame: source frame properties
354 * @d_frame: destination frame properties
355 * @out_order_1p: output 1-plane YCBCR order
356 * @out_order_2p: output 2-plane YCBCR order
357 * @in_order_1p input 1-plane YCBCR order
358 * @in_order_2p: input 2-plane YCBCR order
359 * @in_path: input mode (DMA or camera)
360 * @out_path: output mode (DMA or FIFO)
361 * @scaler: image scaler properties
362 * @effect: image effect
363 * @rotation: image clockwise rotation in degrees
364 * @flip: image flip mode
548aafcd 365 * @flags: additional flags for image conversion
5fd8f738
SN
366 * @state: flags to keep track of user configuration
367 * @fimc_dev: the FIMC device this context applies to
368 * @m2m_ctx: memory-to-memory device context
369 */
370struct fimc_ctx {
371 spinlock_t slock;
372 struct fimc_frame s_frame;
373 struct fimc_frame d_frame;
374 u32 out_order_1p;
375 u32 out_order_2p;
376 u32 in_order_1p;
377 u32 in_order_2p;
378 enum fimc_datapath in_path;
379 enum fimc_datapath out_path;
380 struct fimc_scaler scaler;
381 struct fimc_effect effect;
382 int rotation;
383 u32 flip;
384 u32 flags;
385 u32 state;
386 struct fimc_dev *fimc_dev;
387 struct v4l2_m2m_ctx *m2m_ctx;
388};
389
390
391static inline int tiled_fmt(struct fimc_fmt *fmt)
392{
393 return 0;
394}
395
396static inline void fimc_hw_clear_irq(struct fimc_dev *dev)
397{
398 u32 cfg = readl(dev->regs + S5P_CIGCTRL);
399 cfg |= S5P_CIGCTRL_IRQ_CLR;
400 writel(cfg, dev->regs + S5P_CIGCTRL);
401}
402
548aafcd 403static inline void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on)
5fd8f738
SN
404{
405 u32 cfg = readl(dev->regs + S5P_CISCCTRL);
548aafcd
SN
406 if (on)
407 cfg |= S5P_CISCCTRL_SCALERSTART;
408 else
409 cfg &= ~S5P_CISCCTRL_SCALERSTART;
5fd8f738
SN
410 writel(cfg, dev->regs + S5P_CISCCTRL);
411}
412
548aafcd 413static inline void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on)
5fd8f738 414{
548aafcd
SN
415 u32 cfg = readl(dev->regs + S5P_MSCTRL);
416 if (on)
417 cfg |= S5P_MSCTRL_ENVID;
418 else
419 cfg &= ~S5P_MSCTRL_ENVID;
420 writel(cfg, dev->regs + S5P_MSCTRL);
5fd8f738
SN
421}
422
423static inline void fimc_hw_dis_capture(struct fimc_dev *dev)
424{
425 u32 cfg = readl(dev->regs + S5P_CIIMGCPT);
426 cfg &= ~(S5P_CIIMGCPT_IMGCPTEN | S5P_CIIMGCPT_IMGCPTEN_SC);
427 writel(cfg, dev->regs + S5P_CIIMGCPT);
428}
429
548aafcd
SN
430static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
431 enum v4l2_buf_type type)
03e30ca5
PO
432{
433 struct fimc_frame *frame;
434
435 if (V4L2_BUF_TYPE_VIDEO_OUTPUT == type) {
436 frame = &ctx->s_frame;
437 } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE == type) {
438 frame = &ctx->d_frame;
439 } else {
440 v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev,
441 "Wrong buffer/video queue type (%d)\n", type);
442 return ERR_PTR(-EINVAL);
443 }
444
445 return frame;
446}
447
5fd8f738
SN
448/* -----------------------------------------------------*/
449/* fimc-reg.c */
548aafcd 450void fimc_hw_reset(struct fimc_dev *fimc);
5fd8f738
SN
451void fimc_hw_set_rotation(struct fimc_ctx *ctx);
452void fimc_hw_set_target_format(struct fimc_ctx *ctx);
453void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
548aafcd
SN
454void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
455void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
5fd8f738
SN
456void fimc_hw_set_scaler(struct fimc_ctx *ctx);
457void fimc_hw_en_capture(struct fimc_ctx *ctx);
458void fimc_hw_set_effect(struct fimc_ctx *ctx);
459void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
460void fimc_hw_set_input_path(struct fimc_ctx *ctx);
461void fimc_hw_set_output_path(struct fimc_ctx *ctx);
548aafcd
SN
462void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr);
463void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr,
464 int index);
465
466/* Locking: the caller holds fimc->slock */
467static inline void fimc_activate_capture(struct fimc_ctx *ctx)
468{
469 fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled);
470 fimc_hw_en_capture(ctx);
471}
472
473static inline void fimc_deactivate_capture(struct fimc_dev *fimc)
474{
475 fimc_hw_en_lastirq(fimc, true);
476 fimc_hw_dis_capture(fimc);
477 fimc_hw_enable_scaler(fimc, false);
478 fimc_hw_en_lastirq(fimc, false);
479}
5fd8f738
SN
480
481#endif /* FIMC_CORE_H_ */
This page took 0.091436 seconds and 5 git commands to generate.