Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
media
platform
s5p-fimc
fimc-core.h
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
3
*
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License version 2 as
6
* published by the Free Software Foundation.
7
*/
8
9
#ifndef FIMC_CORE_H_
10
#define FIMC_CORE_H_
11
12
/*#define DEBUG*/
13
14
#include <
linux/platform_device.h
>
15
#include <linux/sched.h>
16
#include <
linux/spinlock.h
>
17
#include <linux/types.h>
18
#include <linux/videodev2.h>
19
#include <
linux/io.h
>
20
#include <
linux/sizes.h
>
21
22
#include <
media/media-entity.h
>
23
#include <
media/videobuf2-core.h
>
24
#include <
media/v4l2-ctrls.h
>
25
#include <
media/v4l2-device.h
>
26
#include <
media/v4l2-mem2mem.h
>
27
#include <
media/v4l2-mediabus.h
>
28
#include <
media/s5p_fimc.h
>
29
30
#define dbg(fmt, args...) \
31
pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args)
32
33
/* Time to wait for next frame VSYNC interrupt while stopping operation. */
34
#define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000)
35
#define MAX_FIMC_CLOCKS 2
36
#define FIMC_MODULE_NAME "s5p-fimc"
37
#define FIMC_MAX_DEVS 4
38
#define FIMC_MAX_OUT_BUFS 4
39
#define SCALER_MAX_HRATIO 64
40
#define SCALER_MAX_VRATIO 64
41
#define DMA_MIN_SIZE 8
42
#define FIMC_CAMIF_MAX_HEIGHT 0x2000
43
#define FIMC_MAX_JPEG_BUF_SIZE (10 * SZ_1M)
44
#define FIMC_MAX_PLANES 3
45
46
/* indices to the clocks array */
47
enum
{
48
CLK_BUS
,
49
CLK_GATE
,
50
};
51
52
enum
fimc_dev_flags
{
53
ST_LPM
,
54
/* m2m node */
55
ST_M2M_RUN
,
56
ST_M2M_PEND
,
57
ST_M2M_SUSPENDING
,
58
ST_M2M_SUSPENDED
,
59
/* capture node */
60
ST_CAPT_PEND
,
61
ST_CAPT_RUN
,
62
ST_CAPT_STREAM
,
63
ST_CAPT_ISP_STREAM
,
64
ST_CAPT_SUSPENDED
,
65
ST_CAPT_SHUT
,
66
ST_CAPT_BUSY
,
67
ST_CAPT_APPLY_CFG
,
68
ST_CAPT_JPEG
,
69
};
70
71
#define fimc_m2m_active(dev) test_bit(ST_M2M_RUN, &(dev)->state)
72
#define fimc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state)
73
74
#define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state)
75
#define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state)
76
#define fimc_capture_busy(dev) test_bit(ST_CAPT_BUSY, &(dev)->state)
77
78
enum
fimc_datapath
{
79
FIMC_IO_NONE
,
80
FIMC_IO_CAMERA
,
81
FIMC_IO_DMA
,
82
FIMC_IO_LCDFIFO
,
83
FIMC_IO_WRITEBACK
,
84
FIMC_IO_ISP
,
85
};
86
87
enum
fimc_color_fmt
{
88
FIMC_FMT_RGB444
= 0x10,
89
FIMC_FMT_RGB555
,
90
FIMC_FMT_RGB565
,
91
FIMC_FMT_RGB666
,
92
FIMC_FMT_RGB888
,
93
FIMC_FMT_RGB30_LOCAL
,
94
FIMC_FMT_YCBCR420
= 0x20,
95
FIMC_FMT_YCBYCR422
,
96
FIMC_FMT_YCRYCB422
,
97
FIMC_FMT_CBYCRY422
,
98
FIMC_FMT_CRYCBY422
,
99
FIMC_FMT_YCBCR444_LOCAL
,
100
FIMC_FMT_RAW8
= 0x40,
101
FIMC_FMT_RAW10
,
102
FIMC_FMT_RAW12
,
103
FIMC_FMT_JPEG
= 0x80,
104
FIMC_FMT_YUYV_JPEG
= 0x100,
105
};
106
107
#define fimc_fmt_is_user_defined(x) (!!((x) & 0x180))
108
#define fimc_fmt_is_rgb(x) (!!((x) & 0x10))
109
110
#define IS_M2M(__strt) ((__strt) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || \
111
__strt == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
112
113
/* The hardware context state. */
114
#define FIMC_PARAMS (1 << 0)
115
#define FIMC_SRC_FMT (1 << 3)
116
#define FIMC_DST_FMT (1 << 4)
117
#define FIMC_COMPOSE (1 << 5)
118
#define FIMC_CTX_M2M (1 << 16)
119
#define FIMC_CTX_CAP (1 << 17)
120
#define FIMC_CTX_SHUT (1 << 18)
121
122
/* Image conversion flags */
123
#define FIMC_IN_DMA_ACCESS_TILED (1 << 0)
124
#define FIMC_IN_DMA_ACCESS_LINEAR (0 << 0)
125
#define FIMC_OUT_DMA_ACCESS_TILED (1 << 1)
126
#define FIMC_OUT_DMA_ACCESS_LINEAR (0 << 1)
127
#define FIMC_SCAN_MODE_PROGRESSIVE (0 << 2)
128
#define FIMC_SCAN_MODE_INTERLACED (1 << 2)
129
/*
130
* YCbCr data dynamic range for RGB-YUV color conversion.
131
* Y/Cb/Cr: (0 ~ 255) */
132
#define FIMC_COLOR_RANGE_WIDE (0 << 3)
133
/* Y (16 ~ 235), Cb/Cr (16 ~ 240) */
134
#define FIMC_COLOR_RANGE_NARROW (1 << 3)
135
148
struct
fimc_fmt
{
149
enum
v4l2_mbus_pixelcode
mbus_code
;
150
char
*
name
;
151
u32
fourcc
;
152
u32
color
;
153
u16
memplanes
;
154
u16
colplanes
;
155
u8
depth
[
VIDEO_MAX_PLANES
];
156
u16
mdataplanes
;
157
u16
flags
;
158
#define FMT_FLAGS_CAM (1 << 0)
159
#define FMT_FLAGS_M2M_IN (1 << 1)
160
#define FMT_FLAGS_M2M_OUT (1 << 2)
161
#define FMT_FLAGS_M2M (1 << 1 | 1 << 2)
162
#define FMT_HAS_ALPHA (1 << 3)
163
#define FMT_FLAGS_COMPRESSED (1 << 4)
164
};
165
175
struct
fimc_dma_offset
{
176
int
y_h
;
177
int
y_v
;
178
int
cb_h
;
179
int
cb_v
;
180
int
cr_h
;
181
int
cr_v
;
182
};
183
190
struct
fimc_effect
{
191
u32
type
;
192
u8
pat_cb
;
193
u8
pat_cr
;
194
};
195
214
struct
fimc_scaler
{
215
unsigned
int
scaleup_h
:1;
216
unsigned
int
scaleup_v
:1;
217
unsigned
int
copy_mode
:1;
218
unsigned
int
enabled
:1;
219
u32
hfactor
;
220
u32
vfactor
;
221
u32
pre_hratio
;
222
u32
pre_vratio
;
223
u32
pre_dst_width
;
224
u32
pre_dst_height
;
225
u32
main_hratio
;
226
u32
main_vratio
;
227
u32
real_width
;
228
u32
real_height
;
229
};
230
237
struct
fimc_addr
{
238
u32
y
;
239
u32
cb
;
240
u32
cr
;
241
};
242
250
struct
fimc_vid_buffer
{
251
struct
vb2_buffer
vb
;
252
struct
list_head
list
;
253
struct
fimc_addr
paddr
;
254
int
index
;
255
};
256
272
struct
fimc_frame
{
273
u32
f_width
;
274
u32
f_height
;
275
u32
o_width
;
276
u32
o_height
;
277
u32
offs_h
;
278
u32
offs_v
;
279
u32
width
;
280
u32
height
;
281
unsigned
int
payload
[
VIDEO_MAX_PLANES
];
282
struct
fimc_addr
paddr
;
283
struct
fimc_dma_offset
dma_offset
;
284
struct
fimc_fmt
*
fmt
;
285
u8
alpha
;
286
};
287
295
struct
fimc_m2m_device
{
296
struct
video_device
vfd
;
297
struct
v4l2_m2m_dev
*
m2m_dev
;
298
struct
fimc_ctx
*
ctx
;
299
int
refcnt
;
300
};
301
302
#define FIMC_SD_PAD_SINK 0
303
#define FIMC_SD_PAD_SOURCE 1
304
#define FIMC_SD_PADS_NUM 2
305
326
struct
fimc_vid_cap
{
327
struct
fimc_ctx
*
ctx
;
328
struct
vb2_alloc_ctx *
alloc_ctx
;
329
struct
video_device
vfd
;
330
struct
v4l2_subdev
subdev
;
331
struct
media_pad
vd_pad
;
332
struct
v4l2_mbus_framefmt
mf
;
333
struct
media_pad
sd_pads
[
FIMC_SD_PADS_NUM
];
334
struct
list_head
pending_buf_q
;
335
struct
list_head
active_buf_q
;
336
struct
vb2_queue
vbq
;
337
int
active_buf_cnt
;
338
int
buf_index
;
339
unsigned
int
frame_count
;
340
unsigned
int
reqbufs_count
;
341
int
input_index
;
342
int
refcnt
;
343
u32
input
;
344
bool
user_subdev_api
;
345
};
346
357
struct
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
382
struct
fimc_variant
{
383
unsigned
int
pix_hoff
:1;
384
unsigned
int
has_inp_rot
:1;
385
unsigned
int
has_out_rot
:1;
386
unsigned
int
has_cistatus2
:1;
387
unsigned
int
has_mainscaler_ext
:1;
388
unsigned
int
has_cam_if
:1;
389
unsigned
int
has_alpha
:1;
390
struct
fimc_pix_limit
*
pix_limit
;
391
u16
min_inp_pixsize
;
392
u16
min_out_pixsize
;
393
u16
hor_offs_align
;
394
u16
min_vsize_align
;
395
u16
out_buf_count
;
396
};
397
404
struct
fimc_drvdata
{
405
struct
fimc_variant
*
variant
[
FIMC_MAX_DEVS
];
406
int
num_entities
;
407
unsigned
long
lclk_frequency
;
408
};
409
410
#define fimc_get_drvdata(_pdev) \
411
((struct fimc_drvdata *) platform_get_device_id(_pdev)->driver_data)
412
413
struct
fimc_ctx
;
414
433
struct
fimc_dev
{
434
spinlock_t
slock
;
435
struct
mutex
lock
;
436
struct
platform_device
*
pdev
;
437
struct
s5p_platform_fimc
*
pdata
;
438
struct
fimc_variant
*
variant
;
439
u16
id
;
440
struct
clk
*
clock
[
MAX_FIMC_CLOCKS
];
441
void
__iomem
*
regs
;
442
wait_queue_head_t
irq_queue
;
443
struct
v4l2_device
*
v4l2_dev
;
444
struct
fimc_m2m_device
m2m
;
445
struct
fimc_vid_cap
vid_cap
;
446
unsigned
long
state
;
447
struct
vb2_alloc_ctx *
alloc_ctx
;
448
struct
fimc_pipeline
pipeline
;
449
const
struct
fimc_pipeline_ops
*
pipeline_ops
;
450
};
451
463
struct
fimc_ctrls
{
464
struct
v4l2_ctrl_handler
handler
;
465
struct
{
466
struct
v4l2_ctrl
*
colorfx
;
467
struct
v4l2_ctrl
*
colorfx_cbcr
;
468
};
469
struct
v4l2_ctrl
*
rotate
;
470
struct
v4l2_ctrl
*
hflip
;
471
struct
v4l2_ctrl
*
vflip
;
472
struct
v4l2_ctrl
*
alpha
;
473
bool
ready
;
474
};
475
498
struct
fimc_ctx
{
499
struct
fimc_frame
s_frame
;
500
struct
fimc_frame
d_frame
;
501
u32
out_order_1p
;
502
u32
out_order_2p
;
503
u32
in_order_1p
;
504
u32
in_order_2p
;
505
enum
fimc_datapath
in_path
;
506
enum
fimc_datapath
out_path
;
507
struct
fimc_scaler
scaler
;
508
struct
fimc_effect
effect
;
509
int
rotation
;
510
unsigned
int
hflip
:1;
511
unsigned
int
vflip
:1;
512
u32
flags
;
513
u32
state
;
514
struct
fimc_dev
*
fimc_dev
;
515
struct
v4l2_m2m_ctx
*
m2m_ctx
;
516
struct
v4l2_fh
fh
;
517
struct
fimc_ctrls
ctrls
;
518
};
519
520
#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh)
521
522
static
inline
void
set_frame_bounds(
struct
fimc_frame
*
f
,
u32
width
,
u32
height
)
523
{
524
f->
o_width
=
width
;
525
f->
o_height
=
height
;
526
f->
f_width
=
width
;
527
f->
f_height
=
height
;
528
}
529
530
static
inline
void
set_frame_crop(
struct
fimc_frame
*
f
,
531
u32
left
,
u32
top
,
u32
width
,
u32
height
)
532
{
533
f->
offs_h
=
left
;
534
f->
offs_v
=
top
;
535
f->
width
=
width
;
536
f->
height
=
height
;
537
}
538
539
static
inline
u32
fimc_get_format_depth(
struct
fimc_fmt
*ff)
540
{
541
u32
i
,
depth
= 0;
542
543
if
(ff !=
NULL
)
544
for
(i = 0; i < ff->
colplanes
; i++)
545
depth += ff->
depth
[i];
546
return
depth;
547
}
548
549
static
inline
bool
fimc_capture_active(
struct
fimc_dev
*fimc)
550
{
551
unsigned
long
flags
;
552
bool
ret
;
553
554
spin_lock_irqsave
(&fimc->
slock
, flags);
555
ret = !!(fimc->
state
& (1 <<
ST_CAPT_RUN
) ||
556
fimc->
state
& (1 <<
ST_CAPT_PEND
));
557
spin_unlock_irqrestore(&fimc->
slock
, flags);
558
return
ret
;
559
}
560
561
static
inline
void
fimc_ctx_state_set(
u32
state
,
struct
fimc_ctx
*
ctx
)
562
{
563
unsigned
long
flags
;
564
565
spin_lock_irqsave
(&ctx->
fimc_dev
->slock, flags);
566
ctx->
state
|=
state
;
567
spin_unlock_irqrestore(&ctx->
fimc_dev
->slock, flags);
568
}
569
570
static
inline
bool
fimc_ctx_state_is_set(
u32
mask
,
struct
fimc_ctx
*
ctx
)
571
{
572
unsigned
long
flags
;
573
bool
ret
;
574
575
spin_lock_irqsave
(&ctx->
fimc_dev
->slock, flags);
576
ret = (ctx->
state
&
mask
) == mask;
577
spin_unlock_irqrestore(&ctx->
fimc_dev
->slock, flags);
578
return
ret
;
579
}
580
581
static
inline
int
tiled_fmt(
struct
fimc_fmt
*
fmt
)
582
{
583
return
fmt->
fourcc
==
V4L2_PIX_FMT_NV12MT
;
584
}
585
586
static
inline
bool
fimc_jpeg_fourcc(
u32
pixelformat
)
587
{
588
return
(pixelformat ==
V4L2_PIX_FMT_JPEG
||
589
pixelformat ==
V4L2_PIX_FMT_S5C_UYVY_JPG
);
590
}
591
592
static
inline
bool
fimc_user_defined_mbus_fmt(
u32
code
)
593
{
594
return
(code ==
V4L2_MBUS_FMT_JPEG_1X8
||
595
code ==
V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8
);
596
}
597
598
/* Return the alpha component bit mask */
599
static
inline
int
fimc_get_alpha_mask(
struct
fimc_fmt
*
fmt
)
600
{
601
switch
(fmt->
color
) {
602
case
FIMC_FMT_RGB444
:
return
0x0f;
603
case
FIMC_FMT_RGB555
:
return
0x01;
604
case
FIMC_FMT_RGB888
:
return
0xff;
605
default
:
return
0;
606
};
607
}
608
609
static
inline
struct
fimc_frame
*ctx_get_frame(
struct
fimc_ctx
*
ctx
,
610
enum
v4l2_buf_type
type
)
611
{
612
struct
fimc_frame
*
frame
;
613
614
if
(
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
== type) {
615
if
(fimc_ctx_state_is_set(
FIMC_CTX_M2M
, ctx))
616
frame = &ctx->
s_frame
;
617
else
618
return
ERR_PTR(-
EINVAL
);
619
}
else
if
(
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
== type) {
620
frame = &ctx->
d_frame
;
621
}
else
{
622
v4l2_err
(ctx->
fimc_dev
->v4l2_dev,
623
"Wrong buffer/video queue type (%d)\n"
, type);
624
return
ERR_PTR(-
EINVAL
);
625
}
626
627
return
frame
;
628
}
629
630
/* -----------------------------------------------------*/
631
/* fimc-core.c */
632
int
fimc_vidioc_enum_fmt_mplane
(
struct
file
*
file
,
void
*
priv
,
633
struct
v4l2_fmtdesc
*
f
);
634
int
fimc_ctrls_create
(
struct
fimc_ctx
*ctx);
635
void
fimc_ctrls_delete
(
struct
fimc_ctx
*ctx);
636
void
fimc_ctrls_activate
(
struct
fimc_ctx
*ctx,
bool
active
);
637
void
fimc_alpha_ctrl_update
(
struct
fimc_ctx
*ctx);
638
int
fimc_fill_format
(
struct
fimc_frame
*frame,
struct
v4l2_format
*
f
);
639
void
fimc_adjust_mplane_format
(
struct
fimc_fmt
*fmt,
u32
width
,
u32
height
,
640
struct
v4l2_pix_format_mplane
*pix);
641
struct
fimc_fmt
*
fimc_find_format
(
const
u32
*pixelformat,
const
u32
*
mbus_code
,
642
unsigned
int
mask
,
int
index
);
643
struct
fimc_fmt
*
fimc_get_format
(
unsigned
int
index
);
644
645
int
fimc_check_scaler_ratio
(
struct
fimc_ctx
*ctx,
int
sw
,
int
sh,
646
int
dw,
int
dh,
int
rotation);
647
int
fimc_set_scaler_info
(
struct
fimc_ctx
*ctx);
648
int
fimc_prepare_config
(
struct
fimc_ctx
*ctx,
u32
flags
);
649
int
fimc_prepare_addr
(
struct
fimc_ctx
*ctx,
struct
vb2_buffer
*vb,
650
struct
fimc_frame
*frame,
struct
fimc_addr
*
paddr
);
651
void
fimc_prepare_dma_offset
(
struct
fimc_ctx
*ctx,
struct
fimc_frame
*
f
);
652
void
fimc_set_yuv_order
(
struct
fimc_ctx
*ctx);
653
void
fimc_fill_frame
(
struct
fimc_frame
*frame,
struct
v4l2_format
*
f
);
654
void
fimc_capture_irq_handler
(
struct
fimc_dev
*fimc,
int
deq_buf);
655
656
int
fimc_register_m2m_device
(
struct
fimc_dev
*fimc,
657
struct
v4l2_device
*v4l2_dev);
658
void
fimc_unregister_m2m_device
(
struct
fimc_dev
*fimc);
659
int
fimc_register_driver
(
void
);
660
void
fimc_unregister_driver
(
void
);
661
662
/* -----------------------------------------------------*/
663
/* fimc-m2m.c */
664
void
fimc_m2m_job_finish
(
struct
fimc_ctx
*ctx,
int
vb_state);
665
666
/* -----------------------------------------------------*/
667
/* fimc-capture.c */
668
int
fimc_initialize_capture_subdev
(
struct
fimc_dev
*fimc);
669
void
fimc_unregister_capture_subdev
(
struct
fimc_dev
*fimc);
670
int
fimc_capture_ctrls_create
(
struct
fimc_dev
*fimc);
671
void
fimc_sensor_notify
(
struct
v4l2_subdev
*
sd
,
unsigned
int
notification
,
672
void
*
arg
);
673
int
fimc_capture_suspend
(
struct
fimc_dev
*fimc);
674
int
fimc_capture_resume
(
struct
fimc_dev
*fimc);
675
676
/*
677
* Buffer list manipulation functions. Must be called with fimc.slock held.
678
*/
679
684
static
inline
void
fimc_active_queue_add(
struct
fimc_vid_cap
*vid_cap,
685
struct
fimc_vid_buffer
*
buf
)
686
{
687
list_add_tail
(&buf->
list
, &vid_cap->
active_buf_q
);
688
vid_cap->
active_buf_cnt
++;
689
}
690
696
static
inline
struct
fimc_vid_buffer
*fimc_active_queue_pop(
697
struct
fimc_vid_cap
*vid_cap)
698
{
699
struct
fimc_vid_buffer
*
buf
;
700
buf =
list_entry
(vid_cap->
active_buf_q
.next,
701
struct
fimc_vid_buffer
,
list
);
702
list_del
(&buf->
list
);
703
vid_cap->
active_buf_cnt
--;
704
return
buf
;
705
}
706
711
static
inline
void
fimc_pending_queue_add(
struct
fimc_vid_cap
*vid_cap,
712
struct
fimc_vid_buffer
*
buf
)
713
{
714
list_add_tail
(&buf->
list
, &vid_cap->
pending_buf_q
);
715
}
716
722
static
inline
struct
fimc_vid_buffer
*fimc_pending_queue_pop(
723
struct
fimc_vid_cap
*vid_cap)
724
{
725
struct
fimc_vid_buffer
*
buf
;
726
buf =
list_entry
(vid_cap->
pending_buf_q
.next,
727
struct
fimc_vid_buffer
,
list
);
728
list_del
(&buf->
list
);
729
return
buf
;
730
}
731
732
#endif
/* FIMC_CORE_H_ */
Generated on Thu Jan 10 2013 13:03:24 for Linux Kernel by
1.8.2