From e3e12f52b214121840b44c91de5b3e5af5d3eb84 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 06 Nov 2023 03:04:41 +0000 Subject: [PATCH] rk3568 rt init --- 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