314 lines
8.5 KiB
C
Executable File
314 lines
8.5 KiB
C
Executable File
/*
|
|
* 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_GROUP_MGR_H
|
|
#define FIMC_IS_GROUP_MGR_H
|
|
|
|
#include "fimc-is-config.h"
|
|
#include "fimc-is-time.h"
|
|
#include "fimc-is-subdev-ctrl.h"
|
|
#include "fimc-is-video.h"
|
|
#include "fimc-is-cmd.h"
|
|
|
|
/* #define DEBUG_AA */
|
|
/* #define DEBUG_FLASH */
|
|
|
|
#define GROUP_STREAM_INVALID 0xFFFFFFFF
|
|
|
|
#ifdef CONFIG_USE_SENSOR_GROUP
|
|
#define TRACE_GROUP
|
|
#define GROUP_ID_3AA0 0
|
|
#define GROUP_ID_3AA1 1
|
|
#define GROUP_ID_ISP0 2
|
|
#define GROUP_ID_ISP1 3
|
|
#define GROUP_ID_DIS0 4
|
|
#define GROUP_ID_DIS1 5
|
|
#define GROUP_ID_DCP 6
|
|
#define GROUP_ID_MCS0 7
|
|
#define GROUP_ID_MCS1 8
|
|
#define GROUP_ID_VRA0 9
|
|
#define GROUP_ID_PAF0 10 /* PAF RDMA */
|
|
#define GROUP_ID_PAF1 11 /* PAF RDMA */
|
|
#define GROUP_ID_SS0 12
|
|
#define GROUP_ID_SS1 13
|
|
#define GROUP_ID_SS2 14
|
|
#define GROUP_ID_SS3 15
|
|
#define GROUP_ID_SS4 16
|
|
#define GROUP_ID_SS5 17
|
|
#define GROUP_ID_3AA2 18 /* VPP */
|
|
#define GROUP_ID_MAX 19
|
|
#define GROUP_ID_PARM_MASK ((1 << (GROUP_ID_SS0)) - 1)
|
|
#define GROUP_ID_SHIFT (19)
|
|
#define GROUP_ID_MASK (0x7FFFF)
|
|
#define GROUP_ID(id) (1 << (id))
|
|
|
|
#define GROUP_SLOT_SENSOR 0
|
|
#define GROUP_SLOT_PAF 1
|
|
#define GROUP_SLOT_3AA 2
|
|
#define GROUP_SLOT_ISP 3
|
|
#define GROUP_SLOT_DIS 4
|
|
#define GROUP_SLOT_DCP 5
|
|
#define GROUP_SLOT_MCS 6
|
|
#define GROUP_SLOT_VRA 7
|
|
#define GROUP_SLOT_MAX 8
|
|
#else
|
|
#define TRACE_GROUP
|
|
#define GROUP_ID_3AA0 0
|
|
#define GROUP_ID_3AA1 1
|
|
#define GROUP_ID_ISP0 2
|
|
#define GROUP_ID_ISP1 3
|
|
#define GROUP_ID_DIS0 4
|
|
#define GROUP_ID_DIS1 5
|
|
#define GROUP_ID_DCP 6
|
|
#define GROUP_ID_MCS0 7
|
|
#define GROUP_ID_MCS1 8
|
|
#define GROUP_ID_VRA0 9
|
|
#define GROUP_ID_MAX 10
|
|
#define GROUP_ID_PARM_MASK ((1 << (GROUP_ID_MAX)) - 1)
|
|
#define GROUP_ID_SHIFT (16)
|
|
#define GROUP_ID_MASK (0xFFFF)
|
|
#define GROUP_ID(id) (1 << (id))
|
|
|
|
#define GROUP_SLOT_3AA 0
|
|
#define GROUP_SLOT_ISP 1
|
|
#define GROUP_SLOT_DIS 2
|
|
#define GROUP_SLOT_DCP 3
|
|
#define GROUP_SLOT_MCS 4
|
|
#define GROUP_SLOT_VRA 5
|
|
#define GROUP_SLOT_MAX 6
|
|
#endif
|
|
|
|
#define FIMC_IS_MAX_GFRAME (VIDEO_MAX_FRAME) /* max shot buffer of F/W : 32 */
|
|
#define MIN_OF_ASYNC_SHOTS 1
|
|
#define MIN_OF_SYNC_SHOTS 2
|
|
|
|
#ifdef ENABLE_IS_CORE
|
|
#define MIN_OF_SHOT_RSC (MIN_OF_ASYNC_SHOTS + MIN_OF_SYNC_SHOTS)
|
|
#define MIN_OF_ASYNC_SHOTS_240FPS (MIN_OF_ASYNC_SHOTS + 2)
|
|
#else
|
|
#define MIN_OF_SHOT_RSC (1)
|
|
#define MIN_OF_ASYNC_SHOTS_240FPS (MIN_OF_ASYNC_SHOTS + 0)
|
|
#endif
|
|
|
|
#ifdef ENABLE_SYNC_REPROCESSING
|
|
#define REPROCESSING_TICK_COUNT (7) /* about 200ms */
|
|
#endif
|
|
|
|
enum fimc_is_group_state {
|
|
FIMC_IS_GROUP_OPEN,
|
|
FIMC_IS_GROUP_INIT,
|
|
FIMC_IS_GROUP_START,
|
|
FIMC_IS_GROUP_SHOT,
|
|
FIMC_IS_GROUP_REQUEST_FSTOP,
|
|
FIMC_IS_GROUP_FORCE_STOP,
|
|
FIMC_IS_GROUP_OTF_INPUT,
|
|
FIMC_IS_GROUP_OTF_OUTPUT,
|
|
FIMC_IS_GROUP_PIPE_INPUT,
|
|
FIMC_IS_GROUP_PIPE_OUTPUT,
|
|
FIMC_IS_GROUP_SEMI_PIPE_INPUT,
|
|
FIMC_IS_GROUP_SEMI_PIPE_OUTPUT,
|
|
FIMC_IS_GROUP_VIRTUAL_OTF_INPUT,
|
|
FIMC_IS_GROUP_VIRTUAL_OTF_OUTPUT,
|
|
};
|
|
|
|
enum fimc_is_group_input_type {
|
|
GROUP_INPUT_MEMORY,
|
|
GROUP_INPUT_OTF,
|
|
GROUP_INPUT_PIPE,
|
|
GROUP_INPUT_SEMI_PIPE,
|
|
GROUP_INPUT_VIRTUAL_OTF
|
|
};
|
|
|
|
enum fimc_is_group_votf_mode {
|
|
START_VIRTUAL_OTF,
|
|
END_VIRTUAL_OTF
|
|
};
|
|
|
|
struct fimc_is_frame;
|
|
struct fimc_is_device_ischain;
|
|
typedef int (*fimc_is_shot_callback)(struct fimc_is_device_ischain *device,
|
|
struct fimc_is_frame *frame);
|
|
typedef int (*fimc_is_pipe_shot_callback)(struct fimc_is_device_ischain *device,
|
|
struct fimc_is_group *group,
|
|
struct fimc_is_frame *frame);
|
|
|
|
struct fimc_is_group_frame {
|
|
struct list_head list;
|
|
u32 fcount;
|
|
struct fimc_is_crop canv;
|
|
struct camera2_node_group group_cfg[GROUP_SLOT_MAX];
|
|
};
|
|
|
|
struct fimc_is_group_framemgr {
|
|
struct fimc_is_group_frame *gframes;
|
|
spinlock_t gframe_slock;
|
|
struct list_head gframe_head;
|
|
u32 gframe_cnt;
|
|
};
|
|
|
|
struct fimc_is_group {
|
|
struct fimc_is_group *next;
|
|
struct fimc_is_group *prev;
|
|
struct fimc_is_group *gnext;
|
|
struct fimc_is_group *gprev;
|
|
struct fimc_is_group *vnext;
|
|
struct fimc_is_group *vprev;
|
|
struct fimc_is_group *parent;
|
|
struct fimc_is_group *child;
|
|
struct fimc_is_group *head;
|
|
struct fimc_is_group *tail;
|
|
|
|
struct fimc_is_subdev leader;
|
|
struct fimc_is_subdev *junction;
|
|
struct fimc_is_subdev *subdev[ENTRY_END];
|
|
struct fimc_is_framemgr *locked_sub_framemgr[ENTRY_END];
|
|
|
|
struct list_head subdev_list;
|
|
struct list_head votf_list;
|
|
|
|
/* for otf interface */
|
|
atomic_t sensor_fcount;
|
|
atomic_t backup_fcount;
|
|
struct semaphore smp_trigger;
|
|
atomic_t smp_shot_count;
|
|
u32 init_shots;
|
|
u32 asyn_shots;
|
|
u32 sync_shots;
|
|
u32 skip_shots;
|
|
#ifdef ENABLE_FAST_SHOT
|
|
struct camera2_ctl fast_ctl;
|
|
#endif
|
|
struct camera2_aa_ctl intent_ctl;
|
|
struct camera2_lens_ctl lens_ctl;
|
|
|
|
u32 id; /* group id */
|
|
u32 slot; /* group slot */
|
|
u32 instance; /* device instance */
|
|
u32 source_vid; /* source video id */
|
|
u32 pcount; /* program count */
|
|
u32 fcount; /* frame count */
|
|
atomic_t scount; /* shot count */
|
|
atomic_t rcount; /* request count */
|
|
unsigned long state;
|
|
|
|
struct list_head gframe_head;
|
|
u32 gframe_cnt;
|
|
|
|
fimc_is_shot_callback shot_callback;
|
|
fimc_is_pipe_shot_callback pipe_shot_callback;
|
|
struct fimc_is_device_ischain *device;
|
|
struct fimc_is_device_sensor *sensor;
|
|
enum fimc_is_device_type device_type;
|
|
|
|
#ifdef DEBUG_AA
|
|
#ifdef DEBUG_FLASH
|
|
enum aa_ae_flashmode flashmode;
|
|
struct camera2_flash_dm flash;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef MEASURE_TIME
|
|
#ifdef MONITOR_TIME
|
|
struct fimc_is_time time;
|
|
#endif
|
|
#endif
|
|
u32 aeflashMode; /* Flash Mode Control */
|
|
u32 remainIntentCount;
|
|
};
|
|
|
|
enum fimc_is_group_task_state {
|
|
FIMC_IS_GTASK_START,
|
|
FIMC_IS_GTASK_REQUEST_STOP
|
|
};
|
|
|
|
struct fimc_is_group_task {
|
|
u32 id;
|
|
struct task_struct *task;
|
|
struct kthread_worker worker;
|
|
struct semaphore smp_resource;
|
|
unsigned long state;
|
|
atomic_t refcount;
|
|
|
|
#ifdef ENABLE_SYNC_REPROCESSING
|
|
atomic_t rep_tick; /* Sync reprocessing tick */
|
|
struct list_head sync_list;
|
|
#endif
|
|
};
|
|
|
|
struct fimc_is_groupmgr {
|
|
struct fimc_is_group_framemgr gframemgr[FIMC_IS_STREAM_COUNT];
|
|
struct fimc_is_group *leader[FIMC_IS_STREAM_COUNT];
|
|
struct fimc_is_group *group[FIMC_IS_STREAM_COUNT][GROUP_SLOT_MAX];
|
|
struct fimc_is_group_task gtask[GROUP_ID_MAX];
|
|
};
|
|
|
|
int fimc_is_groupmgr_probe(struct platform_device *pdev,
|
|
struct fimc_is_groupmgr *groupmgr);
|
|
int fimc_is_groupmgr_init(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_device_ischain *device);
|
|
int fimc_is_groupmgr_start(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_device_ischain *device);
|
|
int fimc_is_groupmgr_stop(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_device_ischain *device);
|
|
int fimc_is_group_probe(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_group *group,
|
|
struct fimc_is_device_sensor *sensor,
|
|
struct fimc_is_device_ischain *device,
|
|
fimc_is_shot_callback shot_callback,
|
|
u32 slot,
|
|
u32 id,
|
|
char *name,
|
|
const struct fimc_is_subdev_ops *sops);
|
|
int fimc_is_group_open(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_group *group, u32 id,
|
|
struct fimc_is_video_ctx *vctx);
|
|
int fimc_is_group_close(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_group *group);
|
|
int fimc_is_group_init(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_group *group,
|
|
u32 input_type,
|
|
u32 video_id,
|
|
u32 stream_leader);
|
|
int fimc_is_group_start(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_group *group);
|
|
int fimc_is_group_stop(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_group *group);
|
|
int fimc_is_group_buffer_queue(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_group *group,
|
|
struct fimc_is_queue *queue,
|
|
u32 index);
|
|
int fimc_is_group_buffer_finish(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_group *group, u32 index);
|
|
int fimc_is_group_shot(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_group *group,
|
|
struct fimc_is_frame *frame);
|
|
int fimc_is_group_done(struct fimc_is_groupmgr *groupmgr,
|
|
struct fimc_is_group *group,
|
|
struct fimc_is_frame *frame,
|
|
u32 done_state);
|
|
|
|
unsigned long fimc_is_group_lock(struct fimc_is_group *group,
|
|
enum fimc_is_device_type device_type,
|
|
bool leader_lock);
|
|
void fimc_is_group_unlock(struct fimc_is_group *group, unsigned long flags,
|
|
enum fimc_is_device_type device_type,
|
|
bool leader_lock);
|
|
void fimc_is_group_subdev_cancel(struct fimc_is_group *group,
|
|
struct fimc_is_frame *ldr_frame,
|
|
enum fimc_is_device_type device_type,
|
|
enum fimc_is_frame_state frame_state,
|
|
bool flush);
|
|
|
|
/* get head group's framemgr */
|
|
#define GET_HEAD_GROUP_FRAMEMGR(group) \
|
|
(((group) && ((group)->head) && ((group)->head->leader.vctx)) ? (&((group)->head->leader).vctx->queue.framemgr) : NULL)
|
|
#endif
|