mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
media: rockchip: ispp: monitor thread to alive during work
Change-Id: I2c49787ef06f29ae6f279091ac5cf5c82371687c Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
@@ -258,9 +258,16 @@ static int rkispp_sd_s_stream(struct v4l2_subdev *sd, int on)
|
||||
video, s_stream, on);
|
||||
if ((on && ret) || (!on && !ret)) {
|
||||
ispp_sdev->state = ISPP_STOP;
|
||||
if (dev->stream_vdev.monitor.is_en &&
|
||||
dev->stream_vdev.monitor.is_restart)
|
||||
complete(&dev->stream_vdev.monitor.cmpl);
|
||||
if (dev->stream_vdev.monitor.is_en) {
|
||||
if (!completion_done(&dev->stream_vdev.monitor.cmpl))
|
||||
complete(&dev->stream_vdev.monitor.cmpl);
|
||||
if (!completion_done(&dev->stream_vdev.monitor.tnr.cmpl))
|
||||
complete(&dev->stream_vdev.monitor.tnr.cmpl);
|
||||
if (!completion_done(&dev->stream_vdev.monitor.nr.cmpl))
|
||||
complete(&dev->stream_vdev.monitor.nr.cmpl);
|
||||
if (!completion_done(&dev->stream_vdev.monitor.fec.cmpl))
|
||||
complete(&dev->stream_vdev.monitor.fec.cmpl);
|
||||
}
|
||||
rkispp_event_handle(dev, CMD_STREAM, &ispp_sdev->state);
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -618,6 +618,10 @@ static int config_tnr(struct rkispp_device *dev)
|
||||
rkispp_write(dev, RKISPP_TNR_GAIN_WR_VIR_STRIDE, ALIGN(width, 64) >> 4);
|
||||
rkispp_write(dev, RKISPP_CTRL_TNR_SIZE, height << 16 | width);
|
||||
|
||||
if (vdev->monitor.is_en) {
|
||||
init_completion(&vdev->monitor.tnr.cmpl);
|
||||
schedule_work(&vdev->monitor.tnr.work);
|
||||
}
|
||||
v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
|
||||
"%s size:%dx%d ctrl:0x%x core_ctrl:0x%x\n",
|
||||
__func__, width, height,
|
||||
@@ -808,6 +812,10 @@ static int config_nr_shp(struct rkispp_device *dev)
|
||||
rkispp_write(dev, RKISPP_NR_VIR_STRIDE_GAIN, ALIGN(width, 64) >> 4);
|
||||
rkispp_write(dev, RKISPP_CTRL_SIZE, height << 16 | width);
|
||||
|
||||
if (vdev->monitor.is_en) {
|
||||
init_completion(&vdev->monitor.nr.cmpl);
|
||||
schedule_work(&vdev->monitor.nr.work);
|
||||
}
|
||||
v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
|
||||
"%s size:%dx%d\n"
|
||||
"nr ctrl:0x%x ctrl_para:0x%x\n"
|
||||
@@ -872,6 +880,11 @@ static int config_fec(struct rkispp_device *dev)
|
||||
rkispp_write(dev, RKISPP_FEC_RD_VIR_STRIDE, ALIGN(width * mult, 16) >> 2);
|
||||
rkispp_write(dev, RKISPP_FEC_PIC_SIZE, height << 16 | width);
|
||||
rkispp_set_bits(dev, RKISPP_CTRL_QUICK, 0, GLB_FEC2SCL_EN);
|
||||
|
||||
if (vdev->monitor.is_en) {
|
||||
init_completion(&vdev->monitor.fec.cmpl);
|
||||
schedule_work(&vdev->monitor.fec.work);
|
||||
}
|
||||
v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
|
||||
"%s size:%dx%d ctrl:0x%x core_ctrl:0x%x\n",
|
||||
__func__, width, height,
|
||||
@@ -933,6 +946,7 @@ static int config_modules(struct rkispp_device *dev)
|
||||
dev->stream_vdev.monitor.restart_module = 0;
|
||||
dev->stream_vdev.monitor.is_restart = false;
|
||||
dev->stream_vdev.monitor.retry = 0;
|
||||
init_completion(&dev->stream_vdev.monitor.cmpl);
|
||||
|
||||
ret = config_tnr(dev);
|
||||
if (ret < 0)
|
||||
@@ -1912,6 +1926,8 @@ static void restart_module(struct rkispp_device *dev)
|
||||
u32 val = 0;
|
||||
|
||||
monitor->retry++;
|
||||
v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
|
||||
"%s cnt:%d\n", __func__, monitor->retry);
|
||||
if (dev->ispp_sdev.state == ISPP_STOP || monitor->retry > 3) {
|
||||
monitor->is_en = false;
|
||||
monitor->is_restart = false;
|
||||
@@ -1919,9 +1935,12 @@ static void restart_module(struct rkispp_device *dev)
|
||||
}
|
||||
if (monitor->monitoring_module)
|
||||
wait_for_completion_timeout(&monitor->cmpl,
|
||||
msecs_to_jiffies(400));
|
||||
if (dev->ispp_sdev.state == ISPP_STOP)
|
||||
msecs_to_jiffies(500));
|
||||
if (dev->ispp_sdev.state == ISPP_STOP) {
|
||||
monitor->is_en = false;
|
||||
monitor->is_restart = false;
|
||||
return;
|
||||
}
|
||||
rkispp_soft_reset(dev);
|
||||
rkispp_update_regs(dev, RKISPP_CTRL_QUICK, RKISPP_FEC_CROP);
|
||||
writel(ALL_FORCE_UPD, base + RKISPP_CTRL_UPDATE);
|
||||
@@ -1932,44 +1951,49 @@ static void restart_module(struct rkispp_device *dev)
|
||||
rkispp_write(dev, RKISPP_TNR_IIR_UV_BASE,
|
||||
rkispp_read(dev, RKISPP_TNR_WR_UV_BASE));
|
||||
monitor->monitoring_module |= MONITOR_TNR;
|
||||
schedule_work(&monitor->tnr.work);
|
||||
if (!completion_done(&monitor->tnr.cmpl))
|
||||
complete(&monitor->tnr.cmpl);
|
||||
}
|
||||
if (monitor->restart_module & MONITOR_NR) {
|
||||
val |= NR_SHP_ST;
|
||||
monitor->monitoring_module |= MONITOR_NR;
|
||||
schedule_work(&monitor->nr.work);
|
||||
if (!completion_done(&monitor->nr.cmpl))
|
||||
complete(&monitor->nr.cmpl);
|
||||
}
|
||||
if (monitor->restart_module & MONITOR_FEC) {
|
||||
val |= FEC_ST;
|
||||
monitor->monitoring_module |= MONITOR_FEC;
|
||||
schedule_work(&monitor->fec.work);
|
||||
if (!completion_done(&monitor->fec.cmpl))
|
||||
complete(&monitor->fec.cmpl);
|
||||
}
|
||||
writel(val, base + RKISPP_CTRL_STRT);
|
||||
monitor->is_restart = false;
|
||||
monitor->restart_module = 0;
|
||||
}
|
||||
|
||||
static void restart_monitor(struct work_struct *work)
|
||||
{
|
||||
struct module_monitor *m_monitor =
|
||||
container_of(work, struct module_monitor, work);
|
||||
struct rkispp_device *dev = m_monitor->dev;
|
||||
struct rkispp_monitor *monitor = &dev->stream_vdev.monitor;
|
||||
u32 time = (!m_monitor->time ? 300 : m_monitor->time) + 100;
|
||||
unsigned long lock_flags = 0;
|
||||
int ret;
|
||||
int ret, time;
|
||||
|
||||
if (dev->ispp_sdev.state == ISPP_STOP)
|
||||
return;
|
||||
ret = wait_for_completion_timeout(&m_monitor->cmpl,
|
||||
msecs_to_jiffies(time));
|
||||
spin_lock_irqsave(&monitor->lock, lock_flags);
|
||||
if (m_monitor->is_cancel) {
|
||||
m_monitor->is_cancel = false;
|
||||
spin_unlock_irqrestore(&monitor->lock, lock_flags);
|
||||
return;
|
||||
}
|
||||
monitor->monitoring_module &= ~m_monitor->module;
|
||||
if (!ret) {
|
||||
v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
|
||||
"%s module:0x%x enter\n", __func__, m_monitor->module);
|
||||
while (monitor->is_en) {
|
||||
time = (!m_monitor->time ? 300 : m_monitor->time) + 150;
|
||||
ret = wait_for_completion_timeout(&m_monitor->cmpl,
|
||||
msecs_to_jiffies(time));
|
||||
if (!(monitor->monitoring_module & m_monitor->module) ||
|
||||
ret || !monitor->is_en)
|
||||
continue;
|
||||
if (dev->ispp_sdev.state == ISPP_STOP)
|
||||
break;
|
||||
|
||||
spin_lock_irqsave(&monitor->lock, lock_flags);
|
||||
monitor->monitoring_module &= ~m_monitor->module;
|
||||
monitor->restart_module |= m_monitor->module;
|
||||
if (monitor->is_restart)
|
||||
ret = true;
|
||||
@@ -1982,15 +2006,19 @@ static void restart_monitor(struct work_struct *work)
|
||||
readl(dev->hw_dev->base_addr + RKISPP_TNR_IIR_UV_BASE_SHD));
|
||||
}
|
||||
v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
|
||||
"%s monitoring:0x%x module:0x%x timeout\n", __func__,
|
||||
"monitoring:0x%x module:0x%x timeout\n",
|
||||
monitor->monitoring_module, m_monitor->module);
|
||||
spin_unlock_irqrestore(&monitor->lock, lock_flags);
|
||||
if (!ret && monitor->is_restart)
|
||||
restart_module(dev);
|
||||
/* waitting for other working module if need restart ispp */
|
||||
if (monitor->is_restart &&
|
||||
!monitor->monitoring_module &&
|
||||
!completion_done(&monitor->cmpl))
|
||||
complete(&monitor->cmpl);
|
||||
}
|
||||
spin_unlock_irqrestore(&monitor->lock, lock_flags);
|
||||
if (!ret && monitor->is_restart)
|
||||
restart_module(dev);
|
||||
/* waitting for other working module if need restart ispp */
|
||||
if (monitor->is_restart && !monitor->monitoring_module)
|
||||
complete(&monitor->cmpl);
|
||||
v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
|
||||
"%s module:0x%x exit\n", __func__, m_monitor->module);
|
||||
}
|
||||
|
||||
static void monitor_init(struct rkispp_device *dev)
|
||||
@@ -2111,13 +2139,10 @@ static void fec_work_event(struct rkispp_device *dev,
|
||||
vdev->fec.dbg.id = seq;
|
||||
vdev->fec.dbg.timestamp = ktime_get_ns();
|
||||
if (monitor->is_en) {
|
||||
monitor->fec.is_cancel = false;
|
||||
monitor->fec.time = vdev->fec.dbg.interval / 1000 / 1000;
|
||||
if (monitor->monitoring_module & MONITOR_FEC)
|
||||
monitor->fec.is_cancel = true;
|
||||
else
|
||||
monitor->monitoring_module |= MONITOR_FEC;
|
||||
schedule_work(&monitor->fec.work);
|
||||
monitor->monitoring_module |= MONITOR_FEC;
|
||||
if (!completion_done(&monitor->fec.cmpl))
|
||||
complete(&monitor->fec.cmpl);
|
||||
}
|
||||
writel(FEC_ST, base + RKISPP_CTRL_STRT);
|
||||
vdev->fec.is_end = false;
|
||||
@@ -2313,13 +2338,10 @@ static void nr_work_event(struct rkispp_device *dev,
|
||||
vdev->nr.dbg.id = seq;
|
||||
vdev->nr.dbg.timestamp = ktime_get_ns();
|
||||
if (monitor->is_en) {
|
||||
monitor->nr.is_cancel = false;
|
||||
monitor->nr.time = vdev->nr.dbg.interval / 1000 / 1000;
|
||||
if (monitor->monitoring_module & MONITOR_NR)
|
||||
monitor->nr.is_cancel = true;
|
||||
else
|
||||
monitor->monitoring_module |= MONITOR_NR;
|
||||
schedule_work(&monitor->nr.work);
|
||||
monitor->monitoring_module |= MONITOR_NR;
|
||||
if (!completion_done(&monitor->nr.cmpl))
|
||||
complete(&monitor->nr.cmpl);
|
||||
}
|
||||
if (!is_quick)
|
||||
writel(NR_SHP_ST, base + RKISPP_CTRL_STRT);
|
||||
@@ -2537,13 +2559,10 @@ static void tnr_work_event(struct rkispp_device *dev,
|
||||
vdev->tnr.dbg.id = seq;
|
||||
vdev->tnr.dbg.timestamp = ktime_get_ns();
|
||||
if (monitor->is_en) {
|
||||
monitor->tnr.is_cancel = false;
|
||||
monitor->tnr.time = vdev->tnr.dbg.interval / 1000 / 1000;
|
||||
if (monitor->monitoring_module & MONITOR_TNR)
|
||||
monitor->tnr.is_cancel = true;
|
||||
else
|
||||
monitor->monitoring_module |= MONITOR_TNR;
|
||||
schedule_work(&monitor->tnr.work);
|
||||
monitor->monitoring_module |= MONITOR_TNR;
|
||||
if (!completion_done(&monitor->tnr.cmpl))
|
||||
complete(&monitor->tnr.cmpl);
|
||||
}
|
||||
writel(TNR_ST, base + RKISPP_CTRL_STRT);
|
||||
vdev->tnr.is_end = false;
|
||||
@@ -2617,18 +2636,27 @@ void rkispp_isr(u32 mis_val, struct rkispp_device *dev)
|
||||
}
|
||||
|
||||
if (mis_val & TNR_INT) {
|
||||
if (vdev->monitor.is_en)
|
||||
complete(&vdev->monitor.tnr.cmpl);
|
||||
if (vdev->monitor.is_en) {
|
||||
vdev->monitor.monitoring_module &= ~MONITOR_TNR;
|
||||
if (!completion_done(&vdev->monitor.tnr.cmpl))
|
||||
complete(&vdev->monitor.tnr.cmpl);
|
||||
}
|
||||
vdev->tnr.dbg.interval = ns - vdev->tnr.dbg.timestamp;
|
||||
}
|
||||
if (mis_val & NR_INT) {
|
||||
if (vdev->monitor.is_en)
|
||||
complete(&vdev->monitor.nr.cmpl);
|
||||
if (vdev->monitor.is_en) {
|
||||
vdev->monitor.monitoring_module &= ~MONITOR_NR;
|
||||
if (!completion_done(&vdev->monitor.nr.cmpl))
|
||||
complete(&vdev->monitor.nr.cmpl);
|
||||
}
|
||||
vdev->nr.dbg.interval = ns - vdev->nr.dbg.timestamp;
|
||||
}
|
||||
if (mis_val & FEC_INT) {
|
||||
if (vdev->monitor.is_en)
|
||||
complete(&vdev->monitor.fec.cmpl);
|
||||
if (vdev->monitor.is_en) {
|
||||
vdev->monitor.monitoring_module &= ~MONITOR_FEC;
|
||||
if (!completion_done(&vdev->monitor.fec.cmpl))
|
||||
complete(&vdev->monitor.fec.cmpl);
|
||||
}
|
||||
vdev->fec.dbg.interval = ns - vdev->fec.dbg.timestamp;
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,6 @@ struct module_monitor {
|
||||
struct completion cmpl;
|
||||
u16 time;
|
||||
u8 module;
|
||||
bool is_cancel;
|
||||
};
|
||||
|
||||
struct rkispp_monitor {
|
||||
|
||||
Reference in New Issue
Block a user