Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 {
50 };
51 
54  /* m2m node */
59  /* capture node */
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 
85 };
86 
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 {
150  char *name;
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 
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 {
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;
229 };
230 
237 struct fimc_addr {
241 };
242 
251  struct vb2_buffer vb;
252  struct list_head list;
253  struct fimc_addr paddr;
254  int index;
255 };
256 
272 struct fimc_frame {
281  unsigned int payload[VIDEO_MAX_PLANES];
282  struct fimc_addr paddr;
284  struct fimc_fmt *fmt;
286 };
287 
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;
332  struct v4l2_mbus_framefmt mf;
336  struct vb2_queue vbq;
339  unsigned int frame_count;
340  unsigned int reqbufs_count;
342  int refcnt;
345 };
346 
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;
396 };
397 
404 struct fimc_drvdata {
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 {
435  struct mutex lock;
441  void __iomem *regs;
446  unsigned long state;
447  struct vb2_alloc_ctx *alloc_ctx;
450 };
451 
463 struct fimc_ctrls {
465  struct {
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 {
509  int rotation;
510  unsigned int hflip:1;
511  unsigned int vflip:1;
516  struct v4l2_fh fh;
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,
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 ||
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);
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_ */