1
2
3
4
5
6
7
8
9#ifndef FIMC_CORE_H_
10#define FIMC_CORE_H_
11
12
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
21#include <media/media-entity.h>
22#include <media/videobuf2-core.h>
23#include <media/v4l2-ctrls.h>
24#include <media/v4l2-device.h>
25#include <media/v4l2-mem2mem.h>
26#include <media/v4l2-mediabus.h>
27#include <media/s5p_fimc.h>
28
29#include "regs-fimc.h"
30
31#define err(fmt, args...) \
32 printk(KERN_ERR "%s:%d: " fmt "\n", __func__, __LINE__, ##args)
33
34#define dbg(fmt, args...) \
35 pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args)
36
37
38#define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000)
39#define MAX_FIMC_CLOCKS 2
40#define FIMC_MODULE_NAME "s5p-fimc"
41#define FIMC_MAX_DEVS 4
42#define FIMC_MAX_OUT_BUFS 4
43#define SCALER_MAX_HRATIO 64
44#define SCALER_MAX_VRATIO 64
45#define DMA_MIN_SIZE 8
46#define FIMC_CAMIF_MAX_HEIGHT 0x2000
47
48
49enum {
50 CLK_BUS,
51 CLK_GATE,
52};
53
54enum fimc_dev_flags {
55 ST_LPM,
56
57 ST_M2M_RUN,
58 ST_M2M_PEND,
59 ST_M2M_SUSPENDING,
60 ST_M2M_SUSPENDED,
61
62 ST_CAPT_PEND,
63 ST_CAPT_RUN,
64 ST_CAPT_STREAM,
65 ST_CAPT_ISP_STREAM,
66 ST_CAPT_SUSPENDED,
67 ST_CAPT_SHUT,
68 ST_CAPT_BUSY,
69 ST_CAPT_APPLY_CFG,
70 ST_CAPT_JPEG,
71};
72
73#define fimc_m2m_active(dev) test_bit(ST_M2M_RUN, &(dev)->state)
74#define fimc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state)
75
76#define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state)
77#define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state)
78#define fimc_capture_busy(dev) test_bit(ST_CAPT_BUSY, &(dev)->state)
79
80enum fimc_datapath {
81 FIMC_CAMERA,
82 FIMC_DMA,
83 FIMC_LCDFIFO,
84 FIMC_WRITEBACK
85};
86
87enum fimc_color_fmt {
88 S5P_FIMC_RGB444 = 0x10,
89 S5P_FIMC_RGB555,
90 S5P_FIMC_RGB565,
91 S5P_FIMC_RGB666,
92 S5P_FIMC_RGB888,
93 S5P_FIMC_RGB30_LOCAL,
94 S5P_FIMC_YCBCR420 = 0x20,
95 S5P_FIMC_YCBYCR422,
96 S5P_FIMC_YCRYCB422,
97 S5P_FIMC_CBYCRY422,
98 S5P_FIMC_CRYCBY422,
99 S5P_FIMC_YCBCR444_LOCAL,
100 S5P_FIMC_JPEG = 0x40,
101};
102
103#define fimc_fmt_is_rgb(x) (!!((x) & 0x10))
104#define fimc_fmt_is_jpeg(x) (!!((x) & 0x40))
105
106#define IS_M2M(__strt) ((__strt) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || \
107 __strt == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
108
109
110#define S5P_FIMC_LSB_CRCB S5P_CIOCTRL_ORDER422_2P_LSB_CRCB
111
112
113#define S5P_FIMC_EFFECT_ORIGINAL S5P_CIIMGEFF_FIN_BYPASS
114#define S5P_FIMC_EFFECT_ARBITRARY S5P_CIIMGEFF_FIN_ARBITRARY
115#define S5P_FIMC_EFFECT_NEGATIVE S5P_CIIMGEFF_FIN_NEGATIVE
116#define S5P_FIMC_EFFECT_ARTFREEZE S5P_CIIMGEFF_FIN_ARTFREEZE
117#define S5P_FIMC_EFFECT_EMBOSSING S5P_CIIMGEFF_FIN_EMBOSSING
118#define S5P_FIMC_EFFECT_SIKHOUETTE S5P_CIIMGEFF_FIN_SILHOUETTE
119
120
121#define FIMC_PARAMS (1 << 0)
122#define FIMC_SRC_ADDR (1 << 1)
123#define FIMC_DST_ADDR (1 << 2)
124#define FIMC_SRC_FMT (1 << 3)
125#define FIMC_DST_FMT (1 << 4)
126#define FIMC_DST_CROP (1 << 5)
127#define FIMC_CTX_M2M (1 << 16)
128#define FIMC_CTX_CAP (1 << 17)
129#define FIMC_CTX_SHUT (1 << 18)
130
131
132#define FIMC_IN_DMA_ACCESS_TILED (1 << 0)
133#define FIMC_IN_DMA_ACCESS_LINEAR (0 << 0)
134#define FIMC_OUT_DMA_ACCESS_TILED (1 << 1)
135#define FIMC_OUT_DMA_ACCESS_LINEAR (0 << 1)
136#define FIMC_SCAN_MODE_PROGRESSIVE (0 << 2)
137#define FIMC_SCAN_MODE_INTERLACED (1 << 2)
138
139
140
141#define FIMC_COLOR_RANGE_WIDE (0 << 3)
142
143#define FIMC_COLOR_RANGE_NARROW (1 << 3)
144
145
146
147
148
149
150
151
152
153
154
155
156struct fimc_fmt {
157 enum v4l2_mbus_pixelcode mbus_code;
158 char *name;
159 u32 fourcc;
160 u32 color;
161 u16 memplanes;
162 u16 colplanes;
163 u8 depth[VIDEO_MAX_PLANES];
164 u16 flags;
165#define FMT_FLAGS_CAM (1 << 0)
166#define FMT_FLAGS_M2M_IN (1 << 1)
167#define FMT_FLAGS_M2M_OUT (1 << 2)
168#define FMT_FLAGS_M2M (1 << 1 | 1 << 2)
169#define FMT_HAS_ALPHA (1 << 3)
170};
171
172
173
174
175
176
177
178
179
180
181struct fimc_dma_offset {
182 int y_h;
183 int y_v;
184 int cb_h;
185 int cb_v;
186 int cr_h;
187 int cr_v;
188};
189
190
191
192
193
194
195
196struct fimc_effect {
197 u32 type;
198 u8 pat_cb;
199 u8 pat_cr;
200};
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220struct fimc_scaler {
221 unsigned int scaleup_h:1;
222 unsigned int scaleup_v:1;
223 unsigned int copy_mode:1;
224 unsigned int enabled:1;
225 u32 hfactor;
226 u32 vfactor;
227 u32 pre_hratio;
228 u32 pre_vratio;
229 u32 pre_dst_width;
230 u32 pre_dst_height;
231 u32 main_hratio;
232 u32 main_vratio;
233 u32 real_width;
234 u32 real_height;
235};
236
237
238
239
240
241
242
243struct fimc_addr {
244 u32 y;
245 u32 cb;
246 u32 cr;
247};
248
249
250
251
252
253
254
255
256struct fimc_vid_buffer {
257 struct vb2_buffer vb;
258 struct list_head list;
259 struct fimc_addr paddr;
260 int index;
261};
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278struct fimc_frame {
279 u32 f_width;
280 u32 f_height;
281 u32 o_width;
282 u32 o_height;
283 u32 offs_h;
284 u32 offs_v;
285 u32 width;
286 u32 height;
287 unsigned long payload[VIDEO_MAX_PLANES];
288 struct fimc_addr paddr;
289 struct fimc_dma_offset dma_offset;
290 struct fimc_fmt *fmt;
291 u8 alpha;
292};
293
294
295
296
297
298
299
300
301struct fimc_m2m_device {
302 struct video_device *vfd;
303 struct v4l2_m2m_dev *m2m_dev;
304 struct fimc_ctx *ctx;
305 int refcnt;
306};
307
308#define FIMC_SD_PAD_SINK 0
309#define FIMC_SD_PAD_SOURCE 1
310#define FIMC_SD_PADS_NUM 2
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332struct fimc_vid_cap {
333 struct fimc_ctx *ctx;
334 struct vb2_alloc_ctx *alloc_ctx;
335 struct video_device *vfd;
336 struct v4l2_subdev *subdev;
337 struct media_pad vd_pad;
338 struct v4l2_mbus_framefmt mf;
339 struct media_pad sd_pads[FIMC_SD_PADS_NUM];
340 struct list_head pending_buf_q;
341 struct list_head active_buf_q;
342 struct vb2_queue vbq;
343 int active_buf_cnt;
344 int buf_index;
345 unsigned int frame_count;
346 unsigned int reqbufs_count;
347 int input_index;
348 int refcnt;
349 u32 input;
350 bool user_subdev_api;
351};
352
353
354
355
356
357
358
359
360
361
362
363struct fimc_pix_limit {
364 u16 scaler_en_w;
365 u16 scaler_dis_w;
366 u16 in_rot_en_h;
367 u16 in_rot_dis_w;
368 u16 out_rot_en_w;
369 u16 out_rot_dis_w;
370};
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389struct samsung_fimc_variant {
390 unsigned int pix_hoff:1;
391 unsigned int has_inp_rot:1;
392 unsigned int has_out_rot:1;
393 unsigned int has_cistatus2:1;
394 unsigned int has_mainscaler_ext:1;
395 unsigned int has_cam_if:1;
396 unsigned int has_alpha:1;
397 struct fimc_pix_limit *pix_limit;
398 u16 min_inp_pixsize;
399 u16 min_out_pixsize;
400 u16 hor_offs_align;
401 u16 min_vsize_align;
402 u16 out_buf_count;
403};
404
405
406
407
408
409
410
411
412struct samsung_fimc_driverdata {
413 struct samsung_fimc_variant *variant[FIMC_MAX_DEVS];
414 unsigned long lclk_frequency;
415 int num_entities;
416};
417
418struct fimc_pipeline {
419 struct media_pipeline *pipe;
420 struct v4l2_subdev *sensor;
421 struct v4l2_subdev *csis;
422};
423
424struct fimc_ctx;
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447struct fimc_dev {
448 spinlock_t slock;
449 struct mutex lock;
450 struct platform_device *pdev;
451 struct s5p_platform_fimc *pdata;
452 struct samsung_fimc_variant *variant;
453 u16 id;
454 u16 num_clocks;
455 struct clk *clock[MAX_FIMC_CLOCKS];
456 void __iomem *regs;
457 struct resource *regs_res;
458 int irq;
459 wait_queue_head_t irq_queue;
460 struct v4l2_device *v4l2_dev;
461 struct fimc_m2m_device m2m;
462 struct fimc_vid_cap vid_cap;
463 unsigned long state;
464 struct vb2_alloc_ctx *alloc_ctx;
465 struct fimc_pipeline pipeline;
466};
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496struct fimc_ctx {
497 spinlock_t slock;
498 struct fimc_frame s_frame;
499 struct fimc_frame d_frame;
500 u32 out_order_1p;
501 u32 out_order_2p;
502 u32 in_order_1p;
503 u32 in_order_2p;
504 enum fimc_datapath in_path;
505 enum fimc_datapath out_path;
506 struct fimc_scaler scaler;
507 struct fimc_effect effect;
508 int rotation;
509 unsigned int hflip:1;
510 unsigned int vflip:1;
511 u32 flags;
512 u32 state;
513 struct fimc_dev *fimc_dev;
514 struct v4l2_m2m_ctx *m2m_ctx;
515 struct v4l2_fh fh;
516 struct v4l2_ctrl_handler ctrl_handler;
517 struct v4l2_ctrl *ctrl_rotate;
518 struct v4l2_ctrl *ctrl_hflip;
519 struct v4l2_ctrl *ctrl_vflip;
520 struct v4l2_ctrl *ctrl_alpha;
521 bool ctrls_rdy;
522};
523
524#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh)
525
526static inline void set_frame_bounds(struct fimc_frame *f, u32 width, u32 height)
527{
528 f->o_width = width;
529 f->o_height = height;
530 f->f_width = width;
531 f->f_height = height;
532}
533
534static inline void set_frame_crop(struct fimc_frame *f,
535 u32 left, u32 top, u32 width, u32 height)
536{
537 f->offs_h = left;
538 f->offs_v = top;
539 f->width = width;
540 f->height = height;
541}
542
543static inline u32 fimc_get_format_depth(struct fimc_fmt *ff)
544{
545 u32 i, depth = 0;
546
547 if (ff != NULL)
548 for (i = 0; i < ff->colplanes; i++)
549 depth += ff->depth[i];
550 return depth;
551}
552
553static inline bool fimc_capture_active(struct fimc_dev *fimc)
554{
555 unsigned long flags;
556 bool ret;
557
558 spin_lock_irqsave(&fimc->slock, flags);
559 ret = !!(fimc->state & (1 << ST_CAPT_RUN) ||
560 fimc->state & (1 << ST_CAPT_PEND));
561 spin_unlock_irqrestore(&fimc->slock, flags);
562 return ret;
563}
564
565static inline void fimc_ctx_state_lock_set(u32 state, struct fimc_ctx *ctx)
566{
567 unsigned long flags;
568
569 spin_lock_irqsave(&ctx->slock, flags);
570 ctx->state |= state;
571 spin_unlock_irqrestore(&ctx->slock, flags);
572}
573
574static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx)
575{
576 unsigned long flags;
577 bool ret;
578
579 spin_lock_irqsave(&ctx->slock, flags);
580 ret = (ctx->state & mask) == mask;
581 spin_unlock_irqrestore(&ctx->slock, flags);
582 return ret;
583}
584
585static inline int tiled_fmt(struct fimc_fmt *fmt)
586{
587 return fmt->fourcc == V4L2_PIX_FMT_NV12MT;
588}
589
590
591static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt)
592{
593 switch (fmt->color) {
594 case S5P_FIMC_RGB444: return 0x0f;
595 case S5P_FIMC_RGB555: return 0x01;
596 case S5P_FIMC_RGB888: return 0xff;
597 default: return 0;
598 };
599}
600
601static inline void fimc_hw_clear_irq(struct fimc_dev *dev)
602{
603 u32 cfg = readl(dev->regs + S5P_CIGCTRL);
604 cfg |= S5P_CIGCTRL_IRQ_CLR;
605 writel(cfg, dev->regs + S5P_CIGCTRL);
606}
607
608static inline void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on)
609{
610 u32 cfg = readl(dev->regs + S5P_CISCCTRL);
611 if (on)
612 cfg |= S5P_CISCCTRL_SCALERSTART;
613 else
614 cfg &= ~S5P_CISCCTRL_SCALERSTART;
615 writel(cfg, dev->regs + S5P_CISCCTRL);
616}
617
618static inline void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on)
619{
620 u32 cfg = readl(dev->regs + S5P_MSCTRL);
621 if (on)
622 cfg |= S5P_MSCTRL_ENVID;
623 else
624 cfg &= ~S5P_MSCTRL_ENVID;
625 writel(cfg, dev->regs + S5P_MSCTRL);
626}
627
628static inline void fimc_hw_dis_capture(struct fimc_dev *dev)
629{
630 u32 cfg = readl(dev->regs + S5P_CIIMGCPT);
631 cfg &= ~(S5P_CIIMGCPT_IMGCPTEN | S5P_CIIMGCPT_IMGCPTEN_SC);
632 writel(cfg, dev->regs + S5P_CIIMGCPT);
633}
634
635
636
637
638
639
640
641
642
643
644static inline void fimc_hw_set_dma_seq(struct fimc_dev *dev, u32 mask)
645{
646 writel(mask, dev->regs + S5P_CIFCNTSEQ);
647}
648
649static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
650 enum v4l2_buf_type type)
651{
652 struct fimc_frame *frame;
653
654 if (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE == type) {
655 if (fimc_ctx_state_is_set(FIMC_CTX_M2M, ctx))
656 frame = &ctx->s_frame;
657 else
658 return ERR_PTR(-EINVAL);
659 } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == type) {
660 frame = &ctx->d_frame;
661 } else {
662 v4l2_err(ctx->fimc_dev->v4l2_dev,
663 "Wrong buffer/video queue type (%d)\n", type);
664 return ERR_PTR(-EINVAL);
665 }
666
667 return frame;
668}
669
670
671static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
672{
673 u32 reg;
674
675 if (dev->variant->has_cistatus2) {
676 reg = readl(dev->regs + S5P_CISTATUS2) & 0x3F;
677 return reg > 0 ? --reg : reg;
678 } else {
679 reg = readl(dev->regs + S5P_CISTATUS);
680 return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
681 S5P_CISTATUS_FRAMECNT_SHIFT;
682 }
683}
684
685
686
687void fimc_hw_reset(struct fimc_dev *fimc);
688void fimc_hw_set_rotation(struct fimc_ctx *ctx);
689void fimc_hw_set_target_format(struct fimc_ctx *ctx);
690void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
691void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
692void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
693void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
694void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
695void fimc_hw_en_capture(struct fimc_ctx *ctx);
696void fimc_hw_set_effect(struct fimc_ctx *ctx, bool active);
697void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx);
698void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
699void fimc_hw_set_input_path(struct fimc_ctx *ctx);
700void fimc_hw_set_output_path(struct fimc_ctx *ctx);
701void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr);
702void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr,
703 int index);
704int fimc_hw_set_camera_source(struct fimc_dev *fimc,
705 struct s5p_fimc_isp_info *cam);
706int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f);
707int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
708 struct s5p_fimc_isp_info *cam);
709int fimc_hw_set_camera_type(struct fimc_dev *fimc,
710 struct s5p_fimc_isp_info *cam);
711
712
713
714int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
715 struct v4l2_fmtdesc *f);
716int fimc_ctrls_create(struct fimc_ctx *ctx);
717void fimc_ctrls_delete(struct fimc_ctx *ctx);
718void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active);
719void fimc_alpha_ctrl_update(struct fimc_ctx *ctx);
720int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f);
721void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
722 struct v4l2_pix_format_mplane *pix);
723struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code,
724 unsigned int mask, int index);
725
726int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
727 int dw, int dh, int rotation);
728int fimc_set_scaler_info(struct fimc_ctx *ctx);
729int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags);
730int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
731 struct fimc_frame *frame, struct fimc_addr *paddr);
732void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f);
733void fimc_set_yuv_order(struct fimc_ctx *ctx);
734void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f);
735void fimc_capture_irq_handler(struct fimc_dev *fimc, bool done);
736
737int fimc_register_m2m_device(struct fimc_dev *fimc,
738 struct v4l2_device *v4l2_dev);
739void fimc_unregister_m2m_device(struct fimc_dev *fimc);
740int fimc_register_driver(void);
741void fimc_unregister_driver(void);
742
743
744
745int fimc_register_capture_device(struct fimc_dev *fimc,
746 struct v4l2_device *v4l2_dev);
747void fimc_unregister_capture_device(struct fimc_dev *fimc);
748int fimc_capture_ctrls_create(struct fimc_dev *fimc);
749int fimc_vid_cap_buf_queue(struct fimc_dev *fimc,
750 struct fimc_vid_buffer *fimc_vb);
751void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
752 void *arg);
753int fimc_capture_suspend(struct fimc_dev *fimc);
754int fimc_capture_resume(struct fimc_dev *fimc);
755int fimc_capture_config_update(struct fimc_ctx *ctx);
756
757
758static inline void fimc_activate_capture(struct fimc_ctx *ctx)
759{
760 fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled);
761 fimc_hw_en_capture(ctx);
762}
763
764static inline void fimc_deactivate_capture(struct fimc_dev *fimc)
765{
766 fimc_hw_en_lastirq(fimc, true);
767 fimc_hw_dis_capture(fimc);
768 fimc_hw_enable_scaler(fimc, false);
769 fimc_hw_en_lastirq(fimc, false);
770}
771
772
773
774
775
776
777
778
779
780static inline void fimc_active_queue_add(struct fimc_vid_cap *vid_cap,
781 struct fimc_vid_buffer *buf)
782{
783 list_add_tail(&buf->list, &vid_cap->active_buf_q);
784 vid_cap->active_buf_cnt++;
785}
786
787
788
789
790
791
792static inline struct fimc_vid_buffer *fimc_active_queue_pop(
793 struct fimc_vid_cap *vid_cap)
794{
795 struct fimc_vid_buffer *buf;
796 buf = list_entry(vid_cap->active_buf_q.next,
797 struct fimc_vid_buffer, list);
798 list_del(&buf->list);
799 vid_cap->active_buf_cnt--;
800 return buf;
801}
802
803
804
805
806
807static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap,
808 struct fimc_vid_buffer *buf)
809{
810 list_add_tail(&buf->list, &vid_cap->pending_buf_q);
811}
812
813
814
815
816
817
818static inline struct fimc_vid_buffer *fimc_pending_queue_pop(
819 struct fimc_vid_cap *vid_cap)
820{
821 struct fimc_vid_buffer *buf;
822 buf = list_entry(vid_cap->pending_buf_q.next,
823 struct fimc_vid_buffer, list);
824 list_del(&buf->list);
825 return buf;
826}
827
828#endif
829