mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
drivers: media: platform: rockchip: cif: restruct cif reset monitor
Signed-off-by: Allon Huang <allon.huang@rock-chips.com> Change-Id: Iec0b8499f4a3da086421bc7ab28566bb27ca6aa8 Signed-off-by: Vicent Chi <vicent.chi@rock-chips.com>
This commit is contained in:
@@ -24,16 +24,3 @@ config ROCKCHIP_CIF_WORKMODE_ONEFRAME
|
||||
bool "interface works in oneframe mode"
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "rockchip camera sensor interface monitor mode of reset"
|
||||
depends on VIDEO_ROCKCHIP_CIF
|
||||
default ROCKCHIP_CIF_RESET_MONITOR_TRIGGER
|
||||
|
||||
config ROCKCHIP_CIF_RESET_MONITOR_TRIGGER
|
||||
bool "cif reset monitor is triggered by event"
|
||||
|
||||
config ROCKCHIP_CIF_RESET_MONITOR_CONTINU
|
||||
bool "cif reset monitor is opened always"
|
||||
|
||||
endchoice
|
||||
|
||||
@@ -2479,7 +2479,6 @@ static int rkcif_start_streaming(struct vb2_queue *queue, unsigned int count)
|
||||
}
|
||||
}
|
||||
|
||||
v4l2_info(&dev->v4l2_dev, "%s successfully!\n", __func__);
|
||||
goto out;
|
||||
|
||||
stop_stream:
|
||||
@@ -3774,16 +3773,80 @@ static int rkcif_csi_g_mipi_id(struct v4l2_device *v4l2_dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static bool rkcif_is_csi2_err_trigger_reset(struct rkcif_timer *timer)
|
||||
{
|
||||
struct rkcif_device *dev = container_of(timer,
|
||||
struct rkcif_device,
|
||||
reset_watchdog_timer);
|
||||
|
||||
bool is_triggered = false;
|
||||
unsigned long lock_flags;
|
||||
|
||||
spin_lock_irqsave(&timer->csi2_err_lock, lock_flags);
|
||||
|
||||
if (timer->csi2_err_cnt_even != 0 &&
|
||||
timer->csi2_err_cnt_odd != 0) {
|
||||
is_triggered = true;
|
||||
timer->csi2_err_cnt_odd = 0;
|
||||
timer->csi2_err_cnt_even = 0;
|
||||
timer->reset_src = RKCIF_RESET_SRC_ERR_CSI2;
|
||||
v4l2_info(&dev->v4l2_dev, "do csi2 err reset\n");
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&timer->csi2_err_lock, lock_flags);
|
||||
|
||||
return is_triggered;
|
||||
}
|
||||
|
||||
static bool rkcif_is_triggered_monitoring(struct rkcif_device *dev)
|
||||
{
|
||||
struct rkcif_timer *timer = &dev->reset_watchdog_timer;
|
||||
struct rkcif_stream *stream = &dev->stream[RKCIF_STREAM_MIPI_ID0];
|
||||
bool ret = false;
|
||||
|
||||
if (timer->monitor_mode == RKCIF_MONITOR_MODE_IDLE)
|
||||
ret = false;
|
||||
|
||||
if (timer->monitor_mode == RKCIF_MONITOR_MODE_CONTINUE ||
|
||||
timer->monitor_mode == RKCIF_MONITOR_MODE_HOTPLUG) {
|
||||
if (stream->frame_idx >= timer->triggered_frame_num)
|
||||
ret = true;
|
||||
}
|
||||
|
||||
if (timer->monitor_mode == RKCIF_MONITOR_MODE_TRIGGER) {
|
||||
timer->is_csi2_err_occurred = rkcif_is_csi2_err_trigger_reset(timer);
|
||||
ret = timer->is_csi2_err_occurred;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static s32 rkcif_get_sensor_vblank(struct rkcif_device *dev)
|
||||
{
|
||||
struct rkcif_sensor_info *terminal_sensor = &dev->terminal_sensor;
|
||||
struct v4l2_subdev *sd = terminal_sensor->sd;
|
||||
struct v4l2_ctrl_handler *hdl = sd->ctrl_handler;
|
||||
struct v4l2_ctrl *ctrl = NULL;
|
||||
|
||||
if (!list_empty(&hdl->ctrls)) {
|
||||
list_for_each_entry(ctrl, &hdl->ctrls, node) {
|
||||
if (ctrl->id == V4L2_CID_VBLANK)
|
||||
return ctrl->val;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rkcif_monitor_reset_event(struct rkcif_device *dev)
|
||||
{
|
||||
struct rkcif_sensor_info *sensor = &dev->terminal_sensor;
|
||||
struct rkcif_stream *stream = &dev->stream[RKCIF_STREAM_MIPI_ID0];
|
||||
struct rkcif_timer *timer = &dev->reset_watchdog_timer;
|
||||
unsigned long lock_flags = 0;
|
||||
u32 denominator = 0, numerator = 0, interval = 0;
|
||||
u32 time = 60ul;
|
||||
unsigned int cycle = 0;
|
||||
u64 fps, timestamp0, timestamp1;
|
||||
unsigned long lock_flags = 0, fps_flags = 0;
|
||||
|
||||
if (timer->reset_src == RKCIF_RESET_SRC_NON)
|
||||
if (timer->monitor_mode == RKCIF_MONITOR_MODE_IDLE)
|
||||
return;
|
||||
|
||||
if (stream->state != RKCIF_STATE_STREAMING)
|
||||
@@ -3792,42 +3855,59 @@ static void rkcif_monitor_reset_event(struct rkcif_device *dev)
|
||||
if (timer->is_running)
|
||||
return;
|
||||
|
||||
if (timer->reset_src == RKCIF_RESET_SRC_NORMAL)
|
||||
timer->is_triggered = true;
|
||||
timer->is_triggered = rkcif_is_triggered_monitoring(dev);
|
||||
|
||||
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev, "%s: reset src:%d\n",
|
||||
__func__, timer->reset_src);
|
||||
|
||||
spin_lock_irqsave(&timer->timer_lock, lock_flags);
|
||||
if (timer->is_triggered) {
|
||||
|
||||
numerator = sensor->fi.interval.numerator;
|
||||
denominator = sensor->fi.interval.denominator;
|
||||
if (denominator && numerator) {
|
||||
time = denominator / numerator;
|
||||
struct v4l2_rect *raw_rect = &dev->terminal_sensor.raw_rect;
|
||||
enum rkcif_monitor_mode mode;
|
||||
s32 vblank = 0;
|
||||
u32 vts = 0;
|
||||
|
||||
/* in non-normal err src, do monitor in 1 second */
|
||||
if (timer->reset_src == RKCIF_RESET_SRC_NORMAL)
|
||||
timer->max_run_cnt = 0xffffffff - CIF_TIMEOUT_FRAME_NUM;
|
||||
else
|
||||
timer->max_run_cnt = time * 1;
|
||||
spin_lock_irqsave(&stream->fps_lock, fps_flags);
|
||||
timestamp0 = stream->fps_stats.frm0_timestamp;
|
||||
timestamp1 = stream->fps_stats.frm1_timestamp;
|
||||
spin_unlock_irqrestore(&stream->fps_lock, fps_flags);
|
||||
|
||||
spin_lock_irqsave(&timer->timer_lock, lock_flags);
|
||||
|
||||
fps = timestamp0 > timestamp1 ?
|
||||
timestamp0 - timestamp1 : timestamp1 - timestamp0;
|
||||
fps = div_u64(fps, 1000);
|
||||
timer->frame_end_cycle_us = fps;
|
||||
|
||||
vblank = rkcif_get_sensor_vblank(dev);
|
||||
timer->raw_height = raw_rect->height;
|
||||
vts = timer->raw_height + vblank;
|
||||
timer->vts = vts;
|
||||
|
||||
timer->line_end_cycle = div_u64(timer->frame_end_cycle_us, timer->vts);
|
||||
fps = div_u64(timer->frame_end_cycle_us, 1000);
|
||||
cycle = fps * timer->frm_num_of_monitor_cycle;
|
||||
timer->cycle = msecs_to_jiffies(cycle);
|
||||
|
||||
interval = DIV_ROUND_UP(1000, time);
|
||||
time = interval + interval / 3;
|
||||
}
|
||||
timer->run_cnt = 0;
|
||||
timer->is_running = true;
|
||||
timer->is_buf_stop_update = false;
|
||||
timer->cycle = msecs_to_jiffies(interval);
|
||||
timer->timer.expires = jiffies + msecs_to_jiffies(time);
|
||||
timer->last_buf_wakeup_cnt = dev->buf_wake_up_cnt;
|
||||
/* in trigger mode, monitoring count is fps */
|
||||
mode = timer->monitor_mode;
|
||||
if (mode == RKCIF_MONITOR_MODE_CONTINUE ||
|
||||
mode == RKCIF_MONITOR_MODE_HOTPLUG)
|
||||
timer->max_run_cnt = 0xffffffff - CIF_TIMEOUT_FRAME_NUM;
|
||||
else
|
||||
timer->max_run_cnt = div_u64(1000, fps) * 1;
|
||||
|
||||
timer->timer.expires = jiffies + timer->cycle;
|
||||
mod_timer(&timer->timer, timer->timer.expires);
|
||||
|
||||
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev, "%s:timer init inter:%ld, cycle:%ld\n",
|
||||
__func__, timer->timer.expires, timer->cycle);
|
||||
}
|
||||
spin_unlock_irqrestore(&timer->timer_lock, lock_flags);
|
||||
spin_unlock_irqrestore(&timer->timer_lock, lock_flags);
|
||||
|
||||
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev,
|
||||
"%s:mode:%d, raw height:%d,vblank:%d, cycle:%ld, fps:%llu\n",
|
||||
__func__, timer->monitor_mode, raw_rect->height,
|
||||
vblank, timer->cycle, div_u64(1000, fps));
|
||||
}
|
||||
}
|
||||
|
||||
static void rkcif_rdbk_frame_end(struct rkcif_stream *stream)
|
||||
@@ -3898,8 +3978,6 @@ static void rkcif_rdbk_frame_end(struct rkcif_stream *stream)
|
||||
rkcif_vb_done_oneframe(stream, &dev->rdbk_buf[RDBK_L]->vb);
|
||||
rkcif_vb_done_oneframe(stream, &dev->rdbk_buf[RDBK_M]->vb);
|
||||
rkcif_vb_done_oneframe(stream, &dev->rdbk_buf[RDBK_S]->vb);
|
||||
dev->buf_wake_up_cnt += 1;
|
||||
rkcif_monitor_reset_event(dev);
|
||||
} else {
|
||||
if (!dev->rdbk_buf[RDBK_L])
|
||||
v4l2_err(&dev->v4l2_dev, "lost long frames\n");
|
||||
@@ -3946,8 +4024,6 @@ static void rkcif_rdbk_frame_end(struct rkcif_stream *stream)
|
||||
dev->rdbk_buf[RDBK_L]->vb.sequence;
|
||||
rkcif_vb_done_oneframe(stream, &dev->rdbk_buf[RDBK_L]->vb);
|
||||
rkcif_vb_done_oneframe(stream, &dev->rdbk_buf[RDBK_M]->vb);
|
||||
dev->buf_wake_up_cnt += 1;
|
||||
rkcif_monitor_reset_event(dev);
|
||||
} else {
|
||||
if (!dev->rdbk_buf[RDBK_L])
|
||||
v4l2_err(&dev->v4l2_dev, "lost long frames\n");
|
||||
@@ -3991,14 +4067,19 @@ static void rkcif_update_stream(struct rkcif_device *cif_dev,
|
||||
struct vb2_v4l2_buffer *vb_done = NULL;
|
||||
unsigned long lock_flags = 0;
|
||||
|
||||
spin_lock(&stream->fps_lock);
|
||||
if (stream->frame_phase & CIF_CSI_FRAME1_READY) {
|
||||
if (stream->next_buf)
|
||||
active_buf = stream->next_buf;
|
||||
stream->fps_stats.frm1_timestamp = ktime_get_ns();
|
||||
} else if (stream->frame_phase & CIF_CSI_FRAME0_READY) {
|
||||
if (stream->curr_buf)
|
||||
active_buf = stream->curr_buf;
|
||||
stream->fps_stats.frm0_timestamp = ktime_get_ns();
|
||||
}
|
||||
spin_unlock(&stream->fps_lock);
|
||||
|
||||
cif_dev->buf_wake_up_cnt += 1;
|
||||
rkcif_assign_new_buffer_pingpong(stream, 0, mipi_id);
|
||||
|
||||
if (cif_dev->chip_id == CHIP_RV1126_CIF ||
|
||||
@@ -4010,24 +4091,13 @@ static void rkcif_update_stream(struct rkcif_device *cif_dev,
|
||||
vb_done = &active_buf->vb;
|
||||
vb_done->vb2_buf.timestamp = ktime_get_ns();
|
||||
vb_done->sequence = stream->frame_idx;
|
||||
spin_lock(&stream->fps_lock);
|
||||
if (stream->frame_phase & CIF_CSI_FRAME0_READY)
|
||||
stream->fps_stats.frm0_timestamp = vb_done->vb2_buf.timestamp;
|
||||
else if (stream->frame_phase & CIF_CSI_FRAME1_READY)
|
||||
stream->fps_stats.frm1_timestamp = vb_done->vb2_buf.timestamp;
|
||||
spin_unlock(&stream->fps_lock);
|
||||
}
|
||||
|
||||
if (cif_dev->hdr.mode == NO_HDR) {
|
||||
if (active_buf)
|
||||
rkcif_vb_done_oneframe(stream, vb_done);
|
||||
|
||||
cif_dev->buf_wake_up_cnt += 1;
|
||||
|
||||
rkcif_monitor_reset_event(cif_dev);
|
||||
} else {
|
||||
if (cif_dev->is_start_hdr) {
|
||||
|
||||
spin_lock_irqsave(&cif_dev->hdr_lock, lock_flags);
|
||||
if (mipi_id == RKCIF_STREAM_MIPI_ID0) {
|
||||
if (cif_dev->rdbk_buf[RDBK_L]) {
|
||||
@@ -4069,7 +4139,6 @@ static void rkcif_update_stream(struct rkcif_device *cif_dev,
|
||||
rkcif_rdbk_frame_end(stream);
|
||||
}
|
||||
spin_unlock_irqrestore(&cif_dev->hdr_lock, lock_flags);
|
||||
|
||||
} else {
|
||||
if (active_buf) {
|
||||
vb_done->vb2_buf.state = VB2_BUF_STATE_ACTIVE;
|
||||
@@ -4106,7 +4175,7 @@ u32 rkcif_get_sof(struct rkcif_device *cif_dev)
|
||||
}
|
||||
|
||||
static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
|
||||
enum rkcif_reset_src reset_src)
|
||||
enum rkmodule_reset_src reset_src)
|
||||
{
|
||||
struct rkcif_pipeline *p = &cif_dev->pipe;
|
||||
struct rkcif_stream *stream = NULL;
|
||||
@@ -4139,7 +4208,7 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
|
||||
}
|
||||
|
||||
if (stream->id == RKCIF_STREAM_MIPI_ID0)
|
||||
resume_info->frm_sync_seq = rkcif_csi2_get_sof() + 1;
|
||||
resume_info->frm_sync_seq = rkcif_get_sof(cif_dev) + 1;
|
||||
|
||||
stream->state = RKCIF_STATE_RESET_IN_STREAMING;
|
||||
resume_stream[j] = stream;
|
||||
@@ -4159,8 +4228,11 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
|
||||
|
||||
if (p->subdevs[i] == terminal_sensor->sd) {
|
||||
|
||||
if (reset_src == RKCIF_RESET_SRC_ERR_HOTPLUG)
|
||||
continue;
|
||||
|
||||
if (reset_src == RKCIF_RESET_SRC_ERR_CSI2 ||
|
||||
reset_src == RKCIF_RESET_SRC_NORMAL) {
|
||||
reset_src == RKICF_RESET_SRC_ERR_CUTOFF) {
|
||||
|
||||
ret = v4l2_subdev_call(p->subdevs[i], core, ioctl,
|
||||
RKMODULE_SET_QUICK_STREAM, &on);
|
||||
@@ -4215,8 +4287,11 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
|
||||
|
||||
rkcif_csi2_set_sof(resume_info->frm_sync_seq);
|
||||
|
||||
if (reset_src == RKCIF_RESET_SRC_ERR_HOTPLUG)
|
||||
continue;
|
||||
|
||||
if (reset_src == RKCIF_RESET_SRC_ERR_CSI2 ||
|
||||
reset_src == RKCIF_RESET_SRC_NORMAL) {
|
||||
reset_src == RKICF_RESET_SRC_ERR_CUTOFF) {
|
||||
ret = v4l2_subdev_call(p->subdevs[i], core, ioctl,
|
||||
RKMODULE_SET_QUICK_STREAM, &on);
|
||||
if (ret)
|
||||
@@ -4260,12 +4335,112 @@ static void rkcif_reset_work(struct work_struct *work)
|
||||
|
||||
}
|
||||
|
||||
static bool rkcif_is_reduced_frame_rate(struct rkcif_device *dev)
|
||||
{
|
||||
struct rkcif_timer *timer = &dev->reset_watchdog_timer;
|
||||
struct rkcif_stream *stream = &dev->stream[RKCIF_STREAM_MIPI_ID0];
|
||||
struct v4l2_rect *raw_rect = &dev->terminal_sensor.raw_rect;
|
||||
u64 fps, timestamp0, timestamp1, diff_time;
|
||||
unsigned long fps_flags = 0;
|
||||
unsigned int deviation = 1;
|
||||
bool is_reduced = false;
|
||||
|
||||
spin_lock_irqsave(&stream->fps_lock, fps_flags);
|
||||
timestamp0 = stream->fps_stats.frm0_timestamp;
|
||||
timestamp1 = stream->fps_stats.frm1_timestamp;
|
||||
spin_unlock_irqrestore(&stream->fps_lock, fps_flags);
|
||||
|
||||
fps = timestamp0 > timestamp1 ?
|
||||
timestamp0 - timestamp1 : timestamp1 - timestamp0;
|
||||
fps = div_u64(fps, 1000);
|
||||
diff_time = fps > timer->frame_end_cycle_us ?
|
||||
fps - timer->frame_end_cycle_us : 0;
|
||||
deviation = DIV_ROUND_UP(timer->vts, 100);
|
||||
|
||||
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev, "diff_time:%lld,devi_t:%ld,devi_h:%d\n",
|
||||
diff_time, timer->line_end_cycle * deviation, deviation);
|
||||
|
||||
if (diff_time > timer->line_end_cycle * deviation) {
|
||||
s32 vblank = 0;
|
||||
unsigned int vts;
|
||||
|
||||
is_reduced = true;
|
||||
vblank = rkcif_get_sensor_vblank(dev);
|
||||
vts = vblank + timer->raw_height;
|
||||
|
||||
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev, "old vts:%d,new vts:%d\n", timer->vts, vts);
|
||||
|
||||
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev,
|
||||
"reduce frame rate,vblank:%d, height(raw output):%d, fps:%lld, frm_end_t:%ld, line_t:%ld, diff:%lld\n",
|
||||
rkcif_get_sensor_vblank(dev),
|
||||
raw_rect->height,
|
||||
fps,
|
||||
timer->frame_end_cycle_us,
|
||||
timer->line_end_cycle,
|
||||
diff_time);
|
||||
|
||||
timer->vts = vts;
|
||||
timer->frame_end_cycle_us = fps;
|
||||
timer->line_end_cycle = div_u64(timer->frame_end_cycle_us, timer->vts);
|
||||
} else {
|
||||
is_reduced = false;
|
||||
}
|
||||
|
||||
timer->frame_end_cycle_us = fps;
|
||||
|
||||
fps = div_u64(fps, 1000);
|
||||
fps = fps * timer->frm_num_of_monitor_cycle;
|
||||
timer->cycle = msecs_to_jiffies(fps);
|
||||
timer->timer.expires = jiffies + timer->cycle;
|
||||
|
||||
return is_reduced;
|
||||
|
||||
}
|
||||
|
||||
static void rkcif_init_reset_work(struct rkcif_timer *timer)
|
||||
{
|
||||
struct rkcif_device *dev = container_of(timer,
|
||||
struct rkcif_device,
|
||||
reset_watchdog_timer);
|
||||
unsigned long lock_flags = 0;
|
||||
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"do reset work schedule, run_cnt:%d, reset source:%d\n",
|
||||
timer->run_cnt, timer->reset_src);
|
||||
|
||||
spin_lock_irqsave(&timer->timer_lock, lock_flags);
|
||||
timer->is_running = false;
|
||||
timer->is_triggered = false;
|
||||
timer->csi2_err_cnt_odd = 0;
|
||||
timer->csi2_err_cnt_even = 0;
|
||||
timer->csi2_err_fs_fe_cnt = 0;
|
||||
timer->notifer_called_cnt = 0;
|
||||
timer->last_buf_wakeup_cnt = dev->buf_wake_up_cnt;
|
||||
spin_unlock_irqrestore(&timer->timer_lock, lock_flags);
|
||||
|
||||
dev->reset_work.reset_src = timer->reset_src;
|
||||
INIT_WORK(&dev->reset_work.work, rkcif_reset_work);
|
||||
if (schedule_work_on(smp_processor_id(), &dev->reset_work.work))
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"schedule reset work successfully\n");
|
||||
else
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"schedule reset work failed\n");
|
||||
|
||||
}
|
||||
|
||||
void rkcif_reset_watchdog_timer_handler(struct timer_list *t)
|
||||
{
|
||||
struct rkcif_timer *timer = container_of(t, struct rkcif_timer, timer);
|
||||
struct rkcif_device *dev = container_of(timer, struct rkcif_device, reset_watchdog_timer);
|
||||
struct rkcif_device *dev = container_of(timer,
|
||||
struct rkcif_device,
|
||||
reset_watchdog_timer);
|
||||
struct rkcif_sensor_info *terminal_sensor = &dev->terminal_sensor;
|
||||
|
||||
unsigned long lock_flags = 0;
|
||||
unsigned int i, stream_num = 1;
|
||||
int ret, is_reset = 0;
|
||||
struct rkmodule_vicap_reset_info rst_info;
|
||||
|
||||
if (dev->hdr.mode == NO_HDR) {
|
||||
i = 0;
|
||||
@@ -4287,13 +4462,46 @@ void rkcif_reset_watchdog_timer_handler(struct timer_list *t)
|
||||
|
||||
if (timer->last_buf_wakeup_cnt < dev->buf_wake_up_cnt) {
|
||||
|
||||
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev, "info: frame end still update(%d, %d) in detecting cnt:%d, src:%d\n",
|
||||
timer->last_buf_wakeup_cnt, dev->buf_wake_up_cnt,
|
||||
timer->run_cnt, timer->reset_src);
|
||||
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev,
|
||||
"info: frame end still update(%d, %d) in detecting cnt:%d, mode:%d\n",
|
||||
timer->last_buf_wakeup_cnt, dev->buf_wake_up_cnt,
|
||||
timer->run_cnt, timer->monitor_mode);
|
||||
|
||||
timer->last_buf_wakeup_cnt = dev->buf_wake_up_cnt;
|
||||
|
||||
if (timer->reset_src == RKCIF_RESET_SRC_NORMAL) {
|
||||
rkcif_is_reduced_frame_rate(dev);
|
||||
|
||||
if (timer->monitor_mode == RKCIF_MONITOR_MODE_HOTPLUG) {
|
||||
ret = v4l2_subdev_call(terminal_sensor->sd,
|
||||
core, ioctl,
|
||||
RKMODULE_GET_VICAP_RST_INFO,
|
||||
&rst_info);
|
||||
if (ret)
|
||||
is_reset = 0;
|
||||
else
|
||||
is_reset = rst_info.is_reset;
|
||||
rst_info.is_reset = 0;
|
||||
timer->reset_src = RKCIF_RESET_SRC_ERR_HOTPLUG;
|
||||
v4l2_subdev_call(terminal_sensor->sd, core, ioctl,
|
||||
RKMODULE_SET_VICAP_RST_INFO, &rst_info);
|
||||
if (!is_reset)
|
||||
is_reset = rkcif_is_csi2_err_trigger_reset(timer);
|
||||
} else if (timer->monitor_mode == RKCIF_MONITOR_MODE_CONTINUE) {
|
||||
is_reset = rkcif_is_csi2_err_trigger_reset(timer);
|
||||
} else if (timer->monitor_mode == RKCIF_MONITOR_MODE_TRIGGER) {
|
||||
is_reset = timer->is_csi2_err_occurred;
|
||||
if (is_reset)
|
||||
timer->reset_src = RKCIF_RESET_SRC_ERR_CSI2;
|
||||
timer->is_csi2_err_occurred = false;
|
||||
}
|
||||
|
||||
if (is_reset) {
|
||||
rkcif_init_reset_work(timer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (timer->monitor_mode == RKCIF_MONITOR_MODE_CONTINUE ||
|
||||
timer->monitor_mode == RKCIF_MONITOR_MODE_HOTPLUG) {
|
||||
if (timer->run_cnt == timer->max_run_cnt)
|
||||
timer->run_cnt = 0x0;
|
||||
mod_timer(&timer->timer, jiffies + timer->cycle);
|
||||
@@ -4310,41 +4518,19 @@ void rkcif_reset_watchdog_timer_handler(struct timer_list *t)
|
||||
}
|
||||
} else if (timer->last_buf_wakeup_cnt == dev->buf_wake_up_cnt) {
|
||||
|
||||
if (!timer->is_buf_stop_update) {
|
||||
timer->stop_index_of_run_cnt = timer->run_cnt;
|
||||
timer->is_buf_stop_update = true;
|
||||
bool is_reduced = rkcif_is_reduced_frame_rate(dev);
|
||||
|
||||
if (is_reduced) {
|
||||
mod_timer(&timer->timer, jiffies + timer->cycle);
|
||||
|
||||
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev, "find first frame end no update(%d, %d) in detecting cnt:%d!\n",
|
||||
timer->last_buf_wakeup_cnt, dev->buf_wake_up_cnt, timer->run_cnt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((timer->run_cnt - timer->stop_index_of_run_cnt >= CIF_TIMEOUT_FRAME_NUM) &&
|
||||
timer->is_buf_stop_update) {
|
||||
|
||||
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev,
|
||||
"do reset work schedule, run_cnt:%d, csi_crc_cnt:%d\n",
|
||||
timer->run_cnt, timer->csi_crc_cnt);
|
||||
|
||||
spin_lock_irqsave(&timer->timer_lock, lock_flags);
|
||||
timer->is_triggered = false;
|
||||
timer->is_running = false;
|
||||
spin_unlock_irqrestore(&timer->timer_lock, lock_flags);
|
||||
|
||||
dev->reset_work.reset_src = timer->reset_src;
|
||||
INIT_WORK(&dev->reset_work.work, rkcif_reset_work);
|
||||
if (schedule_work_on(smp_processor_id(), &dev->reset_work.work))
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"schedule reset work successfully,reset src:%d\n",
|
||||
dev->reset_work.reset_src);
|
||||
else
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"schedule reset work failed,reset src:%d\n",
|
||||
dev->reset_work.reset_src);
|
||||
v4l2_info(&dev->v4l2_dev, "%s fps is reduced\n", __func__);
|
||||
} else {
|
||||
mod_timer(&timer->timer, jiffies + timer->cycle);
|
||||
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"do reset work due to frame end is stopped, run_cnt:%d\n",
|
||||
timer->run_cnt);
|
||||
|
||||
timer->reset_src = RKICF_RESET_SRC_ERR_CUTOFF;
|
||||
rkcif_init_reset_work(timer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4364,12 +4550,24 @@ end_detect:
|
||||
int rkcif_reset_notifier(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
|
||||
struct rkcif_device *dev = container_of(nb, struct rkcif_device, reset_notifier);
|
||||
struct rkcif_timer *timer = &dev->reset_watchdog_timer;
|
||||
unsigned long lock_flags = 0, val;
|
||||
|
||||
timer->csi_crc_cnt = action;
|
||||
/* TODO: trigger reset work */
|
||||
if (timer->is_running) {
|
||||
val = action & CSI2_ERR_COUNT_ALL_MASK;
|
||||
spin_lock_irqsave(&timer->csi2_err_lock, lock_flags);
|
||||
if ((val % timer->csi2_err_ref_cnt) == 0) {
|
||||
timer->notifer_called_cnt++;
|
||||
if ((timer->notifer_called_cnt % 2) == 0)
|
||||
timer->csi2_err_cnt_even = val;
|
||||
else
|
||||
timer->csi2_err_cnt_odd = val;
|
||||
}
|
||||
|
||||
timer->csi2_err_fs_fe_cnt = (action & CSI2_ERR_FSFE_MASK) >> 8;
|
||||
spin_unlock_irqrestore(&timer->csi2_err_lock, lock_flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4478,6 +4676,7 @@ void rkcif_irq_pingpong(struct rkcif_device *cif_dev)
|
||||
}
|
||||
|
||||
rkcif_update_stream(cif_dev, stream, mipi_id);
|
||||
rkcif_monitor_reset_event(cif_dev);
|
||||
}
|
||||
cif_dev->irq_stats.all_frm_end_cnt++;
|
||||
} else {
|
||||
@@ -4495,7 +4694,7 @@ void rkcif_irq_pingpong(struct rkcif_device *cif_dev)
|
||||
|
||||
stream = &cif_dev->stream[RKCIF_STREAM_CIF];
|
||||
|
||||
if ((intstat & LINE_INT_END) && !(intstat & FRAME_END)) {
|
||||
if ((intstat & LINE_INT_END) && !(intstat & (FRAME_END))) {
|
||||
rkcif_dvp_event_inc_sof(cif_dev);
|
||||
rkcif_write_register(cif_dev, CIF_REG_DVP_INTSTAT, intstat);
|
||||
int_en = rkcif_read_register(cif_dev, CIF_REG_DVP_INTEN);
|
||||
@@ -4589,20 +4788,19 @@ void rkcif_irq_pingpong(struct rkcif_device *cif_dev)
|
||||
stream->frame_phase = CIF_CSI_FRAME1_READY;
|
||||
}
|
||||
|
||||
spin_lock(&stream->fps_lock);
|
||||
if (stream->frame_phase & CIF_CSI_FRAME0_READY)
|
||||
stream->fps_stats.frm0_timestamp = ktime_get_ns();
|
||||
else if (stream->frame_phase & CIF_CSI_FRAME1_READY)
|
||||
stream->fps_stats.frm1_timestamp = ktime_get_ns();
|
||||
spin_unlock(&stream->fps_lock);
|
||||
|
||||
rkcif_assign_new_buffer_oneframe(stream,
|
||||
RKCIF_YUV_ADDR_STATE_UPDATE);
|
||||
|
||||
if (vb_done) {
|
||||
vb_done->sequence = stream->frame_idx;
|
||||
|
||||
rkcif_vb_done_oneframe(stream, vb_done);
|
||||
|
||||
spin_lock(&stream->fps_lock);
|
||||
if (stream->frame_phase & CIF_CSI_FRAME0_READY)
|
||||
stream->fps_stats.frm0_timestamp = vb_done->vb2_buf.timestamp;
|
||||
else if (stream->frame_phase & CIF_CSI_FRAME1_READY)
|
||||
stream->fps_stats.frm1_timestamp = vb_done->vb2_buf.timestamp;
|
||||
spin_unlock(&stream->fps_lock);
|
||||
}
|
||||
|
||||
stream->frame_idx++;
|
||||
@@ -4698,6 +4896,7 @@ void rkcif_irq_lite_lvds(struct rkcif_device *cif_dev)
|
||||
}
|
||||
|
||||
rkcif_update_stream(cif_dev, stream, mipi_id);
|
||||
rkcif_monitor_reset_event(cif_dev);
|
||||
}
|
||||
cif_dev->irq_stats.all_frm_end_cnt++;
|
||||
}
|
||||
|
||||
@@ -826,6 +826,95 @@ static int rkcif_detach_hw(struct rkcif_device *cif_dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char* rkcif_get_monitor_mode(enum rkcif_monitor_mode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case RKCIF_MONITOR_MODE_IDLE:
|
||||
return "idle";
|
||||
case RKCIF_MONITOR_MODE_CONTINUE:
|
||||
return "continue";
|
||||
case RKCIF_MONITOR_MODE_TRIGGER:
|
||||
return "trigger";
|
||||
case RKCIF_MONITOR_MODE_HOTPLUG:
|
||||
return "hotplug";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void rkcif_init_reset_monitor(struct rkcif_device *dev)
|
||||
{
|
||||
struct device_node *node = dev->dev->of_node;
|
||||
struct rkcif_timer *timer = &dev->reset_watchdog_timer;
|
||||
struct notifier_block *notifier = &dev->reset_notifier;
|
||||
u32 para[8];
|
||||
int i;
|
||||
|
||||
if (!of_property_read_u32_array(node,
|
||||
OF_CIF_MONITOR_PARA,
|
||||
para,
|
||||
CIF_MONITOR_PARA_NUM)) {
|
||||
for (i = 0; i < CIF_MONITOR_PARA_NUM; i++) {
|
||||
if (i == 0) {
|
||||
timer->monitor_mode = para[0];
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"%s: timer monitor mode:%s\n",
|
||||
__func__, rkcif_get_monitor_mode(timer->monitor_mode));
|
||||
}
|
||||
|
||||
if (i == 1) {
|
||||
timer->triggered_frame_num = para[1];
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"timer triggered frm num:%d\n",
|
||||
timer->triggered_frame_num);
|
||||
}
|
||||
|
||||
if (i == 2) {
|
||||
timer->frm_num_of_monitor_cycle = para[2];
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"timer frm num of monitor cycle:%d\n",
|
||||
timer->frm_num_of_monitor_cycle);
|
||||
}
|
||||
|
||||
if (i == 3) {
|
||||
timer->err_time_interval = para[3];
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"timer err time for keeping:%d ms\n",
|
||||
timer->err_time_interval);
|
||||
}
|
||||
|
||||
if (i == 4) {
|
||||
timer->csi2_err_ref_cnt = para[4];
|
||||
v4l2_info(&dev->v4l2_dev,
|
||||
"timer csi2 err ref val for resetting:%d\n",
|
||||
timer->csi2_err_ref_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
}else {
|
||||
timer->monitor_mode = RKCIF_MONITOR_MODE_IDLE;
|
||||
timer->err_time_interval = 0xffffffff;
|
||||
timer->frm_num_of_monitor_cycle = 0xffffffff;
|
||||
timer->triggered_frame_num = 0xffffffff;
|
||||
timer->csi2_err_ref_cnt = 0xffffffff;
|
||||
}
|
||||
|
||||
timer->is_running = false;
|
||||
timer->is_triggered = false;
|
||||
timer->is_buf_stop_update = false;
|
||||
timer->csi2_err_cnt_even = 0;
|
||||
timer->csi2_err_cnt_odd = 0;
|
||||
timer->csi2_err_fs_fe_cnt = 0;
|
||||
timer->csi2_err_fs_fe_detect_cnt = 0;
|
||||
|
||||
timer_setup(&timer->timer, rkcif_reset_watchdog_timer_handler, 0);
|
||||
|
||||
notifier->priority = 1;
|
||||
notifier->notifier_call = rkcif_reset_notifier;
|
||||
rkcif_csi2_register_notifier(notifier);
|
||||
|
||||
}
|
||||
|
||||
int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int inf_id)
|
||||
{
|
||||
struct device *dev = cif_dev->dev;
|
||||
@@ -838,6 +927,7 @@ int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int
|
||||
mutex_init(&cif_dev->stream_lock);
|
||||
spin_lock_init(&cif_dev->hdr_lock);
|
||||
spin_lock_init(&cif_dev->reset_watchdog_timer.timer_lock);
|
||||
spin_lock_init(&cif_dev->reset_watchdog_timer.csi2_err_lock);
|
||||
atomic_set(&cif_dev->pipe.power_cnt, 0);
|
||||
atomic_set(&cif_dev->pipe.stream_cnt, 0);
|
||||
atomic_set(&cif_dev->fh_cnt, 0);
|
||||
@@ -998,16 +1088,7 @@ static int rkcif_plat_probe(struct platform_device *pdev)
|
||||
if (rkcif_proc_init(cif_dev))
|
||||
dev_warn(dev, "dev:%s create proc failed\n", dev_name(dev));
|
||||
|
||||
cif_dev->reset_notifier.priority = 1;
|
||||
cif_dev->reset_notifier.notifier_call = rkcif_reset_notifier;
|
||||
rkcif_csi2_register_notifier(&cif_dev->reset_notifier);
|
||||
#if defined(CONFIG_ROCKCHIP_CIF_RESET_MONITOR_CONTINU)
|
||||
cif_dev->reset_watchdog_timer.reset_src = RKCIF_RESET_SRC_NORMAL;
|
||||
#else
|
||||
cif_dev->reset_watchdog_timer.reset_src = RKCIF_RESET_SRC_NON;
|
||||
#endif
|
||||
timer_setup(&cif_dev->reset_watchdog_timer.timer,
|
||||
rkcif_reset_watchdog_timer_handler, 0);
|
||||
rkcif_init_reset_monitor(cif_dev);
|
||||
|
||||
rkcif_soft_reset(cif_dev, true);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#define CIF_DRIVER_NAME "rkcif"
|
||||
#define CIF_VIDEODEVICE_NAME "stream_cif"
|
||||
|
||||
#define OF_CIF_MONITOR_PARA "rockchip,cif-monitor"
|
||||
#define CIF_MONITOR_PARA_NUM (5)
|
||||
|
||||
#define RKCIF_SINGLE_STREAM 1
|
||||
#define RKCIF_STREAM_CIF 0
|
||||
#define CIF_DVP_VDEV_NAME CIF_VIDEODEVICE_NAME "_dvp"
|
||||
@@ -301,14 +304,14 @@ struct rkcif_irq_stats {
|
||||
};
|
||||
|
||||
/*
|
||||
* the causation to do cif reset work
|
||||
* the detecting mode of cif reset timer
|
||||
* related with dts property:rockchip,cif-monitor
|
||||
*/
|
||||
enum rkcif_reset_src {
|
||||
RKCIF_RESET_SRC_NON = 0x0,
|
||||
RKCIF_RESET_SRC_NORMAL,
|
||||
RKCIF_RESET_SRC_ERR_CSI2,
|
||||
RKCIF_RESET_SRC_ERR_LVDS,
|
||||
RKCIF_RESET_SRC_ERR_APP,
|
||||
enum rkcif_monitor_mode {
|
||||
RKCIF_MONITOR_MODE_IDLE = 0x0,
|
||||
RKCIF_MONITOR_MODE_CONTINUE,
|
||||
RKCIF_MONITOR_MODE_TRIGGER,
|
||||
RKCIF_MONITOR_MODE_HOTPLUG,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -320,23 +323,40 @@ struct rkcif_resume_info {
|
||||
|
||||
struct rkcif_work_struct {
|
||||
struct work_struct work;
|
||||
enum rkcif_reset_src reset_src;
|
||||
enum rkmodule_reset_src reset_src;
|
||||
struct rkcif_resume_info resume_info;
|
||||
};
|
||||
|
||||
struct rkcif_timer {
|
||||
struct timer_list timer;
|
||||
spinlock_t timer_lock;
|
||||
spinlock_t csi2_err_lock;
|
||||
unsigned long cycle;
|
||||
/* unit: us */
|
||||
unsigned long line_end_cycle;
|
||||
unsigned int run_cnt;
|
||||
unsigned int max_run_cnt;
|
||||
unsigned int stop_index_of_run_cnt;
|
||||
unsigned int last_buf_wakeup_cnt;
|
||||
unsigned int csi_crc_cnt;
|
||||
unsigned long csi2_err_cnt_even;
|
||||
unsigned long csi2_err_cnt_odd;
|
||||
unsigned int csi2_err_ref_cnt;
|
||||
unsigned int csi2_err_fs_fe_cnt;
|
||||
unsigned int csi2_err_fs_fe_detect_cnt;
|
||||
unsigned int frm_num_of_monitor_cycle;
|
||||
unsigned int triggered_frame_num;
|
||||
unsigned int vts;
|
||||
unsigned int raw_height;
|
||||
/* unit: ms */
|
||||
unsigned int err_time_interval;
|
||||
unsigned long frame_end_cycle_us;
|
||||
unsigned int notifer_called_cnt;
|
||||
bool is_triggered;
|
||||
bool is_buf_stop_update;
|
||||
bool is_running;
|
||||
enum rkcif_reset_src reset_src;
|
||||
bool is_csi2_err_occurred;
|
||||
enum rkcif_monitor_mode monitor_mode;
|
||||
enum rkmodule_reset_src reset_src;
|
||||
};
|
||||
|
||||
struct rkcif_extend_info {
|
||||
|
||||
@@ -70,7 +70,12 @@ enum csi2_pads {
|
||||
};
|
||||
|
||||
enum csi2_err {
|
||||
RK_CSI2_ERR_CRC = 0,
|
||||
RK_CSI2_ERR_SOTSYN = 0x0,
|
||||
RK_CSI2_ERR_FS_FE_MIS,
|
||||
RK_CSI2_ERR_FRM_SEQ_ERR,
|
||||
RK_CSI2_ERR_CRC_ONCE,
|
||||
RK_CSI2_ERR_CRC,
|
||||
RK_CSI2_ERR_ALL,
|
||||
RK_CSI2_ERR_MAX
|
||||
};
|
||||
|
||||
@@ -680,7 +685,8 @@ static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
|
||||
{
|
||||
struct device *dev = ctx;
|
||||
struct csi2_dev *csi2 = sd_to_dev(dev_get_drvdata(dev));
|
||||
struct csi2_err_stats *err_stats = NULL;
|
||||
struct csi2_err_stats *err_list = NULL;
|
||||
unsigned long err_stat = 0;
|
||||
u32 val;
|
||||
|
||||
val = read_csihost_reg(csi2->base, CSIHOST_ERR1);
|
||||
@@ -688,35 +694,53 @@ static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
|
||||
write_csihost_reg(csi2->base,
|
||||
CSIHOST_ERR1, 0x0);
|
||||
|
||||
if (val & CSIHOST_ERR1_PHYERR_SPTSYNCHS)
|
||||
if (val & CSIHOST_ERR1_PHYERR_SPTSYNCHS) {
|
||||
err_list = &csi2->err_list[RK_CSI2_ERR_SOTSYN];
|
||||
err_list->cnt++;
|
||||
v4l2_err(&csi2->sd,
|
||||
"ERR1: start of transmission error(no synchronization achieved), reg: 0x%x\n",
|
||||
val);
|
||||
"ERR1: start of transmission error(no synchronization achieved), reg: 0x%x,cnt:%d\n",
|
||||
val, err_list->cnt);
|
||||
}
|
||||
|
||||
if (val & CSIHOST_ERR1_ERR_BNDRY_MATCH)
|
||||
if (val & CSIHOST_ERR1_ERR_BNDRY_MATCH) {
|
||||
err_list = &csi2->err_list[RK_CSI2_ERR_FS_FE_MIS];
|
||||
err_list->cnt++;
|
||||
v4l2_err(&csi2->sd,
|
||||
"ERR1: error matching frame start with frame end, reg: 0x%x\n",
|
||||
val);
|
||||
"ERR1: error matching frame start with frame end, reg: 0x%x,cnt:%d\n",
|
||||
val, err_list->cnt);
|
||||
}
|
||||
|
||||
if (val & CSIHOST_ERR1_ERR_SEQ)
|
||||
if (val & CSIHOST_ERR1_ERR_SEQ) {
|
||||
err_list = &csi2->err_list[RK_CSI2_ERR_FRM_SEQ_ERR];
|
||||
err_list->cnt++;
|
||||
v4l2_err(&csi2->sd,
|
||||
"ERR1: incorrect frame sequence detected, reg: 0x%x\n",
|
||||
val);
|
||||
"ERR1: incorrect frame sequence detected, reg: 0x%x,cnt:%d\n",
|
||||
val, err_list->cnt);
|
||||
}
|
||||
|
||||
if (val & CSIHOST_ERR1_ERR_FRM_DATA)
|
||||
if (val & CSIHOST_ERR1_ERR_FRM_DATA) {
|
||||
err_list = &csi2->err_list[RK_CSI2_ERR_CRC_ONCE];
|
||||
err_list->cnt++;
|
||||
v4l2_dbg(1, csi2_debug, &csi2->sd,
|
||||
"ERR1: at least one crc error, reg: 0x%x\n", val);
|
||||
"ERR1: at least one crc error, reg: 0x%x\n,cnt:%d", val, err_list->cnt);
|
||||
}
|
||||
|
||||
if (val & CSIHOST_ERR1_ERR_CRC) {
|
||||
|
||||
err_stats = &csi2->err_list[RK_CSI2_ERR_CRC];
|
||||
err_stats->cnt += 1;
|
||||
atomic_notifier_call_chain(&g_csi_host_chain, err_stats->cnt, NULL);
|
||||
|
||||
err_list = &csi2->err_list[RK_CSI2_ERR_CRC];
|
||||
err_list->cnt++;
|
||||
v4l2_err(&csi2->sd,
|
||||
"ERR1: crc errors, reg: 0x%x, cnt:%d\n",
|
||||
val, err_stats->cnt);
|
||||
val, err_list->cnt);
|
||||
}
|
||||
|
||||
csi2->err_list[RK_CSI2_ERR_ALL].cnt++;
|
||||
err_stat = ((csi2->err_list[RK_CSI2_ERR_FS_FE_MIS].cnt & 0xff) << 8) |
|
||||
((csi2->err_list[RK_CSI2_ERR_ALL].cnt) & 0xff);
|
||||
|
||||
atomic_notifier_call_chain(&g_csi_host_chain,
|
||||
err_stat,
|
||||
NULL);
|
||||
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#define CSI2_ERR_FSFE_MASK (0xff << 8)
|
||||
#define CSI2_ERR_COUNT_ALL_MASK (0xff)
|
||||
|
||||
u32 rkcif_csi2_get_sof(void);
|
||||
void rkcif_csi2_set_sof(u32 seq);
|
||||
void rkcif_csi2_event_inc_sof(void);
|
||||
|
||||
@@ -196,8 +196,26 @@ static const char *rkcif_pixelcode_to_string(u32 mbus_code)
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static const char *rkcif_get_monitor_mode(enum rkcif_monitor_mode monitor_mode)
|
||||
{
|
||||
switch (monitor_mode) {
|
||||
case RKCIF_MONITOR_MODE_IDLE:
|
||||
return "idle";
|
||||
case RKCIF_MONITOR_MODE_CONTINUE:
|
||||
return "continue";
|
||||
case RKCIF_MONITOR_MODE_TRIGGER:
|
||||
return "trigger";
|
||||
case RKCIF_MONITOR_MODE_HOTPLUG:
|
||||
return "hotplug";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void rkcif_show_mixed_info(struct rkcif_device *dev, struct seq_file *f)
|
||||
{
|
||||
enum rkcif_monitor_mode monitor_mode;
|
||||
|
||||
seq_printf(f, "Driver Version:v%02x.%02x.%02x\n",
|
||||
RKCIF_DRIVER_VERSION >> 16,
|
||||
(RKCIF_DRIVER_VERSION & 0xff00) >> 8,
|
||||
@@ -205,6 +223,10 @@ static void rkcif_show_mixed_info(struct rkcif_device *dev, struct seq_file *f)
|
||||
seq_printf(f, "Work Mode:%s\n",
|
||||
dev->workmode == RKCIF_WORKMODE_ONEFRAME ? "one frame" :
|
||||
dev->workmode == RKCIF_WORKMODE_PINGPONG ? "ping pong" : "line loop");
|
||||
|
||||
monitor_mode = dev->reset_watchdog_timer.monitor_mode;
|
||||
seq_printf(f, "Monitor Mode:%s\n",
|
||||
rkcif_get_monitor_mode(monitor_mode));
|
||||
}
|
||||
|
||||
static void rkcif_show_clks(struct rkcif_device *dev, struct seq_file *f)
|
||||
|
||||
@@ -322,9 +322,11 @@ enum cif_reg_index {
|
||||
#define IFIFO_OVERFLOW (0x1 << 4)
|
||||
#define DFIFO_OVERFLOW (0x1 << 5)
|
||||
#define BUS_ERR (0x1 << 6)
|
||||
#define PRE_INF_FRAME_END (0x01 << 8)
|
||||
#define PST_INF_FRAME_END (0x01 << 9)
|
||||
#define LINE_INT_END (0x1 << 10)
|
||||
#define FRAME_END_CLR (0x01 << 0)
|
||||
#define PRE_INF_FRAME_END_CLR (0x01 << 8)
|
||||
#define PST_INF_FRAME_END_CLR (0x01 << 9)
|
||||
#define INTSTAT_ERR (0xFC)
|
||||
#define DVP_ALL_OVERFLOW (IFIFO_OVERFLOW | DFIFO_OVERFLOW)
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
*2. support rk3568 csi-host
|
||||
*3. add dvp sof
|
||||
*4. add extended lines to out image for normal & hdr short frame
|
||||
*5. modify reset mechanism drivered by real-time frame rate
|
||||
*/
|
||||
|
||||
#define RKCIF_DRIVER_VERSION RKCIF_API_VERSION
|
||||
|
||||
@@ -69,6 +69,12 @@
|
||||
#define RKMODULE_GET_START_STREAM_SEQ \
|
||||
_IOR('V', BASE_VIDIOC_PRIVATE + 14, __u32)
|
||||
|
||||
#define RKMODULE_GET_VICAP_RST_INFO \
|
||||
_IOR('V', BASE_VIDIOC_PRIVATE + 15, struct rkmodule_vicap_reset_info)
|
||||
|
||||
#define RKMODULE_SET_VICAP_RST_INFO \
|
||||
_IOR('V', BASE_VIDIOC_PRIVATE + 16, struct rkmodule_vicap_reset_info)
|
||||
|
||||
/**
|
||||
* struct rkmodule_base_inf - module base information
|
||||
*
|
||||
@@ -370,4 +376,21 @@ enum rkmodule_start_stream_seq {
|
||||
RKMODULE_START_STREAM_FRONT,
|
||||
};
|
||||
|
||||
/*
|
||||
* the causation to do cif reset work
|
||||
*/
|
||||
enum rkmodule_reset_src {
|
||||
RKCIF_RESET_SRC_NON = 0x0,
|
||||
RKCIF_RESET_SRC_ERR_CSI2,
|
||||
RKCIF_RESET_SRC_ERR_LVDS,
|
||||
RKICF_RESET_SRC_ERR_CUTOFF,
|
||||
RKCIF_RESET_SRC_ERR_HOTPLUG,
|
||||
RKCIF_RESET_SRC_ERR_APP,
|
||||
};
|
||||
|
||||
struct rkmodule_vicap_reset_info {
|
||||
__u32 is_reset;
|
||||
enum rkmodule_reset_src src;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* _UAPI_RKMODULE_CAMERA_H */
|
||||
|
||||
Reference in New Issue
Block a user