1/* 2 * Copyright (C) 2010 - 2011 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 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/* Time to wait for next frame VSYNC interrupt while stopping operation. */ 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/* indices to the clocks array */ 49enum { 50 CLK_BUS, 51 CLK_GATE, 52}; 53 54enum fimc_dev_flags { 55 ST_LPM, 56 /* m2m node */ 57 ST_M2M_RUN, 58 ST_M2M_PEND, 59 ST_M2M_SUSPENDING, 60 ST_M2M_SUSPENDED, 61 /* capture node */ 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/* Cb/Cr chrominance components order for 2 plane Y/CbCr 4:2:2 formats. */ 110#define S5P_FIMC_LSB_CRCB S5P_CIOCTRL_ORDER422_2P_LSB_CRCB 111 112/* The embedded image effect selection */ 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/* The hardware context state. */ 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/* Image conversion flags */ 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 * YCbCr data dynamic range for RGB-YUV color conversion. 140 * Y/Cb/Cr: (0 ~ 255) */ 141#define FIMC_COLOR_RANGE_WIDE (0 << 3) 142/* Y (16 ~ 235), Cb/Cr (16 ~ 240) */ 143#define FIMC_COLOR_RANGE_NARROW (1 << 3) 144 145/** 146 * struct fimc_fmt - the driver's internal color format data 147 * @mbus_code: Media Bus pixel code, -1 if not applicable 148 * @name: format description 149 * @fourcc: the fourcc code for this format, 0 if not applicable 150 * @color: the corresponding fimc_color_fmt 151 * @memplanes: number of physically non-contiguous data planes 152 * @colplanes: number of physically contiguous data planes 153 * @depth: per plane driver's private 'number of bits per pixel' 154 * @flags: flags indicating which operation mode format applies to 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 * struct fimc_dma_offset - pixel offset information for DMA 174 * @y_h: y value horizontal offset 175 * @y_v: y value vertical offset 176 * @cb_h: cb value horizontal offset 177 * @cb_v: cb value vertical offset 178 * @cr_h: cr value horizontal offset 179 * @cr_v: cr value vertical offset 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 * struct fimc_effect - color effect information 192 * @type: effect type 193 * @pat_cb: cr value when type is "arbitrary" 194 * @pat_cr: cr value when type is "arbitrary" 195 */ 196struct fimc_effect { 197 u32 type; 198 u8 pat_cb; 199 u8 pat_cr; 200}; 201 202/** 203 * struct fimc_scaler - the configuration data for FIMC inetrnal scaler 204 * @scaleup_h: flag indicating scaling up horizontally 205 * @scaleup_v: flag indicating scaling up vertically 206 * @copy_mode: flag indicating transparent DMA transfer (no scaling 207 * and color format conversion) 208 * @enabled: flag indicating if the scaler is used 209 * @hfactor: horizontal shift factor 210 * @vfactor: vertical shift factor 211 * @pre_hratio: horizontal ratio of the prescaler 212 * @pre_vratio: vertical ratio of the prescaler 213 * @pre_dst_width: the prescaler's destination width 214 * @pre_dst_height: the prescaler's destination height 215 * @main_hratio: the main scaler's horizontal ratio 216 * @main_vratio: the main scaler's vertical ratio 217 * @real_width: source pixel (width - offset) 218 * @real_height: source pixel (height - offset) 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 * struct fimc_addr - the FIMC physical address set for DMA 239 * @y: luminance plane physical address 240 * @cb: Cb plane physical address 241 * @cr: Cr plane physical address 242 */ 243struct fimc_addr { 244 u32 y; 245 u32 cb; 246 u32 cr; 247}; 248 249/** 250 * struct fimc_vid_buffer - the driver's video buffer 251 * @vb: v4l videobuf buffer 252 * @list: linked list structure for buffer queue 253 * @paddr: precalculated physical address set 254 * @index: buffer index for the output DMA engine 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 * struct fimc_frame - source/target frame properties 265 * @f_width: image full width (virtual screen size) 266 * @f_height: image full height (virtual screen size) 267 * @o_width: original image width as set by S_FMT 268 * @o_height: original image height as set by S_FMT 269 * @offs_h: image horizontal pixel offset 270 * @offs_v: image vertical pixel offset 271 * @width: image pixel width 272 * @height: image pixel weight 273 * @payload: image size in bytes (w x h x bpp) 274 * @paddr: image frame buffer physical addresses 275 * @dma_offset: DMA offset in bytes 276 * @fmt: fimc color format pointer 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 * struct fimc_m2m_device - v4l2 memory-to-memory device data 296 * @vfd: the video device node for v4l2 m2m mode 297 * @m2m_dev: v4l2 memory-to-memory device data 298 * @ctx: hardware context data 299 * @refcnt: the reference counter 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 * struct fimc_vid_cap - camera capture device information 314 * @ctx: hardware context data 315 * @vfd: video device node for camera capture mode 316 * @subdev: subdev exposing the FIMC processing block 317 * @vd_pad: fimc video capture node pad 318 * @sd_pads: fimc video processing block pads 319 * @mf: media bus format at the FIMC camera input (and the scaler output) pad 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 * @input: capture input type, grp_id of the attached subdev 330 * @user_subdev_api: true if subdevs are not configured by the host driver 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 * struct fimc_pix_limit - image pixel size limits in various IP configurations 355 * 356 * @scaler_en_w: max input pixel width when the scaler is enabled 357 * @scaler_dis_w: max input pixel width when the scaler is disabled 358 * @in_rot_en_h: max input width with the input rotator is on 359 * @in_rot_dis_w: max input width with the input rotator is off 360 * @out_rot_en_w: max output width with the output rotator on 361 * @out_rot_dis_w: max output width with the output rotator off 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 * struct samsung_fimc_variant - camera interface variant information 374 * 375 * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes 376 * @has_inp_rot: set if has input rotator 377 * @has_out_rot: set if has output rotator 378 * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision 379 * @has_mainscaler_ext: 1 if extended mainscaler ratios in CIEXTEN register 380 * are present in this IP revision 381 * @has_cam_if: set if this instance has a camera input interface 382 * @pix_limit: pixel size constraints for the scaler 383 * @min_inp_pixsize: minimum input pixel size 384 * @min_out_pixsize: minimum output pixel size 385 * @hor_offs_align: horizontal pixel offset aligment 386 * @min_vsize_align: minimum vertical pixel size alignment 387 * @out_buf_count: the number of buffers in output DMA sequence 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 * struct samsung_fimc_driverdata - per device type driver data for init time. 407 * 408 * @variant: the variant information for this driver. 409 * @dev_cnt: number of fimc sub-devices available in SoC 410 * @lclk_frequency: fimc bus clock frequency 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 * struct fimc_dev - abstraction for FIMC entity 428 * @slock: the spinlock protecting this data structure 429 * @lock: the mutex protecting this data structure 430 * @pdev: pointer to the FIMC platform device 431 * @pdata: pointer to the device platform data 432 * @variant: the IP variant information 433 * @id: FIMC device index (0..FIMC_MAX_DEVS) 434 * @num_clocks: the number of clocks managed by this device instance 435 * @clock: clocks required for FIMC operation 436 * @regs: the mapped hardware registers 437 * @irq: FIMC interrupt number 438 * @irq_queue: interrupt handler waitqueue 439 * @v4l2_dev: root v4l2_device 440 * @m2m: memory-to-memory V4L2 device information 441 * @vid_cap: camera capture device information 442 * @state: flags used to synchronize m2m and capture mode operation 443 * @alloc_ctx: videobuf2 memory allocator context 444 * @pipeline: fimc video capture pipeline data structure 445 */ 446struct fimc_dev { 447 spinlock_t slock; 448 struct mutex lock; 449 struct platform_device *pdev; 450 struct s5p_platform_fimc *pdata; 451 struct samsung_fimc_variant *variant; 452 u16 id; 453 u16 num_clocks; 454 struct clk *clock[MAX_FIMC_CLOCKS]; 455 void __iomem *regs; 456 int irq; 457 wait_queue_head_t irq_queue; 458 struct v4l2_device *v4l2_dev; 459 struct fimc_m2m_device m2m; 460 struct fimc_vid_cap vid_cap; 461 unsigned long state; 462 struct vb2_alloc_ctx *alloc_ctx; 463 struct fimc_pipeline pipeline; 464}; 465 466/** 467 * fimc_ctx - the device context data 468 * @slock: spinlock protecting this data structure 469 * @s_frame: source frame properties 470 * @d_frame: destination frame properties 471 * @out_order_1p: output 1-plane YCBCR order 472 * @out_order_2p: output 2-plane YCBCR order 473 * @in_order_1p input 1-plane YCBCR order 474 * @in_order_2p: input 2-plane YCBCR order 475 * @in_path: input mode (DMA or camera) 476 * @out_path: output mode (DMA or FIFO) 477 * @scaler: image scaler properties 478 * @effect: image effect 479 * @rotation: image clockwise rotation in degrees 480 * @hflip: indicates image horizontal flip if set 481 * @vflip: indicates image vertical flip if set 482 * @flags: additional flags for image conversion 483 * @state: flags to keep track of user configuration 484 * @fimc_dev: the FIMC device this context applies to 485 * @m2m_ctx: memory-to-memory device context 486 * @fh: v4l2 file handle 487 * @ctrl_handler: v4l2 controls handler 488 * @ctrl_rotate image rotation control 489 * @ctrl_hflip horizontal flip control 490 * @ctrl_vflip vertical flip control 491 * @ctrl_alpha RGB alpha control 492 * @ctrls_rdy: true if the control handler is initialized 493 */ 494struct fimc_ctx { 495 spinlock_t slock; 496 struct fimc_frame s_frame; 497 struct fimc_frame d_frame; 498 u32 out_order_1p; 499 u32 out_order_2p; 500 u32 in_order_1p; 501 u32 in_order_2p; 502 enum fimc_datapath in_path; 503 enum fimc_datapath out_path; 504 struct fimc_scaler scaler; 505 struct fimc_effect effect; 506 int rotation; 507 unsigned int hflip:1; 508 unsigned int vflip:1; 509 u32 flags; 510 u32 state; 511 struct fimc_dev *fimc_dev; 512 struct v4l2_m2m_ctx *m2m_ctx; 513 struct v4l2_fh fh; 514 struct v4l2_ctrl_handler ctrl_handler; 515 struct v4l2_ctrl *ctrl_rotate; 516 struct v4l2_ctrl *ctrl_hflip; 517 struct v4l2_ctrl *ctrl_vflip; 518 struct v4l2_ctrl *ctrl_alpha; 519 bool ctrls_rdy; 520}; 521 522#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh) 523 524static inline void set_frame_bounds(struct fimc_frame *f, u32 width, u32 height) 525{ 526 f->o_width = width; 527 f->o_height = height; 528 f->f_width = width; 529 f->f_height = height; 530} 531 532static inline void set_frame_crop(struct fimc_frame *f, 533 u32 left, u32 top, u32 width, u32 height) 534{ 535 f->offs_h = left; 536 f->offs_v = top; 537 f->width = width; 538 f->height = height; 539} 540 541static inline u32 fimc_get_format_depth(struct fimc_fmt *ff) 542{ 543 u32 i, depth = 0; 544 545 if (ff != NULL) 546 for (i = 0; i < ff->colplanes; i++) 547 depth += ff->depth[i]; 548 return depth; 549} 550 551static inline bool fimc_capture_active(struct fimc_dev *fimc) 552{ 553 unsigned long flags; 554 bool ret; 555 556 spin_lock_irqsave(&fimc->slock, flags); 557 ret = !!(fimc->state & (1 << ST_CAPT_RUN) || 558 fimc->state & (1 << ST_CAPT_PEND)); 559 spin_unlock_irqrestore(&fimc->slock, flags); 560 return ret; 561} 562 563static inline void fimc_ctx_state_lock_set(u32 state, struct fimc_ctx *ctx) 564{ 565 unsigned long flags; 566 567 spin_lock_irqsave(&ctx->slock, flags); 568 ctx->state |= state; 569 spin_unlock_irqrestore(&ctx->slock, flags); 570} 571 572static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx) 573{ 574 unsigned long flags; 575 bool ret; 576 577 spin_lock_irqsave(&ctx->slock, flags); 578 ret = (ctx->state & mask) == mask; 579 spin_unlock_irqrestore(&ctx->slock, flags); 580 return ret; 581} 582 583static inline int tiled_fmt(struct fimc_fmt *fmt) 584{ 585 return fmt->fourcc == V4L2_PIX_FMT_NV12MT; 586} 587 588/* Return the alpha component bit mask */ 589static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt) 590{ 591 switch (fmt->color) { 592 case S5P_FIMC_RGB444: return 0x0f; 593 case S5P_FIMC_RGB555: return 0x01; 594 case S5P_FIMC_RGB888: return 0xff; 595 default: return 0; 596 }; 597} 598 599static inline void fimc_hw_clear_irq(struct fimc_dev *dev) 600{ 601 u32 cfg = readl(dev->regs + S5P_CIGCTRL); 602 cfg |= S5P_CIGCTRL_IRQ_CLR; 603 writel(cfg, dev->regs + S5P_CIGCTRL); 604} 605 606static inline void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on) 607{ 608 u32 cfg = readl(dev->regs + S5P_CISCCTRL); 609 if (on) 610 cfg |= S5P_CISCCTRL_SCALERSTART; 611 else 612 cfg &= ~S5P_CISCCTRL_SCALERSTART; 613 writel(cfg, dev->regs + S5P_CISCCTRL); 614} 615 616static inline void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on) 617{ 618 u32 cfg = readl(dev->regs + S5P_MSCTRL); 619 if (on) 620 cfg |= S5P_MSCTRL_ENVID; 621 else 622 cfg &= ~S5P_MSCTRL_ENVID; 623 writel(cfg, dev->regs + S5P_MSCTRL); 624} 625 626static inline void fimc_hw_dis_capture(struct fimc_dev *dev) 627{ 628 u32 cfg = readl(dev->regs + S5P_CIIMGCPT); 629 cfg &= ~(S5P_CIIMGCPT_IMGCPTEN | S5P_CIIMGCPT_IMGCPTEN_SC); 630 writel(cfg, dev->regs + S5P_CIIMGCPT); 631} 632 633/** 634 * fimc_hw_set_dma_seq - configure output DMA buffer sequence 635 * @mask: each bit corresponds to one of 32 output buffer registers set 636 * 1 to include buffer in the sequence, 0 to disable 637 * 638 * This function mask output DMA ring buffers, i.e. it allows to configure 639 * which of the output buffer address registers will be used by the DMA 640 * engine. 641 */ 642static inline void fimc_hw_set_dma_seq(struct fimc_dev *dev, u32 mask) 643{ 644 writel(mask, dev->regs + S5P_CIFCNTSEQ); 645} 646 647static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx, 648 enum v4l2_buf_type type) 649{ 650 struct fimc_frame *frame; 651 652 if (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE == type) { 653 if (fimc_ctx_state_is_set(FIMC_CTX_M2M, ctx)) 654 frame = &ctx->s_frame; 655 else 656 return ERR_PTR(-EINVAL); 657 } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == type) { 658 frame = &ctx->d_frame; 659 } else { 660 v4l2_err(ctx->fimc_dev->v4l2_dev, 661 "Wrong buffer/video queue type (%d)\n", type); 662 return ERR_PTR(-EINVAL); 663 } 664 665 return frame; 666} 667 668/* Return an index to the buffer actually being written. */ 669static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev) 670{ 671 u32 reg; 672 673 if (dev->variant->has_cistatus2) { 674 reg = readl(dev->regs + S5P_CISTATUS2) & 0x3F; 675 return reg > 0 ? --reg : reg; 676 } else { 677 reg = readl(dev->regs + S5P_CISTATUS); 678 return (reg & S5P_CISTATUS_FRAMECNT_MASK) >> 679 S5P_CISTATUS_FRAMECNT_SHIFT; 680 } 681} 682 683/* -----------------------------------------------------*/ 684/* fimc-reg.c */ 685void fimc_hw_reset(struct fimc_dev *fimc); 686void fimc_hw_set_rotation(struct fimc_ctx *ctx); 687void fimc_hw_set_target_format(struct fimc_ctx *ctx); 688void fimc_hw_set_out_dma(struct fimc_ctx *ctx); 689void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable); 690void fimc_hw_en_irq(struct fimc_dev *fimc, int enable); 691void fimc_hw_set_prescaler(struct fimc_ctx *ctx); 692void fimc_hw_set_mainscaler(struct fimc_ctx *ctx); 693void fimc_hw_en_capture(struct fimc_ctx *ctx); 694void fimc_hw_set_effect(struct fimc_ctx *ctx, bool active); 695void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx); 696void fimc_hw_set_in_dma(struct fimc_ctx *ctx); 697void fimc_hw_set_input_path(struct fimc_ctx *ctx); 698void fimc_hw_set_output_path(struct fimc_ctx *ctx); 699void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr); 700void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr, 701 int index); 702int fimc_hw_set_camera_source(struct fimc_dev *fimc, 703 struct s5p_fimc_isp_info *cam); 704int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f); 705int fimc_hw_set_camera_polarity(struct fimc_dev *fimc, 706 struct s5p_fimc_isp_info *cam); 707int fimc_hw_set_camera_type(struct fimc_dev *fimc, 708 struct s5p_fimc_isp_info *cam); 709 710/* -----------------------------------------------------*/ 711/* fimc-core.c */ 712int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv, 713 struct v4l2_fmtdesc *f); 714int fimc_ctrls_create(struct fimc_ctx *ctx); 715void fimc_ctrls_delete(struct fimc_ctx *ctx); 716void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active); 717void fimc_alpha_ctrl_update(struct fimc_ctx *ctx); 718int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f); 719void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, 720 struct v4l2_pix_format_mplane *pix); 721struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code, 722 unsigned int mask, int index); 723 724int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh, 725 int dw, int dh, int rotation); 726int fimc_set_scaler_info(struct fimc_ctx *ctx); 727int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags); 728int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb, 729 struct fimc_frame *frame, struct fimc_addr *paddr); 730void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f); 731void fimc_set_yuv_order(struct fimc_ctx *ctx); 732void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f); 733void fimc_capture_irq_handler(struct fimc_dev *fimc, bool done); 734 735int fimc_register_m2m_device(struct fimc_dev *fimc, 736 struct v4l2_device *v4l2_dev); 737void fimc_unregister_m2m_device(struct fimc_dev *fimc); 738int fimc_register_driver(void); 739void fimc_unregister_driver(void); 740 741/* -----------------------------------------------------*/ 742/* fimc-capture.c */ 743int fimc_register_capture_device(struct fimc_dev *fimc, 744 struct v4l2_device *v4l2_dev); 745void fimc_unregister_capture_device(struct fimc_dev *fimc); 746int fimc_capture_ctrls_create(struct fimc_dev *fimc); 747int fimc_vid_cap_buf_queue(struct fimc_dev *fimc, 748 struct fimc_vid_buffer *fimc_vb); 749void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification, 750 void *arg); 751int fimc_capture_suspend(struct fimc_dev *fimc); 752int fimc_capture_resume(struct fimc_dev *fimc); 753int fimc_capture_config_update(struct fimc_ctx *ctx); 754 755/* Locking: the caller holds fimc->slock */ 756static inline void fimc_activate_capture(struct fimc_ctx *ctx) 757{ 758 fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled); 759 fimc_hw_en_capture(ctx); 760} 761 762static inline void fimc_deactivate_capture(struct fimc_dev *fimc) 763{ 764 fimc_hw_en_lastirq(fimc, true); 765 fimc_hw_dis_capture(fimc); 766 fimc_hw_enable_scaler(fimc, false); 767 fimc_hw_en_lastirq(fimc, false); 768} 769 770/* 771 * Buffer list manipulation functions. Must be called with fimc.slock held. 772 */ 773 774/** 775 * fimc_active_queue_add - add buffer to the capture active buffers queue 776 * @buf: buffer to add to the active buffers list 777 */ 778static inline void fimc_active_queue_add(struct fimc_vid_cap *vid_cap, 779 struct fimc_vid_buffer *buf) 780{ 781 list_add_tail(&buf->list, &vid_cap->active_buf_q); 782 vid_cap->active_buf_cnt++; 783} 784 785/** 786 * fimc_active_queue_pop - pop buffer from the capture active buffers queue 787 * 788 * The caller must assure the active_buf_q list is not empty. 789 */ 790static inline struct fimc_vid_buffer *fimc_active_queue_pop( 791 struct fimc_vid_cap *vid_cap) 792{ 793 struct fimc_vid_buffer *buf; 794 buf = list_entry(vid_cap->active_buf_q.next, 795 struct fimc_vid_buffer, list); 796 list_del(&buf->list); 797 vid_cap->active_buf_cnt--; 798 return buf; 799} 800 801/** 802 * fimc_pending_queue_add - add buffer to the capture pending buffers queue 803 * @buf: buffer to add to the pending buffers list 804 */ 805static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap, 806 struct fimc_vid_buffer *buf) 807{ 808 list_add_tail(&buf->list, &vid_cap->pending_buf_q); 809} 810 811/** 812 * fimc_pending_queue_pop - pop buffer from the capture pending buffers queue 813 * 814 * The caller must assure the pending_buf_q list is not empty. 815 */ 816static inline struct fimc_vid_buffer *fimc_pending_queue_pop( 817 struct fimc_vid_cap *vid_cap) 818{ 819 struct fimc_vid_buffer *buf; 820 buf = list_entry(vid_cap->pending_buf_q.next, 821 struct fimc_vid_buffer, list); 822 list_del(&buf->list); 823 return buf; 824} 825 826#endif /* FIMC_CORE_H_ */ 827