/* * Samsung Exynos5 SoC series FIMC-IS driver * * * Copyright (c) 2011 Samsung Electronics Co., Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifndef FIMC_IS_FRAME_MGR_H #define FIMC_IS_FRAME_MGR_H #include #include #include "fimc-is-time.h" #include "fimc-is-config.h" #define FIMC_IS_MAX_BUFS VIDEO_MAX_FRAME #define FIMC_IS_MAX_PLANES 17 #define FRAMEMGR_ID_INVALID 0x00000000 #define FRAMEMGR_ID_SSX 0x00000100 #define FRAMEMGR_ID_SSXVC0 0x00000011 #define FRAMEMGR_ID_SSXVC1 0x00000012 #define FRAMEMGR_ID_SSXVC2 0x00000013 #define FRAMEMGR_ID_SSXVC3 0x00000014 #define FRAMEMGR_ID_3XS 0x00000200 #define FRAMEMGR_ID_3XC 0x00000400 #define FRAMEMGR_ID_3XP 0x00000800 #define FRAMEMGR_ID_3XF 0x00000801 #define FRAMEMGR_ID_3XG 0x00000802 #define FRAMEMGR_ID_IXS 0x00001000 #define FRAMEMGR_ID_IXC 0x00002000 #define FRAMEMGR_ID_IXP 0x00004000 #define FRAMEMGR_ID_DXS 0x00008000 #define FRAMEMGR_ID_DXC 0x00010000 #define FRAMEMGR_ID_MXS 0x00020000 #define FRAMEMGR_ID_M0P 0x00040000 #define FRAMEMGR_ID_M1P 0x00080000 #define FRAMEMGR_ID_M2P 0x00100000 #define FRAMEMGR_ID_M3P 0x00200000 #define FRAMEMGR_ID_M4P 0x00400000 #define FRAMEMGR_ID_M5P 0x00800000 #define FRAMEMGR_ID_VRA 0x01000000 #if defined(SOC_DCP) #define FRAMEMGR_ID_DCP0S 0x02000000 #define FRAMEMGR_ID_DCP1S 0x04000000 #define FRAMEMGR_ID_DCP0C 0x08000000 #define FRAMEMGR_ID_DCP1C 0x10000000 #define FRAMEMGR_ID_DCP2C 0x20000000 #define FRAMEMGR_ID_MEXC 0x40000000 /* for ME */ #define FRAMEMGR_ID_HW 0x80000000 #define FRAMEMGR_ID_SHOT (FRAMEMGR_ID_SSX | FRAMEMGR_ID_3XS | \ FRAMEMGR_ID_IXS | FRAMEMGR_ID_DXS | \ FRAMEMGR_ID_MXS | FRAMEMGR_ID_VRA | \ FRAMEMGR_ID_DCP0S) #define FRAMEMGR_ID_STREAM (FRAMEMGR_ID_3XC | FRAMEMGR_ID_3XP | \ FRAMEMGR_ID_DXS | FRAMEMGR_ID_DXC | \ FRAMEMGR_ID_M0P | FRAMEMGR_ID_M1P | \ FRAMEMGR_ID_M2P | FRAMEMGR_ID_M3P | \ FRAMEMGR_ID_M4P | FRAMEMGR_ID_M5P | \ FRAMEMGR_ID_DCP1S | FRAMEMGR_ID_DCP0C | \ FRAMEMGR_ID_DCP1C | FRAMEMGR_ID_DCP2C | \ FRAMEMGR_ID_SSXVC0 | FRAMEMGR_ID_SSXVC1 | \ FRAMEMGR_ID_SSXVC2 | FRAMEMGR_ID_SSXVC3) #else #define FRAMEMGR_ID_MEXC 0x02000000 /* for ME */ #define FRAMEMGR_ID_PAFXS 0x04000000 /* for PAF_RDMA */ #define FRAMEMGR_ID_HW 0x08000000 #define FRAMEMGR_ID_SHOT (FRAMEMGR_ID_SSX | FRAMEMGR_ID_3XS | \ FRAMEMGR_ID_IXS | FRAMEMGR_ID_DXS | \ FRAMEMGR_ID_MXS | FRAMEMGR_ID_VRA | \ FRAMEMGR_ID_PAFXS) #define FRAMEMGR_ID_STREAM (FRAMEMGR_ID_3XC | FRAMEMGR_ID_3XP | \ FRAMEMGR_ID_DXS | FRAMEMGR_ID_DXC | \ FRAMEMGR_ID_M0P | FRAMEMGR_ID_M1P | \ FRAMEMGR_ID_M2P | FRAMEMGR_ID_M3P | \ FRAMEMGR_ID_M4P | FRAMEMGR_ID_M5P | \ FRAMEMGR_ID_SSXVC0 | FRAMEMGR_ID_SSXVC1 | \ FRAMEMGR_ID_SSXVC2 | FRAMEMGR_ID_SSXVC3) #endif /* #define TRACE_FRAME */ #define TRACE_ID (FRAMEMGR_ID_SHOT | FRAMEMGR_ID_STREAM | FRAMEMGR_ID_HW) #define FMGR_IDX_0 (1 << 0 ) #define FMGR_IDX_1 (1 << 1 ) #define FMGR_IDX_2 (1 << 2 ) #define FMGR_IDX_3 (1 << 3 ) #define FMGR_IDX_4 (1 << 4 ) #define FMGR_IDX_5 (1 << 5 ) #define FMGR_IDX_6 (1 << 6 ) #define FMGR_IDX_7 (1 << 7 ) #define FMGR_IDX_8 (1 << 8 ) #define FMGR_IDX_9 (1 << 9 ) #define FMGR_IDX_10 (1 << 10) #define FMGR_IDX_11 (1 << 11) #define FMGR_IDX_12 (1 << 12) #define FMGR_IDX_13 (1 << 13) #define FMGR_IDX_14 (1 << 14) #define FMGR_IDX_15 (1 << 15) #define FMGR_IDX_16 (1 << 16) #define FMGR_IDX_17 (1 << 17) #define FMGR_IDX_18 (1 << 18) #define FMGR_IDX_19 (1 << 19) #define FMGR_IDX_20 (1 << 20) #define FMGR_IDX_21 (1 << 21) #define FMGR_IDX_22 (1 << 22) #define FMGR_IDX_23 (1 << 23) #define FMGR_IDX_24 (1 << 24) #define FMGR_IDX_25 (1 << 25) #define FMGR_IDX_26 (1 << 26) #define FMGR_IDX_27 (1 << 27) #define FMGR_IDX_28 (1 << 28) #define FMGR_IDX_29 (1 << 29) #define FMGR_IDX_30 (1 << 30) #define FMGR_IDX_31 (1 << 31) #define framemgr_e_barrier_irqs(this, index, flag) \ do { \ this->sindex |= index; \ spin_lock_irqsave(&this->slock, flag); \ } while (0) #define framemgr_x_barrier_irqr(this, index, flag) \ do { \ spin_unlock_irqrestore(&this->slock, flag); \ this->sindex &= ~index; \ } while (0) #define framemgr_e_barrier_irq(this, index) \ do { \ this->sindex |= index; \ spin_lock_irq(&this->slock); \ } while (0) #define framemgr_x_barrier_irq(this, index) \ do { \ spin_unlock_irq(&this->slock); \ this->sindex &= ~index; \ } while (0) #define framemgr_e_barrier(this, index) \ do { \ this->sindex |= index; \ spin_lock(&this->slock); \ } while (0) #define framemgr_x_barrier(this, index) \ do { \ spin_unlock(&this->slock); \ this->sindex &= ~index; \ } while (0) enum fimc_is_frame_state { FS_FREE, FS_REQUEST, FS_PROCESS, FS_COMPLETE, FS_STRIPE_PROCESS, FS_INVALID }; #define FS_HW_FREE FS_FREE #define FS_HW_REQUEST FS_REQUEST #define FS_HW_CONFIGURE FS_PROCESS #define FS_HW_WAIT_DONE FS_COMPLETE #define FS_HW_INVALID FS_INVALID #define NR_FRAME_STATE FS_INVALID enum fimc_is_frame_mem_state { /* initialized memory */ FRAME_MEM_INIT, /* mapped memory */ FRAME_MEM_MAPPED }; #ifndef ENABLE_IS_CORE #define MAX_FRAME_INFO (4) enum fimc_is_frame_info_index { INFO_FRAME_START, INFO_CONFIG_LOCK, INFO_FRAME_END_PROC }; struct fimc_is_frame_info { int cpu; int pid; unsigned long long when; }; #endif struct fimc_is_stripe_size { /* Horizontal pixel ratio how much stripe processing is done. */ u32 h_pix_ratio; /* Horizontal pixel count which stripe processing is done for. */ u32 h_pix_num; }; struct fimc_is_stripe_info { /* Region index. */ u32 region_id; /* Total region num. */ u32 region_num; /* Stripe size for incrop/otcrop */ struct fimc_is_stripe_size in; struct fimc_is_stripe_size out; }; struct fimc_is_frame { struct list_head list; struct kthread_work work; void *groupmgr; void *group; void *subdev; /* fimc_is_subdev */ /* group leader use */ struct camera2_shot_ext *shot_ext; struct camera2_shot *shot; size_t shot_size; /* stream use */ struct camera2_stream *stream; /* common use */ u32 planes; /* total planes include multi-buffers */ dma_addr_t dvaddr_buffer[FIMC_IS_MAX_PLANES]; ulong kvaddr_buffer[FIMC_IS_MAX_PLANES]; /* * target address for capture node * [0] invalid address, stop * [others] valid address */ u32 sourceAddress[FIMC_IS_MAX_PLANES]; /* DC1S: DCP slave input DMA */ u32 txcTargetAddress[FIMC_IS_MAX_PLANES]; /* 3AA capture DMA */ u32 txpTargetAddress[FIMC_IS_MAX_PLANES]; /* 3AA preview DMA */ u32 mrgTargetAddress[FIMC_IS_MAX_PLANES]; u32 efdTargetAddress[FIMC_IS_MAX_PLANES]; u32 ixcTargetAddress[FIMC_IS_MAX_PLANES]; u32 ixpTargetAddress[FIMC_IS_MAX_PLANES]; u64 mexcTargetAddress[FIMC_IS_MAX_PLANES]; /* ME out DMA */ u32 sccTargetAddress[FIMC_IS_MAX_PLANES]; /* DC0S: DCP master capture DMA */ u32 scpTargetAddress[FIMC_IS_MAX_PLANES]; /* DC1S: DCP slave capture DMA */ u32 sc0TargetAddress[FIMC_IS_MAX_PLANES]; u32 sc1TargetAddress[FIMC_IS_MAX_PLANES]; u32 sc2TargetAddress[FIMC_IS_MAX_PLANES]; u32 sc3TargetAddress[FIMC_IS_MAX_PLANES]; u32 sc4TargetAddress[FIMC_IS_MAX_PLANES]; u32 sc5TargetAddress[FIMC_IS_MAX_PLANES]; u32 dxcTargetAddress[FIMC_IS_MAX_PLANES]; /* DC2S: DCP disparity capture DMA */ /* multi-buffer use */ u32 num_buffers; /* total number of buffers per frame */ u32 cur_buf_index; /* current processed buffer index */ /* internal use */ unsigned long mem_state; u32 state; u32 fcount; u32 rcount; u32 index; u32 lindex; u32 hindex; u32 result; unsigned long out_flag; unsigned long bak_flag; #ifndef ENABLE_IS_CORE struct fimc_is_frame_info frame_info[MAX_FRAME_INFO]; u32 instance; /* device instance */ u32 type; unsigned long core_flag; atomic_t shot_done_flag; #else /* group leader use */ dma_addr_t dvaddr_shot; #endif #ifdef ENABLE_SYNC_REPROCESSING struct list_head sync_list; #endif struct list_head votf_list; /* for NI(noise index from DDK) use */ u32 noise_idx; /* Noise index */ #ifdef MEASURE_TIME /* time measure externally */ struct timeval *tzone; /* time measure internally */ struct fimc_is_monitor mpoint[TMS_END]; #endif #ifdef DBG_DRAW_DIGIT u32 width; u32 height; #endif struct fimc_is_stripe_info stripe_info; }; struct fimc_is_framemgr { u32 id; char name[FIMC_IS_STR_LEN]; spinlock_t slock; ulong sindex; u32 num_frames; struct fimc_is_frame *frames; u32 queued_count[NR_FRAME_STATE]; struct list_head queued_list[NR_FRAME_STATE]; }; static const char * const hw_frame_state_name[NR_FRAME_STATE] = { "Free", "Request", "Configure", "Wait_Done" }; static const char * const frame_state_name[NR_FRAME_STATE] = { "Free", "Request", "Process", "Complete" }; ulong frame_fcount(struct fimc_is_frame *frame, void *data); int put_frame(struct fimc_is_framemgr *this, struct fimc_is_frame *frame, enum fimc_is_frame_state state); struct fimc_is_frame *get_frame(struct fimc_is_framemgr *this, enum fimc_is_frame_state state); int trans_frame(struct fimc_is_framemgr *this, struct fimc_is_frame *frame, enum fimc_is_frame_state state); struct fimc_is_frame *peek_frame(struct fimc_is_framemgr *this, enum fimc_is_frame_state state); struct fimc_is_frame *peek_frame_tail(struct fimc_is_framemgr *this, enum fimc_is_frame_state state); struct fimc_is_frame *find_frame(struct fimc_is_framemgr *this, enum fimc_is_frame_state state, ulong (*fn)(struct fimc_is_frame *, void *), void *data); struct fimc_is_frame *find_stripe_process_frame(struct fimc_is_framemgr *this, u32 fcount); void print_frame_queue(struct fimc_is_framemgr *this, enum fimc_is_frame_state state); int frame_manager_probe(struct fimc_is_framemgr *this, u32 id, const char *name); int frame_manager_open(struct fimc_is_framemgr *this, u32 buffers); int frame_manager_close(struct fimc_is_framemgr *this); int frame_manager_flush(struct fimc_is_framemgr *this); void frame_manager_print_queues(struct fimc_is_framemgr *this); void frame_manager_print_info_queues(struct fimc_is_framemgr *this); #endif