From 0d8657dd3056063fb115946b10157477b5c70451 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 20 Nov 2023 09:09:45 +0000
Subject: [PATCH] enable lvds 1280x800
---
kernel/drivers/media/platform/rockchip/cif/capture.c | 141 +++++++++++++++++++++++++---------------------
1 files changed, 76 insertions(+), 65 deletions(-)
diff --git a/kernel/drivers/media/platform/rockchip/cif/capture.c b/kernel/drivers/media/platform/rockchip/cif/capture.c
index ac8b596..25c664d 100644
--- a/kernel/drivers/media/platform/rockchip/cif/capture.c
+++ b/kernel/drivers/media/platform/rockchip/cif/capture.c
@@ -553,18 +553,21 @@
case MEDIA_BUS_FMT_SGBRG8_1X8:
case MEDIA_BUS_FMT_SGRBG8_1X8:
case MEDIA_BUS_FMT_SRGGB8_1X8:
+ case MEDIA_BUS_FMT_Y8_1X8:
return 0x2a;
/* csi raw10 */
case MEDIA_BUS_FMT_SBGGR10_1X10:
case MEDIA_BUS_FMT_SGBRG10_1X10:
case MEDIA_BUS_FMT_SGRBG10_1X10:
case MEDIA_BUS_FMT_SRGGB10_1X10:
+ case MEDIA_BUS_FMT_Y10_1X10:
return 0x2b;
/* csi raw12 */
case MEDIA_BUS_FMT_SBGGR12_1X12:
case MEDIA_BUS_FMT_SGBRG12_1X12:
case MEDIA_BUS_FMT_SGRBG12_1X12:
case MEDIA_BUS_FMT_SRGGB12_1X12:
+ case MEDIA_BUS_FMT_Y12_1X12:
return 0x2c;
/* csi uyvy 422 */
case MEDIA_BUS_FMT_UYVY8_2X8:
@@ -2425,7 +2428,7 @@
int i;
unsigned long flags;
- mutex_lock(&dev->stream_lock);
+ mutex_lock(&dev->hw_dev->dev_lock);
v4l2_info(&dev->v4l2_dev, "stream[%d] start stopping\n", stream->id);
@@ -2499,20 +2502,18 @@
if (dev->can_be_reset && can_reset) {
rkcif_do_cru_reset(dev);
dev->can_be_reset = false;
- dev->reset_work_cancel = true;
+ hw_dev->reset_work_cancel = true;
hw_dev->hw_timer.is_running = false;
hw_dev->reset_info.is_need_reset = 0;
}
spin_unlock_irqrestore(&hw_dev->hw_timer.timer_lock, flags);
-
- pm_runtime_put_sync(dev->dev);
if (!atomic_read(&dev->pipe.stream_cnt) && dev->dummy_buf.vaddr)
rkcif_destroy_dummy_buf(stream);
v4l2_info(&dev->v4l2_dev, "stream[%d] stopping finished\n", stream->id);
- mutex_unlock(&dev->stream_lock);
+ mutex_unlock(&dev->hw_dev->dev_lock);
}
/*
@@ -3081,7 +3082,7 @@
v4l2_info(&dev->v4l2_dev, "stream[%d] start streaming\n", stream->id);
- mutex_lock(&dev->stream_lock);
+ mutex_lock(&dev->hw_dev->dev_lock);
if (WARN_ON(stream->state != RKCIF_STATE_READY)) {
ret = -EBUSY;
@@ -3141,14 +3142,6 @@
v4l2_err(v4l2_dev, "Failed to create dummy_buf, %d\n", ret);
goto destroy_buf;
}
- }
-
- /* enable clocks/power-domains */
- ret = pm_runtime_get_sync(dev->dev);
- if (ret < 0) {
- v4l2_err(v4l2_dev, "Failed to get runtime pm, %d\n",
- ret);
- goto destroy_buf;
}
ret = dev->pipe.open(&dev->pipe, &node->vdev.entity, true);
@@ -3218,7 +3211,8 @@
}
}
- dev->reset_work_cancel = false;
+ if (dev->hw_dev->reset_work_cancel)
+ dev->hw_dev->reset_work_cancel = false;
if (dev->hdr.mode == NO_HDR)
stream->streamon_timestamp = ktime_get_ns();
goto out;
@@ -3246,7 +3240,7 @@
}
out:
- mutex_unlock(&dev->stream_lock);
+ mutex_unlock(&dev->hw_dev->dev_lock);
return ret;
}
@@ -3524,6 +3518,13 @@
return ret;
}
+ /* enable clocks/power-domains */
+ ret = pm_runtime_get_sync(cifdev->dev);
+ if (ret < 0) {
+ v4l2_err(vdev, "Failed to get runtime pm, %d\n",
+ ret);
+ return ret;
+ }
/*
* Soft reset via CRU.
* Because CRU would reset iommu too, so there's not chance
@@ -3574,6 +3575,7 @@
else if (atomic_read(&cifdev->fh_cnt) < 0)
atomic_set(&cifdev->fh_cnt, 0);
mutex_unlock(&cifdev->stream_lock);
+ pm_runtime_put_sync(cifdev->dev);
return ret;
}
@@ -3584,6 +3586,9 @@
.unlocked_ioctl = video_ioctl2,
.poll = vb2_fop_poll,
.mmap = vb2_fop_mmap,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl32 = video_ioctl2,
+#endif
};
static int rkcif_enum_input(struct file *file, void *priv,
@@ -3925,6 +3930,7 @@
int vc = 0;
struct rkcif_reset_info *reset_info;
int reset_src = 0;
+ unsigned long flags;
switch (cmd) {
case RKCIF_CMD_GET_CSI_MEMORY_MODE:
@@ -3967,12 +3973,16 @@
break;
case RKCIF_CMD_GET_RESET_INFO:
reset_info = (struct rkcif_reset_info *)arg;
+ spin_lock_irqsave(&dev->hw_dev->spin_lock, flags);
*reset_info = dev->hw_dev->reset_info;
- if (dev->hw_dev->reset_info.is_need_reset)
- dev->hw_dev->reset_info.is_need_reset = 0;
+ spin_unlock_irqrestore(&dev->hw_dev->spin_lock, flags);
break;
case RKCIF_CMD_SET_RESET:
reset_src = *(int *)arg;
+ spin_lock_irqsave(&dev->hw_dev->spin_lock, flags);
+ if (dev->hw_dev->reset_info.is_need_reset)
+ dev->hw_dev->reset_info.is_need_reset = 0;
+ spin_unlock_irqrestore(&dev->hw_dev->spin_lock, flags);
return rkcif_do_reset_work(dev, reset_src);
default:
return -EINVAL;
@@ -4789,6 +4799,7 @@
if (dev->irq_stats.csi_bwidth_lack_cnt) {
is_triggered = true;
dev->irq_stats.csi_bwidth_lack_cnt = 0;
+ v4l2_info(&dev->v4l2_dev, "reset for bandwidth lack\n");
}
if (dev->irq_stats.csi_overflow_cnt) {
is_triggered = true;
@@ -5402,7 +5413,6 @@
for (i = 0, j = 0; i < RKCIF_MAX_STREAM_MIPI; i++) {
stream = &cif_dev->stream[i];
- mutex_lock(&cif_dev->stream_lock);
if (stream->state == RKCIF_STATE_STREAMING) {
stream_off_cnt++;
@@ -5422,9 +5432,7 @@
stream->frame_idx,
sof_cnt);
- resume_info->frm_sync_seq = sof_cnt;
- if (stream->frame_idx != sof_cnt)
- stream->frame_idx = sof_cnt;
+ resume_info->frm_sync_seq = stream->frame_idx;
}
stream->state = RKCIF_STATE_RESET_IN_STREAMING;
@@ -5438,7 +5446,6 @@
__func__, stream->id, stream->frame_idx, rkcif_csi2_get_sof());
}
- mutex_unlock(&cif_dev->stream_lock);
}
if (!stream_off_cnt)
return 0;
@@ -5486,7 +5493,6 @@
stream = resume_stream[i];
if (stream == NULL || stream->state != RKCIF_STATE_RESET_IN_STREAMING)
break;
- mutex_lock(&cif_dev->stream_lock);
stream_on_cnt++;
stream->fs_cnt_in_single_frame = 0;
if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
@@ -5514,7 +5520,6 @@
}
atomic_inc(&p->stream_cnt);
stream->streamon_timestamp = ktime_get_ns();
- mutex_unlock(&cif_dev->stream_lock);
v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
"resume stream[%d], frm_idx:%d, csi_sof:%d\n",
stream->id, stream->frame_idx,
@@ -5552,11 +5557,9 @@
v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev, "do rkcif reset successfully!\n");
- mutex_unlock(&cif_dev->stream_lock);
return 0;
unlock_stream:
- mutex_unlock(&cif_dev->stream_lock);
return ret;
}
@@ -5570,8 +5573,13 @@
int i = 0;
int ret = 0;
- v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev, "do rkcif reset\n");
+ v4l2_info(&cif_dev->v4l2_dev, "do rkcif reset\n");
+ mutex_lock(&cif_dev->hw_dev->dev_lock);
+ if (hw->reset_work_cancel) {
+ mutex_unlock(&hw->dev_lock);
+ return 0;
+ }
for (i = 0; i < hw->dev_num; i++) {
cifdev = hw->cif_dev[i];
resume_info[i] = &cifdev->reset_work.resume_info;
@@ -5585,13 +5593,7 @@
rkcif_do_cru_reset(cif_dev);
- rkcif_disable_sys_clk(cif_dev->hw_dev);
-
- udelay(5);
-
- ret |= rkcif_enable_sys_clk(cif_dev->hw_dev);
- if (ret < 0)
- v4l2_err(&cif_dev->v4l2_dev, "%s:resume cif clk failed\n", __func__);
+ udelay(30);
for (i = 0; i < hw->dev_num; i++) {
cifdev = hw->cif_dev[i];
@@ -5607,8 +5609,8 @@
hw->hw_timer.is_running = false;
rkcif_monitor_reset_event(cif_dev->hw_dev);
- v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev, "do rkcif reset successfully!\n");
-
+ v4l2_info(&cif_dev->v4l2_dev, "do rkcif reset successfully!\n");
+ mutex_unlock(&hw->dev_lock);
return ret;
}
@@ -5710,8 +5712,10 @@
spin_unlock_irqrestore(&timer->csi2_err_lock, flags);
}
if (hw_timer->is_reset_by_user) {
+ spin_lock_irqsave(&hw->spin_lock, flags);
hw->reset_info.is_need_reset = 1;
hw->reset_info.reset_src = hw_timer->reset_src;
+ spin_unlock_irqrestore(&hw->spin_lock, flags);
} else {
dev->reset_work.reset_src = hw_timer->reset_src;
if (schedule_work(&dev->reset_work.work)) {
@@ -5762,8 +5766,10 @@
hw_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 && stream->cifdev->inf_id == RKCIF_MIPI_LVDS)
+ if (!is_reset && stream->cifdev->inf_id == RKCIF_MIPI_LVDS) {
+ hw_timer->reset_src = RKICF_RESET_SRC_ERR_CUTOFF;
is_reset = rkcif_is_csi2_err_trigger_reset(timer);
+ }
} else if (hw_timer->monitor_mode == RKCIF_MONITOR_MODE_CONTINUE) {
if (stream->cifdev->inf_id == RKCIF_MIPI_LVDS)
is_reset = rkcif_is_csi2_err_trigger_reset(timer);
@@ -5859,6 +5865,7 @@
int is_reset = 0;
int check_cnt = 0;
bool is_mod_timer = false;
+ struct rkmodule_vicap_reset_info rst_info;
for (i = 0; i < hw->dev_num; i++) {
dev = hw->cif_dev[i];
@@ -5867,7 +5874,16 @@
&is_mod_timer);
if (is_reset)
break;
+ }
+ if (hw_timer->monitor_mode == RKCIF_MONITOR_MODE_HOTPLUG && is_reset) {
+ for (i = 0; i < hw->dev_num; i++) {
+ dev = hw->cif_dev[i];
+ rst_info.is_reset = 0;
+ if (dev->terminal_sensor.sd)
+ v4l2_subdev_call(dev->terminal_sensor.sd, core, ioctl,
+ RKMODULE_SET_VICAP_RST_INFO, &rst_info);
+ }
}
if (!is_reset && is_mod_timer)
@@ -6069,6 +6085,7 @@
}
}
+#define CSI_START_INTSTAT(id) (0x3 << ((id) * 2))
void rkcif_irq_pingpong(struct rkcif_device *cif_dev)
{
struct rkcif_stream *stream;
@@ -6125,27 +6142,6 @@
__func__);
}
- if (intstat & CSI_FRAME0_START_ID0) {
- if (mbus->type == V4L2_MBUS_CSI2)
- rkcif_csi2_event_inc_sof();
- else if (mbus->type == V4L2_MBUS_CCP2)
- rkcif_lvds_event_inc_sof(cif_dev);
- detect_stream->fs_cnt_in_single_frame++;
- spin_lock_irqsave(&detect_stream->fps_lock, flags);
- detect_stream->readout.fs_timestamp = ktime_get_ns();
- spin_unlock_irqrestore(&detect_stream->fps_lock, flags);
- }
-
- if (intstat & CSI_FRAME1_START_ID0) {
- if (mbus->type == V4L2_MBUS_CSI2)
- rkcif_csi2_event_inc_sof();
- else if (mbus->type == V4L2_MBUS_CCP2)
- rkcif_lvds_event_inc_sof(cif_dev);
- detect_stream->fs_cnt_in_single_frame++;
- spin_lock_irqsave(&detect_stream->fps_lock, flags);
- detect_stream->readout.fs_timestamp = ktime_get_ns();
- spin_unlock_irqrestore(&detect_stream->fps_lock, flags);
- }
for (i = 0; i < RKCIF_MAX_STREAM_MIPI; i++) {
if (intstat & CSI_LINE_INTSTAT(i)) {
stream = &cif_dev->stream[i];
@@ -6159,11 +6155,6 @@
"%s: id0 cur line:%d\n", __func__, lastline & 0x3fff);
}
}
-
- /* if do not reach frame dma end, return irq */
- mipi_id = rkcif_csi_g_mipi_id(&cif_dev->v4l2_dev, intstat);
- if (mipi_id < 0)
- return;
for (i = 0; i < RKCIF_MAX_STREAM_MIPI; i++) {
mipi_id = rkcif_csi_g_mipi_id(&cif_dev->v4l2_dev,
@@ -6220,8 +6211,28 @@
detect_stream->fs_cnt_in_single_frame--;
}
}
+ cif_dev->irq_stats.all_frm_end_cnt++;
}
- cif_dev->irq_stats.all_frm_end_cnt++;
+ for (i = 0; i < RKCIF_MAX_STREAM_MIPI; i++) {
+ if (intstat & CSI_START_INTSTAT(i)) {
+ stream = &cif_dev->stream[i];
+ if (i == 0) {
+ if (mbus->type == V4L2_MBUS_CSI2)
+ rkcif_csi2_event_inc_sof();
+ else if (mbus->type == V4L2_MBUS_CCP2)
+ rkcif_lvds_event_inc_sof(cif_dev);
+ stream->fs_cnt_in_single_frame++;
+ spin_lock_irqsave(&stream->fps_lock, flags);
+ stream->readout.fs_timestamp = ktime_get_ns();
+ spin_unlock_irqrestore(&stream->fps_lock, flags);
+ } else {
+ spin_lock_irqsave(&stream->fps_lock, flags);
+ stream->readout.fs_timestamp = ktime_get_ns();
+ spin_unlock_irqrestore(&stream->fps_lock, flags);
+ }
+ }
+ }
+
} else {
u32 lastline, lastpix, ctl;
u32 cif_frmst, frmid, int_en;
--
Gitblit v1.6.2