media: rockchip: isp: support rdbk without aiq

aiq no set readback mode and isp set auto readback mode
echo Y > /sys/module/video_rkisp/parameters/rdbk_auto

Change-Id: I78541b7a88bbfa300323a3c4ef4f8f512d7208bf
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2022-07-19 17:18:12 +08:00
committed by Tao Huang
parent 81f7ff481e
commit 62fa0cda98
9 changed files with 158 additions and 73 deletions

View File

@@ -220,7 +220,7 @@ static int sditf_get_selection(struct v4l2_subdev *sd,
static void sditf_reinit_mode(struct sditf_priv *priv, struct rkisp_vicap_mode *mode)
{
if (mode->is_rdbk) {
if (mode->rdbk_mode) {
priv->toisp_inf.link_mode = TOISP_NONE;
} else {
if (strstr(mode->name, RKISP0_DEVNAME))
@@ -237,8 +237,8 @@ static void sditf_reinit_mode(struct sditf_priv *priv, struct rkisp_vicap_mode *
__func__, mode->name);
}
v4l2_dbg(3, rkcif_debug, &priv->cif_dev->v4l2_dev,
"%s, mode->is_rdbk %d, mode->name %s, link_mode %d\n",
__func__, mode->is_rdbk, mode->name, priv->toisp_inf.link_mode);
"%s, mode->rdbk_mode %d, mode->name %s, link_mode %d\n",
__func__, mode->rdbk_mode, mode->name, priv->toisp_inf.link_mode);
}
static long sditf_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
@@ -829,7 +829,7 @@ static int rkcif_subdev_media_init(struct sditf_priv *priv)
strncpy(priv->sd.name, dev_name(cif_dev->dev), sizeof(priv->sd.name));
priv->cap_info.width = 0;
priv->cap_info.height = 0;
priv->mode.is_rdbk = 0;
priv->mode.rdbk_mode = 0;
priv->toisp_inf.link_mode = TOISP_NONE;
priv->toisp_inf.ch_info[0].is_valid = false;
priv->toisp_inf.ch_info[1].is_valid = false;

View File

@@ -116,6 +116,7 @@ struct rkisp_buffer {
void *vaddr[VIDEO_MAX_PLANES];
u32 buff_addr[VIDEO_MAX_PLANES];
int dev_id;
void *other;
};
struct rkisp_dummy_buffer {

View File

@@ -572,12 +572,14 @@ int rkisp_csi_config_patch(struct rkisp_device *dev)
ret = rkisp_csi_get_hdr_cfg(dev, &hdr_cfg);
if (dev->isp_inp & INP_CIF) {
struct rkisp_vicap_mode mode;
int buf_cnt;
memset(&mode, 0, sizeof(mode));
mode.name = dev->name;
mode.is_rdbk = true;
get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
if (!mipi_sensor)
return -EINVAL;
dev->hdr.op_mode = HDR_NORMAL;
dev->hdr.esp_mode = HDR_NORMAL_VC;
if (!ret) {
@@ -591,13 +593,14 @@ int rkisp_csi_config_patch(struct rkisp_device *dev)
dev->hdr.op_mode = HDR_RDBK_FRAME1;
if (dev->isp_inp == INP_CIF && dev->hw_dev->is_single && dev->isp_ver > ISP_V21)
mode.is_rdbk = false;
v4l2_subdev_call(mipi_sensor, core, ioctl,
RKISP_VICAP_CMD_MODE, &mode);
mode.rdbk_mode = dev->is_rdbk_auto ? RKISP_VICAP_RDBK_AUTO : RKISP_VICAP_ONLINE;
else
mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
v4l2_subdev_call(mipi_sensor, core, ioctl, RKISP_VICAP_CMD_MODE, &mode);
dev->vicap_in = mode.input;
/* vicap direct to isp */
if ((dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32) &&
!mode.is_rdbk) {
!mode.rdbk_mode) {
switch (dev->hdr.op_mode) {
case HDR_RDBK_FRAME3:
dev->hdr.op_mode = HDR_LINEX3_DDR;
@@ -608,12 +611,15 @@ int rkisp_csi_config_patch(struct rkisp_device *dev)
default:
dev->hdr.op_mode = HDR_NORMAL;
}
if (dev->hdr.op_mode != HDR_NORMAL && mipi_sensor) {
int cnt = RKISP_VICAP_BUF_CNT;
if (dev->hdr.op_mode != HDR_NORMAL) {
buf_cnt = 1;
v4l2_subdev_call(mipi_sensor, core, ioctl,
RKISP_VICAP_CMD_INIT_BUF, &cnt);
RKISP_VICAP_CMD_INIT_BUF, &buf_cnt);
}
} else if (mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
buf_cnt = RKISP_VICAP_BUF_CNT;
v4l2_subdev_call(mipi_sensor, core, ioctl,
RKISP_VICAP_CMD_INIT_BUF, &buf_cnt);
}
} else {
dev->hdr.op_mode = hdr_cfg.hdr_mode;

View File

@@ -67,6 +67,10 @@ bool rkisp_irq_dbg;
module_param_named(irq_dbg, rkisp_irq_dbg, bool, 0644);
MODULE_PARM_DESC(irq_dbg, "rkisp interrupt runtime");
static bool rkisp_rdbk_auto;
module_param_named(rdbk_auto, rkisp_rdbk_auto, bool, 0644);
MODULE_PARM_DESC(irq_dbg, "rkisp and vicap auto readback mode");
static bool rkisp_clk_dbg;
module_param_named(clk_dbg, rkisp_clk_dbg, bool, 0644);
MODULE_PARM_DESC(clk_dbg, "rkisp clk set by user");
@@ -958,6 +962,7 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev)
isp_dev->cap_dev.wait_line = rkisp_wait_line;
isp_dev->cap_dev.wrap_line = rkisp_wrap_line;
isp_dev->is_rdbk_auto = rkisp_rdbk_auto;
mutex_lock(&isp_dev->hw_dev->dev_lock);
ret = pm_runtime_get_sync(isp_dev->hw_dev->dev);
mutex_unlock(&isp_dev->hw_dev->dev_lock);

View File

@@ -245,6 +245,7 @@ struct rkisp_device {
bool is_cmsk_upd;
bool is_hw_link;
bool is_bigmode;
bool is_rdbk_auto;
struct rkisp_vicap_input vicap_in;

View File

@@ -388,13 +388,14 @@ static void update_rawrd(struct rkisp_stream *stream)
}
stream->frame_end = false;
if (stream->id == RKISP_STREAM_RAWRD2 &&
stream->out_isp_fmt.fmt_type == FMT_YUV) {
(stream->out_isp_fmt.fmt_type == FMT_YUV ||
dev->dmarx_dev.trigger == T_AUTO)) {
struct vb2_v4l2_buffer *vbuf = &stream->curr_buf->vb;
struct isp2x_csi_trigger trigger = {
.frame_timestamp = vbuf->vb2_buf.timestamp,
.sof_timestamp = vbuf->vb2_buf.timestamp,
.frame_id = vbuf->sequence,
.mode = T_START_X1,
.mode = 0,
.times = 0,
};
@@ -447,8 +448,35 @@ static int dmarx_frame_end(struct rkisp_stream *stream)
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
if (stream->curr_buf) {
vb2_buffer_done(&stream->curr_buf->vb.vb2_buf,
VB2_BUF_STATE_DONE);
if (stream->curr_buf->other) {
struct rkisp_device *dev = stream->ispdev;
struct v4l2_subdev *sd = dev->active_sensor->sd;
struct rkisp_rx_buf *rx_buf = stream->curr_buf->other;
if (rx_buf->is_switch && stream->id == RKISP_STREAM_RAWRD2) {
switch (dev->rd_mode) {
case HDR_RDBK_FRAME3:
dev->rd_mode = HDR_LINEX3_DDR;
break;
case HDR_RDBK_FRAME2:
dev->rd_mode = HDR_LINEX2_DDR;
break;
default:
dev->rd_mode = HDR_NORMAL;
}
dev->hdr.op_mode = dev->rd_mode;
rkisp_unite_write(dev, CSI2RX_CTRL0,
SW_IBUF_OP_MODE(dev->hdr.op_mode),
true, dev->hw_dev->is_unite);
rkisp_unite_set_bits(dev, CSI2RX_MASK_STAT,
0, ISP21_MIPI_DROP_FRM,
true, dev->hw_dev->is_unite);
}
rx_buf->runtime_us = dev->isp_sdev.dbg.interval / 1000;
v4l2_subdev_call(sd, video, s_rx_buffer, rx_buf, NULL);
} else {
vb2_buffer_done(&stream->curr_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
stream->curr_buf = NULL;
}
@@ -460,7 +488,7 @@ static int dmarx_frame_end(struct rkisp_stream *stream)
list_del(&stream->curr_buf->queue);
}
if (stream->streaming)
if (stream->curr_buf)
stream->ops->update_mi(stream);
spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
return 0;
@@ -552,6 +580,7 @@ static void rkisp_buf_queue(struct vb2_buffer *vb)
struct sg_table *sgt;
int i;
ispbuf->other = NULL;
memset(ispbuf->buff_addr, 0, sizeof(ispbuf->buff_addr));
for (i = 0; i < isp_fmt->mplanes; i++) {
void *vaddr = vb2_plane_vaddr(vb, i);
@@ -619,15 +648,15 @@ static void destroy_buf_queue(struct rkisp_stream *stream,
unsigned long lock_flags = 0;
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
if (stream->curr_buf) {
if (stream->curr_buf && !stream->curr_buf->other)
list_add_tail(&stream->curr_buf->queue, &stream->buf_queue);
stream->curr_buf = NULL;
}
stream->curr_buf = NULL;
while (!list_empty(&stream->buf_queue)) {
buf = list_first_entry(&stream->buf_queue,
struct rkisp_buffer, queue);
list_del(&buf->queue);
vb2_buffer_done(&buf->vb.vb2_buf, state);
if (!buf->other)
vb2_buffer_done(&buf->vb.vb2_buf, state);
}
spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
}
@@ -1133,7 +1162,7 @@ void rkisp_dmarx_get_frame(struct rkisp_device *dev, u32 *id,
u64 sof_time = 0, frame_timestamp = 0;
u32 frame_id = 0;
if (!dev->dmarx_dev.trigger && id) {
if (!IS_HDR_RDBK(dev->rd_mode) && id) {
*id = atomic_read(&dev->isp_sdev.frm_sync_seq) - 1;
return;
}

View File

@@ -6,6 +6,7 @@
#include "capture.h"
#include "common.h"
#include "isp_external.h"
#define DMA_VDEV_NAME DRIVER_NAME "_dmapath"
#define DMARX0_VDEV_NAME DRIVER_NAME "_rawrd0_m"
@@ -39,6 +40,12 @@ struct rkisp_dmarx_frame {
u32 id;
};
struct rkisp_rx_buf_pool {
struct rkisp_buffer buf;
struct rkisp_rx_buf *dbufs;
void *mem_priv;
};
/*
* struct rkisp_dmarx_device
* trigger: read back mode

View File

@@ -4,7 +4,6 @@
#ifndef _RKISP_EXTERNAL_H
#define _RKISP_EXTERNAL_H
#define RKISP_VICAP_CMD_MODE \
_IOWR('V', BASE_VIDIOC_PRIVATE + 0, struct rkisp_vicap_mode)
@@ -14,7 +13,7 @@
#define RKISP_VICAP_CMD_RX_BUFFER_FREE \
_IOW('V', BASE_VIDIOC_PRIVATE + 2, struct rkisp_rx_buf)
#define RKISP_VICAP_BUF_CNT 1
#define RKISP_VICAP_BUF_CNT 3
#define RKISP_VICAP_BUF_CNT_MAX 8
#define RKISP_RX_BUF_POOL_MAX (RKISP_VICAP_BUF_CNT_MAX * 3)
@@ -23,9 +22,15 @@ struct rkisp_vicap_input {
u8 index;
};
enum rkisp_vicap_link {
RKISP_VICAP_ONLINE,
RKISP_VICAP_RDBK_AIQ,
RKISP_VICAP_RDBK_AUTO,
};
struct rkisp_vicap_mode {
char *name;
bool is_rdbk;
enum rkisp_vicap_link rdbk_mode;
struct rkisp_vicap_input input;
};
@@ -36,21 +41,20 @@ enum rx_buf_type {
BUF_LONG,
};
struct rkisp_rx_buf_pool {
struct rkisp_rx_buf *dbufs;
void *mem_priv;
dma_addr_t dma;
void *vaddr;
};
struct rkisp_rx_buf {
struct list_head list;
struct dma_buf *dbuf;
dma_addr_t dma;
u64 timestamp;
u32 sequence;
u32 type;
u32 runtime_us;
bool is_init;
bool is_first;
bool is_resmem;
bool is_switch;
};
#endif

View File

@@ -764,6 +764,8 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
goto end;
if (hw->monitor.state & ISP_MIPI_ERROR && hw->monitor.is_en)
goto end;
if (!IS_HDR_RDBK(dev->rd_mode))
goto end;
for (i = 0; i < hw->dev_num; i++) {
isp = hw->isp[i];
@@ -791,6 +793,7 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
isp->dmarx_dev.cur_frame.sof_timestamp = t.sof_timestamp;
isp->dmarx_dev.cur_frame.timestamp = t.frame_timestamp;
isp->isp_sdev.frm_timestamp = t.sof_timestamp;
atomic_set(&isp->isp_sdev.frm_sync_seq, t.frame_id + 1);
mode = t.mode;
times = t.times;
hw->cur_dev_id = id;
@@ -814,9 +817,6 @@ int rkisp_rdbk_trigger_event(struct rkisp_device *dev, u32 cmd, void *arg)
unsigned long lock_flags = 0;
int val, ret = 0;
if (dev->dmarx_dev.trigger != T_MANUAL)
return 0;
spin_lock_irqsave(&dev->rdbk_lock, lock_flags);
switch (cmd) {
case T_CMD_QUEUE:
@@ -906,10 +906,10 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq)
/* FALLTHROUGH */
}
rkisp2_rawrd_isr(val, dev);
end:
dev->irq_ends = 0;
if (dev->dmarx_dev.trigger == T_MANUAL)
tasklet_schedule(&dev->rdbk_tasklet);
tasklet_schedule(&dev->rdbk_tasklet);
}
static void rkisp_set_state(u32 *state, u32 val)
@@ -2762,13 +2762,42 @@ static void rkisp_rx_buf_free(struct rkisp_device *dev, struct rkisp_rx_buf *dbu
}
}
static int rkisp_rx_buf_update(struct rkisp_device *dev,
struct rkisp_rx_buf *dbufs)
static void rkisp_rx_qbuf_online(struct rkisp_stream *stream,
struct rkisp_rx_buf_pool *pool)
{
struct rkisp_device *dev = stream->ispdev;
u32 val = pool->buf.buff_addr[RKISP_PLANE_Y];
rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false);
if (dev->hw_dev->is_unite) {
val += (stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL) *
stream->out_isp_fmt.bpp[0] / 8;
rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false);
}
}
static void rkisp_rx_qbuf_rdbk(struct rkisp_stream *stream,
struct rkisp_rx_buf_pool *pool)
{
unsigned long lock_flags = 0;
struct rkisp_buffer *ispbuf = &pool->buf;
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
if (list_empty(&stream->buf_queue) && !stream->curr_buf) {
stream->curr_buf = ispbuf;
stream->ops->update_mi(stream);
} else {
list_add_tail(&ispbuf->queue, &stream->buf_queue);
}
spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
}
static int rkisp_rx_qbuf(struct rkisp_device *dev,
struct rkisp_rx_buf *dbufs)
{
struct rkisp_stream *stream;
struct rkisp_rx_buf_pool *pool;
int i;
u32 val;
for (i = 0; i < RKISP_RX_BUF_POOL_MAX; i++) {
pool = &dev->pv_pool[i];
@@ -2788,17 +2817,21 @@ static int rkisp_rx_buf_update(struct rkisp_device *dev,
case BUF_LONG:
default:
stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD1];
}
}
val = pool->dma;
rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false);
if (dev->hw_dev->is_unite) {
val += (stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL) *
stream->out_isp_fmt.bpp[0] / 8;
rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false);
}
v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
"%s dma:0x%x vaddr:%p", __func__, (u32)pool->dma, pool->vaddr);
"%s rd_mode:%d dma:0x%x vaddr:%p",
__func__, dev->rd_mode,
pool->buf.buff_addr[RKISP_PLANE_Y],
pool->buf.vaddr[RKISP_PLANE_Y]);
if (!IS_HDR_RDBK(dev->rd_mode)) {
rkisp_rx_qbuf_online(stream, pool);
} else {
pool->buf.vb.vb2_buf.timestamp = dbufs->timestamp;
pool->buf.vb.sequence = dbufs->sequence;
rkisp_rx_qbuf_rdbk(stream, pool);
}
return 0;
}
@@ -2829,9 +2862,9 @@ static int rkisp_rx_buf_pool_init(struct rkisp_device *dev,
struct rkisp_stream *stream;
struct rkisp_rx_buf_pool *pool;
struct sg_table *sg_tbl;
dma_addr_t dma;
int i, ret;
void *mem;
u32 val;
void *mem, *vaddr = NULL;
for (i = 0; i < RKISP_RX_BUF_POOL_MAX; i++) {
pool = &dev->pv_pool[i];
@@ -2843,6 +2876,10 @@ static int rkisp_rx_buf_pool_init(struct rkisp_device *dev,
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
"%s type:0x%x dbufs[%d]:%p", __func__, dbufs->type, i, dbufs);
if (dbufs->is_resmem) {
dma = dbufs->dma;
goto end;
}
mem = g_ops->attach_dmabuf(dev->hw_dev->dev, dbufs->dbuf,
dbufs->dbuf->size, DMA_BIDIRECTIONAL);
if (IS_ERR(mem)) {
@@ -2855,13 +2892,17 @@ static int rkisp_rx_buf_pool_init(struct rkisp_device *dev,
goto err;
if (dev->hw_dev->is_dma_sg_ops) {
sg_tbl = (struct sg_table *)g_ops->cookie(mem);
pool->dma = sg_dma_address(sg_tbl->sgl);
dma = sg_dma_address(sg_tbl->sgl);
} else {
pool->dma = *((dma_addr_t *)g_ops->cookie(mem));
dma = *((dma_addr_t *)g_ops->cookie(mem));
}
get_dma_buf(dbufs->dbuf);
pool->vaddr = g_ops->vaddr(mem);
vaddr = g_ops->vaddr(mem);
end:
dbufs->is_init = true;
pool->buf.other = dbufs;
pool->buf.buff_addr[RKISP_PLANE_Y] = dma;
pool->buf.vaddr[RKISP_PLANE_Y] = vaddr;
switch (dbufs->type) {
case BUF_SHORT:
@@ -2873,21 +2914,13 @@ static int rkisp_rx_buf_pool_init(struct rkisp_device *dev,
case BUF_LONG:
default:
stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD1];
}
if (dbufs->is_first) {
stream->ops->config_mi(stream);
dbufs->is_first = false;
}
val = pool->dma;
rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false);
if (dev->hw_dev->is_unite) {
val += (stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL) *
stream->out_isp_fmt.bpp[0] / 8;
rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false);
}
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
"%s dma:0x%x vaddr:%p", __func__, (u32)pool->dma, pool->vaddr);
"%s dma:0x%x vaddr:%p", __func__, (u32)dma, vaddr);
return 0;
err:
rkisp_rx_buf_pool_free(dev);
@@ -2907,10 +2940,8 @@ static int rkisp_sd_s_rx_buffer(struct v4l2_subdev *sd,
dbufs = buf;
if (!dbufs->is_init)
ret = rkisp_rx_buf_pool_init(dev, dbufs);
else
ret = rkisp_rx_buf_update(dev, dbufs);
/* TODO qbuf/debuf for more buffer */
if (!ret)
ret = rkisp_rx_qbuf(dev, dbufs);
return ret;
}
@@ -3069,21 +3100,22 @@ static int rkisp_subdev_link_setup(struct media_entity *entity,
if (stream)
stream->linked = flags & MEDIA_LNK_FL_ENABLED;
if (dev->isp_inp & rawrd)
if (dev->isp_inp & rawrd) {
dev->dmarx_dev.trigger = T_MANUAL;
else
dev->is_rdbk_auto = false;
} else {
dev->dmarx_dev.trigger = T_AUTO;
}
if (dev->isp_inp & INP_CIF) {
struct v4l2_subdev *remote = get_remote_sensor(sd);
struct rkisp_vicap_mode mode;
memset(&mode, 0, sizeof(mode));
mode.name = dev->name;
mode.is_rdbk = !!(dev->isp_inp & rawrd);
mode.rdbk_mode = !!(dev->isp_inp & rawrd);
/* read back mode only */
if (dev->isp_ver < ISP_V30 || !dev->hw_dev->is_single)
mode.is_rdbk = true;
mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
v4l2_subdev_call(remote, core, ioctl,
RKISP_VICAP_CMD_MODE, &mode);
dev->vicap_in = mode.input;