mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
media: rockchip: ispp: fbc error handle
Change-Id: I9c303ef76831ed45962991a8d7d6e8b67fce78f8 Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
@@ -107,6 +107,7 @@ extern bool rkispp_reg_withstream;
|
||||
extern char rkispp_reg_withstream_video_name[RKISPP_VIDEO_NAME_LEN];
|
||||
extern unsigned int rkispp_debug_reg;
|
||||
extern struct platform_driver rkispp_plat_drv;
|
||||
extern char rkispp_dump_path[128];
|
||||
|
||||
void rkispp_write(struct rkispp_device *dev, u32 reg, u32 val);
|
||||
void rkispp_set_bits(struct rkispp_device *dev, u32 reg, u32 mask, u32 val);
|
||||
|
||||
@@ -64,6 +64,10 @@ static unsigned int rkispp_wait_line;
|
||||
module_param_named(wait_line, rkispp_wait_line, uint, 0644);
|
||||
MODULE_PARM_DESC(wait_line, "rkispp wait line to buf done early");
|
||||
|
||||
char rkispp_dump_path[128];
|
||||
module_param_string(dump_path, rkispp_dump_path, sizeof(rkispp_dump_path), 0644);
|
||||
MODULE_PARM_DESC(dump_path, "rkispp dump debug file path");
|
||||
|
||||
void rkispp_set_clk_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
if (rkispp_clk_dbg)
|
||||
|
||||
@@ -2269,6 +2269,89 @@ unreg:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dump_file(struct rkispp_device *dev, u32 restart_module)
|
||||
{
|
||||
struct rkispp_stream_vdev *vdev = &dev->stream_vdev;
|
||||
void __iomem *base = dev->hw_dev->base_addr;
|
||||
struct rkispp_isp_buf_pool *buf;
|
||||
struct rkispp_dummy_buffer *dummy;
|
||||
struct file *fp = NULL;
|
||||
char file[160], reg[48];
|
||||
int i;
|
||||
|
||||
snprintf(file, sizeof(file), "%s/%s%d.reg",
|
||||
rkispp_dump_path, DRIVER_NAME, dev->dev_id);
|
||||
fp = filp_open(file, O_RDWR | O_CREAT, 0644);
|
||||
if (IS_ERR(fp)) {
|
||||
v4l2_err(&dev->v4l2_dev, "%s open %s fail\n", __func__, file);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < 0x1000; i += 16) {
|
||||
snprintf(reg, sizeof(reg), "ffb6%04x: %08x %08x %08x %08x\n",
|
||||
i, readl(base + i), readl(base + i + 4),
|
||||
readl(base + i + 8), readl(base + i + 12));
|
||||
kernel_write(fp, reg, strlen(reg), &fp->f_pos);
|
||||
}
|
||||
filp_close(fp, NULL);
|
||||
|
||||
if (restart_module & MONITOR_TNR) {
|
||||
if (vdev->tnr.cur_rd) {
|
||||
snprintf(file, sizeof(file), "%s/%s%d_tnr_cur.fbc",
|
||||
rkispp_dump_path, DRIVER_NAME, dev->dev_id);
|
||||
fp = filp_open(file, O_RDWR | O_CREAT, 0644);
|
||||
if (IS_ERR(fp)) {
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"%s open %s fail\n", __func__, file);
|
||||
return;
|
||||
}
|
||||
buf = get_pool_buf(dev, vdev->tnr.cur_rd);
|
||||
kernel_write(fp, buf->vaddr[0], vdev->tnr.cur_rd->dbuf[0]->size, &fp->f_pos);
|
||||
filp_close(fp, NULL);
|
||||
v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
|
||||
"dump tnr cur_rd dma:0x%x vaddr:%p\n",
|
||||
buf->dma[0], buf->vaddr[0]);
|
||||
}
|
||||
|
||||
if (vdev->tnr.nxt_rd && vdev->tnr.nxt_rd != vdev->tnr.cur_rd) {
|
||||
snprintf(file, sizeof(file), "%s/%s%d_tnr_nxt.fbc",
|
||||
rkispp_dump_path, DRIVER_NAME, dev->dev_id);
|
||||
fp = filp_open(file, O_RDWR | O_CREAT, 0644);
|
||||
if (IS_ERR(fp)) {
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"%s open %s fail\n", __func__, file);
|
||||
return;
|
||||
}
|
||||
buf = get_pool_buf(dev, vdev->tnr.nxt_rd);
|
||||
kernel_write(fp, buf->vaddr[0], vdev->tnr.nxt_rd->dbuf[0]->size, &fp->f_pos);
|
||||
filp_close(fp, NULL);
|
||||
v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
|
||||
"dump tnr nxt_rd dma:0x%x vaddr:%p\n",
|
||||
buf->dma[0], buf->vaddr[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(restart_module & MONITOR_FEC)) {
|
||||
for (i = 0; i < RKISPP_BUF_MAX; i++) {
|
||||
dummy = &vdev->tnr.buf.wr[i][0];
|
||||
if (!dummy->mem_priv)
|
||||
break;
|
||||
snprintf(file, sizeof(file), "%s/%s%d_iir%d.fbc",
|
||||
rkispp_dump_path, DRIVER_NAME, dev->dev_id, i);
|
||||
fp = filp_open(file, O_RDWR | O_CREAT, 0644);
|
||||
if (IS_ERR(fp)) {
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"%s open %s fail\n", __func__, file);
|
||||
return;
|
||||
}
|
||||
kernel_write(fp, dummy->vaddr, dummy->size, &fp->f_pos);
|
||||
filp_close(fp, NULL);
|
||||
v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev,
|
||||
"dump tnr wr dma:0x%x vaddr:%p\n",
|
||||
dummy->dma_addr, dummy->vaddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void restart_module(struct rkispp_device *dev)
|
||||
{
|
||||
struct rkispp_monitor *monitor = &dev->stream_vdev.monitor;
|
||||
@@ -2291,6 +2374,21 @@ static void restart_module(struct rkispp_device *dev)
|
||||
monitor->is_restart = false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (rkispp_dump_path[0] == '/')
|
||||
dump_file(dev, monitor->restart_module);
|
||||
|
||||
if (monitor->restart_module & MONITOR_TNR && monitor->tnr.is_err) {
|
||||
rkispp_set_bits(dev, RKISPP_TNR_CTRL, 0, SW_TNR_1ST_FRM);
|
||||
monitor->tnr.is_err = false;
|
||||
}
|
||||
if (monitor->restart_module & MONITOR_NR && monitor->nr.is_err) {
|
||||
rkispp_write(dev, RKISPP_NR_ADDR_BASE_Y,
|
||||
readl(base + RKISPP_NR_ADDR_BASE_Y_SHD));
|
||||
rkispp_write(dev, RKISPP_NR_ADDR_BASE_UV,
|
||||
readl(base + RKISPP_NR_ADDR_BASE_UV_SHD));
|
||||
monitor->nr.is_err = false;
|
||||
}
|
||||
rkispp_soft_reset(dev->hw_dev);
|
||||
rkispp_update_regs(dev, RKISPP_CTRL_QUICK, RKISPP_FEC_CROP);
|
||||
writel(ALL_FORCE_UPD, base + RKISPP_CTRL_UPDATE);
|
||||
@@ -2797,6 +2895,7 @@ static void nr_work_event(struct rkispp_device *dev,
|
||||
if (monitor->is_en) {
|
||||
monitor->nr.time = vdev->nr.dbg.interval / 1000 / 1000;
|
||||
monitor->monitoring_module |= MONITOR_NR;
|
||||
monitor->nr.is_err = false;
|
||||
if (!completion_done(&monitor->nr.cmpl))
|
||||
complete(&monitor->nr.cmpl);
|
||||
}
|
||||
@@ -3107,6 +3206,7 @@ static void tnr_work_event(struct rkispp_device *dev,
|
||||
if (monitor->is_en) {
|
||||
monitor->tnr.time = vdev->tnr.dbg.interval / 1000 / 1000;
|
||||
monitor->monitoring_module |= MONITOR_TNR;
|
||||
monitor->tnr.is_err = false;
|
||||
if (!completion_done(&monitor->tnr.cmpl))
|
||||
complete(&monitor->tnr.cmpl);
|
||||
}
|
||||
@@ -3302,9 +3402,10 @@ void rkispp_isr(u32 mis_val, struct rkispp_device *dev)
|
||||
{
|
||||
struct rkispp_stream_vdev *vdev;
|
||||
struct rkispp_stream *stream;
|
||||
u32 i, err_mask = NR_LOST_ERR | TNR_LOST_ERR |
|
||||
FBCH_EMPTY_NR | FBCH_EMPTY_TNR | FBCD_DEC_ERR_NR |
|
||||
FBCD_DEC_ERR_TNR | BUS_ERR_NR | BUS_ERR_TNR;
|
||||
u32 i, nr_err = NR_LOST_ERR | FBCH_EMPTY_NR |
|
||||
FBCD_DEC_ERR_NR | BUS_ERR_NR;
|
||||
u32 tnr_err = TNR_LOST_ERR | FBCH_EMPTY_TNR |
|
||||
FBCD_DEC_ERR_TNR | BUS_ERR_TNR;
|
||||
u64 ns = ktime_get_ns();
|
||||
|
||||
v4l2_dbg(3, rkispp_debug, &dev->v4l2_dev,
|
||||
@@ -3312,7 +3413,11 @@ void rkispp_isr(u32 mis_val, struct rkispp_device *dev)
|
||||
|
||||
vdev = &dev->stream_vdev;
|
||||
dev->isr_cnt++;
|
||||
if (mis_val & err_mask) {
|
||||
if (mis_val & (tnr_err | nr_err)) {
|
||||
if (mis_val & tnr_err)
|
||||
vdev->monitor.tnr.is_err = true;
|
||||
if (mis_val & nr_err)
|
||||
vdev->monitor.nr.is_err = true;
|
||||
dev->isr_err_cnt++;
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"ispp err:0x%x, seq:%d\n",
|
||||
@@ -3348,7 +3453,7 @@ void rkispp_isr(u32 mis_val, struct rkispp_device *dev)
|
||||
(dev->isp_mode & ISP_ISPP_QUICK))
|
||||
++dev->ispp_sdev.frm_sync_seq;
|
||||
|
||||
if (mis_val & TNR_INT)
|
||||
if (mis_val & TNR_INT && !dev->hw_dev->is_first)
|
||||
if (rkispp_read(dev, RKISPP_TNR_CTRL) & SW_TNR_1ST_FRM)
|
||||
rkispp_clear_bits(dev, RKISPP_TNR_CTRL, SW_TNR_1ST_FRM);
|
||||
|
||||
|
||||
@@ -184,6 +184,7 @@ struct module_monitor {
|
||||
struct completion cmpl;
|
||||
u16 time;
|
||||
u8 module;
|
||||
bool is_err;
|
||||
};
|
||||
|
||||
struct rkispp_monitor {
|
||||
|
||||
Reference in New Issue
Block a user