media: rockchip: aiisp: modify for airms algo

Signed-off-by: Hu Kejun <william.hu@rock-chips.com>
Change-Id: I68bf45d2d83cbd45ce2f955050ece955931ed6d1
This commit is contained in:
Hu Kejun
2025-04-15 11:06:17 +08:00
committed by Tao Huang
parent 38afd05b0d
commit fccdeb1227
5 changed files with 313 additions and 33 deletions

View File

@@ -102,6 +102,8 @@ static int mi_chns_tab[2][7] = {
{15, 1, 1, 1, 1, 1, 1}
};
static int rkaiisp_free_airms_pool(struct rkaiisp_device *aidev);
static void rkaiisp_update_regs(struct rkaiisp_device *aidev, u32 start, u32 end)
{
struct rkaiisp_hw_dev *hw_dev = aidev->hw_dev;
@@ -190,6 +192,40 @@ static void rkaiisp_dump_list_reg(struct rkaiisp_device *aidev)
rkaiisp_dumpreg(aidev, AIISP_MI_WR_CTRL, AIISP_MI_CHN0_WR_STRIDE);
}
static int rkaiisp_buf_get_fd(struct rkaiisp_device *aidev,
struct rkaiisp_dummy_buffer *buf, bool try_fd)
{
const struct vb2_mem_ops *g_ops = aidev->hw_dev->mem_ops;
bool new_dbuf = false;
if (!buf || !buf->mem_priv)
return -EINVAL;
if (try_fd) {
buf->is_need_dbuf = true;
buf->is_need_dmafd = true;
}
if (buf->is_need_dbuf && !buf->dmabuf) {
buf->dmabuf = g_ops->get_dmabuf(&buf->vb, buf->mem_priv, O_RDWR);
new_dbuf = true;
}
if (buf->is_need_dmafd) {
buf->dma_fd = dma_buf_fd(buf->dmabuf, O_CLOEXEC);
if (buf->dma_fd < 0) {
if (new_dbuf) {
dma_buf_put(buf->dmabuf);
buf->dmabuf = NULL;
buf->is_need_dbuf = false;
}
buf->is_need_dmafd = false;
return -EINVAL;
}
get_dma_buf(buf->dmabuf);
}
return 0;
}
#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
static void rkaiisp_init_dummy_vb2(struct rkaiisp_device *dev,
struct rkaiisp_dummy_buffer *buf)
@@ -231,8 +267,16 @@ static int rkaiisp_allow_buffer(struct rkaiisp_device *aidev,
sg_tbl = (struct sg_table *)mem_ops->cookie(&buf->vb, mem_priv);
buf->dma_addr = sg_dma_address(sg_tbl->sgl);
mem_ops->prepare(mem_priv);
buf->vaddr = mem_ops->vaddr(&buf->vb, mem_priv);
if (buf->is_need_vaddr)
buf->vaddr = mem_ops->vaddr(&buf->vb, mem_priv);
ret = rkaiisp_buf_get_fd(aidev, buf, false);
if (ret < 0) {
mem_ops->put(buf->mem_priv);
buf->mem_priv = NULL;
buf->vaddr = NULL;
buf->size = 0;
goto err;
}
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"%s buf:%pad size:%d\n", __func__,
&buf->dma_addr, buf->size);
@@ -271,8 +315,8 @@ static int rkaiisp_allow_buffer(struct rkaiisp_device *aidev,
sg_tbl = (struct sg_table *)mem_ops->cookie(mem_priv);
buf->dma_addr = sg_dma_address(sg_tbl->sgl);
mem_ops->prepare(mem_priv);
buf->vaddr = mem_ops->vaddr(mem_priv);
if (buf->is_need_vaddr)
buf->vaddr = mem_ops->vaddr(mem_priv);
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"%s buf:%pad size:%d\n", __func__,
&buf->dma_addr, buf->size);
@@ -294,10 +338,15 @@ static void rkaiisp_free_buffer(struct rkaiisp_device *aidev,
"%s buf:%pad size:%d\n", __func__,
&buf->dma_addr, buf->size);
if (buf->dmabuf)
dma_buf_put(buf->dmabuf);
mem_ops->put(buf->mem_priv);
buf->size = 0;
buf->vaddr = NULL;
buf->dmabuf = NULL;
buf->mem_priv = NULL;
buf->is_need_dbuf = false;
buf->is_need_dmafd = false;
}
}
@@ -327,6 +376,9 @@ static int rkaiisp_free_pool(struct rkaiisp_device *aidev)
struct rkaiisp_ispbuf_info *ispbuf = &aidev->ispbuf;
int i;
if (aidev->exealgo == AIRMS)
return rkaiisp_free_airms_pool(aidev);
if (!aidev->init_buf)
return 0;
@@ -391,6 +443,9 @@ static void rkaiisp_calc_outbuf_size(struct rkaiisp_device *aidev, u32 raw_hgt,
{
int i;
if (aidev->model_mode == REMOSAIC_MODE)
return;
if (aidev->model_mode == SINGLEX2_MODE) {
for (i = 0; i < RKAIISP_PYRAMID_LAYER_NUM; i++) {
if (i == 0) {
@@ -485,6 +540,12 @@ static int rkaiisp_init_pool(struct rkaiisp_device *aidev, struct rkaiisp_ispbuf
stride = ((ispbuf->iir_width + 1) / 2 * 15 * 11 + 7) >> 3;
aidev->temp_buf[0].size = stride * (ispbuf->iir_height + 1) / 2;
aidev->temp_buf[1].size = aidev->temp_buf[0].size;
aidev->temp_buf[0].is_need_vaddr = false;
aidev->temp_buf[0].is_need_dbuf = false;
aidev->temp_buf[0].is_need_dmafd = false;
aidev->temp_buf[1].is_need_vaddr = false;
aidev->temp_buf[1].is_need_dbuf = false;
aidev->temp_buf[1].is_need_dmafd = false;
ret = rkaiisp_allow_buffer(aidev, &aidev->temp_buf[0]);
ret |= rkaiisp_allow_buffer(aidev, &aidev->temp_buf[1]);
if (ret)
@@ -498,11 +559,88 @@ static int rkaiisp_init_pool(struct rkaiisp_device *aidev, struct rkaiisp_ispbuf
return ret;
}
int rkaiisp_queue_ispbuf(struct rkaiisp_device *aidev, struct rkisp_aiisp_st *idxbuf)
static int rkaiisp_free_airms_pool(struct rkaiisp_device *aidev)
{
int i;
if (!aidev->init_buf)
return 0;
for (i = 0; i < aidev->rmsbuf.inbuf_num; i++)
rkaiisp_free_buffer(aidev, &aidev->rms_inbuf[i]);
for (i = 0; i < aidev->rmsbuf.outbuf_num; i++)
rkaiisp_free_buffer(aidev, &aidev->rms_outbuf[i]);
rkaiisp_free_buffer(aidev, &aidev->sigma_buf);
rkaiisp_free_buffer(aidev, &aidev->narmap_buf);
aidev->init_buf = false;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"free buf poll\n");
return 0;
}
static int rkaiisp_init_airms_pool(struct rkaiisp_device *aidev, struct rkaiisp_rmsbuf_info *rmsbuf)
{
int i, ret = 0;
u32 size;
size = rmsbuf->image_width * rmsbuf->image_height * 2;
rmsbuf->inbuf_num = RKAIISP_MIN(rmsbuf->inbuf_num, RKAIISP_AIRMS_BUF_MAXCNT);
for (i = 0; i < rmsbuf->inbuf_num; i++) {
aidev->rms_inbuf[i].size = size;
aidev->rms_inbuf[i].is_need_vaddr = false;
aidev->rms_inbuf[i].is_need_dbuf = true;
aidev->rms_inbuf[i].is_need_dmafd = true;
ret = rkaiisp_allow_buffer(aidev, &aidev->rms_inbuf[i]);
if (ret) {
rkaiisp_free_airms_pool(aidev);
v4l2_err(&aidev->v4l2_dev, "alloc buf failed: %d\n", ret);
return -EINVAL;
}
rmsbuf->inbuf_fd[i] = aidev->rms_inbuf[i].dma_fd;
}
rmsbuf->outbuf_num = RKAIISP_MIN(rmsbuf->outbuf_num, RKAIISP_AIRMS_BUF_MAXCNT);
for (i = 0; i < rmsbuf->outbuf_num; i++) {
aidev->rms_outbuf[i].size = size;
aidev->rms_outbuf[i].is_need_vaddr = false;
aidev->rms_outbuf[i].is_need_dbuf = true;
aidev->rms_outbuf[i].is_need_dmafd = true;
ret = rkaiisp_allow_buffer(aidev, &aidev->rms_outbuf[i]);
if (ret) {
rkaiisp_free_airms_pool(aidev);
v4l2_err(&aidev->v4l2_dev, "alloc buf failed: %d\n", ret);
return -EINVAL;
}
rmsbuf->outbuf_fd[i] = aidev->rms_outbuf[i].dma_fd;
}
aidev->sigma_buf.size = rmsbuf->sigma_width * rmsbuf->sigma_height;
aidev->sigma_buf.is_need_vaddr = false;
aidev->sigma_buf.is_need_dbuf = false;
aidev->sigma_buf.is_need_dmafd = false;
rkaiisp_allow_buffer(aidev, &aidev->sigma_buf);
aidev->narmap_buf.size = rmsbuf->narmap_width * rmsbuf->narmap_height;
aidev->narmap_buf.is_need_vaddr = false;
aidev->narmap_buf.is_need_dbuf = false;
aidev->narmap_buf.is_need_dmafd = false;
rkaiisp_allow_buffer(aidev, &aidev->narmap_buf);
aidev->rmsbuf = *rmsbuf;
aidev->init_buf = true;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev, "init buf poll\n");
return ret;
}
int rkaiisp_queue_ispbuf(struct rkaiisp_device *aidev, union rkaiisp_queue_buf *idxbuf)
{
struct kfifo *fifo = &aidev->idxbuf_kfifo;
struct rkaiisp_hw_dev *hw_dev = aidev->hw_dev;
unsigned long flags = 0;
int sequence = 0;
int ret = 0;
spin_lock_irqsave(&hw_dev->hw_lock, flags);
@@ -514,12 +652,17 @@ int rkaiisp_queue_ispbuf(struct rkaiisp_device *aidev, struct rkisp_aiisp_st *id
}
if (!kfifo_is_full(fifo))
kfifo_in(fifo, idxbuf, sizeof(struct rkisp_aiisp_st));
kfifo_in(fifo, idxbuf, sizeof(union rkaiisp_queue_buf));
else
v4l2_err(&aidev->v4l2_dev, "fifo is full\n");
if (aidev->exealgo == AIBNR)
sequence = idxbuf->aibnr_st.sequence;
else if (aidev->exealgo == AIRMS)
sequence = idxbuf->airms_st.sequence;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"idxbuf fifo in: %d\n", idxbuf->sequence);
"idxbuf fifo in: %d\n", sequence);
if (hw_dev->is_idle) {
hw_dev->cur_dev_id = aidev->dev_id;
@@ -854,13 +997,15 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
struct rkaiisp_model_cfg *model_cfg, u32 run_idx)
{
struct rkaiisp_ispbuf_info *ispbuf = &aidev->ispbuf;
struct rkaiisp_rmsbuf_info *rmsbuf = &aidev->rmsbuf;
struct rkaiisp_dummy_buffer *vpsl_buf;
dma_addr_t dma_addr;
u32 width, height;
u32 sig_width = 0;
int buffer_index;
int i;
vpsl_buf = &aidev->vpslbuf[aidev->curr_idxbuf.vpsl_index];
vpsl_buf = &aidev->vpslbuf[aidev->curr_idxbuf.aibnr_st.vpsl_index];
for (i = 0; i < 7; i++) {
if (model_cfg->sw_mi_chn_en[i] == 0)
continue;
@@ -871,7 +1016,7 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
width = CEIL_BY(width * 9 / 4, 16);
width = width >> 1;
height = ispbuf->iir_height;
dma_addr = aidev->iirbuf[aidev->curr_idxbuf.iir_index].dma_addr;
dma_addr = aidev->iirbuf[aidev->curr_idxbuf.aibnr_st.iir_index].dma_addr;
break;
case VPSL_YRAW_CHN0:
width = ispbuf->raw_width[0];
@@ -936,7 +1081,8 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
case ISP_AIPRE_NARMAP:
width = ispbuf->narmap_width;
height = ispbuf->narmap_height;
dma_addr = aidev->aiprebuf[aidev->curr_idxbuf.aipre_gain_index].dma_addr;
buffer_index = aidev->curr_idxbuf.aibnr_st.aipre_gain_index;
dma_addr = aidev->aiprebuf[buffer_index].dma_addr;
break;
case AIISP_LAST_OUT:
if (aidev->model_mode == COMBO_MODE) {
@@ -948,6 +1094,22 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
}
dma_addr = aidev->temp_buf[aidev->outbuf_idx].dma_addr;
break;
case VICAP_BAYER_RAW:
width = rmsbuf->image_width;
height = rmsbuf->image_height;
dma_addr = aidev->rms_inbuf[aidev->curr_idxbuf.airms_st.inbuf_idx].dma_addr;
break;
case ALLZERO_SIGMA:
width = rmsbuf->sigma_width;
height = rmsbuf->sigma_height;
dma_addr = aidev->sigma_buf.dma_addr;
sig_width = width;
break;
case ALLZERO_NARMAP:
width = rmsbuf->narmap_width;
height = rmsbuf->narmap_height;
dma_addr = aidev->narmap_buf.dma_addr;
break;
default:
width = 0;
height = 0;
@@ -982,10 +1144,17 @@ static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
u32 iir_stride;
u32 sig_width;
dma_addr_t dma_addr;
int buffer_index;
int sequence = 0;
if (aidev->exealgo == AIBNR)
sequence = aidev->curr_idxbuf.aibnr_st.sequence;
else if (aidev->exealgo == AIRMS)
sequence = aidev->curr_idxbuf.airms_st.sequence;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"run frame id: %d, run_idx: %d\n",
aidev->curr_idxbuf.sequence, run_idx);
sequence, run_idx);
cur_params = (struct rkaiisp_params *)aidev->cur_params->vaddr[0];
model_cfg = &cur_params->model_cfg[run_idx];
@@ -993,7 +1162,15 @@ static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
lastlv = model_cfg->sw_aiisp_level_num - 1;
lv_mode = model_cfg->sw_aiisp_lv_mode[lastlv];
out_chns = channels_lut[model_cfg->sw_aiisp_mode][lv_mode];
if (aidev->model_mode == SINGLEX2_MODE) {
if (aidev->model_mode == REMOSAIC_MODE) {
sig_width = rkaiisp_config_rdchannel(aidev, model_cfg, run_idx);
dma_addr = aidev->rms_outbuf[aidev->curr_idxbuf.airms_st.outbuf_idx].dma_addr;
rkaiisp_write(aidev, AIISP_MI_CHN0_WR_BASE, dma_addr, false);
rkaiisp_gen_slice_param(aidev, model_cfg, sig_width);
rkaiisp_determine_size(aidev, model_cfg);
} else if (aidev->model_mode == SINGLEX2_MODE) {
if (run_idx == 0) {
sig_width = rkaiisp_config_rdchannel(aidev, model_cfg, run_idx);
@@ -1017,7 +1194,8 @@ static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
} else {
sig_width = rkaiisp_config_rdchannel(aidev, model_cfg, run_idx);
dma_addr = aidev->aiispbuf[aidev->curr_idxbuf.aiisp_index].dma_addr;
buffer_index = aidev->curr_idxbuf.aibnr_st.aiisp_index;
dma_addr = aidev->aiispbuf[buffer_index].dma_addr;
rkaiisp_write(aidev, AIISP_MI_CHN0_WR_BASE, dma_addr, false);
rkaiisp_gen_slice_param(aidev, model_cfg, sig_width);
@@ -1055,7 +1233,8 @@ static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
} else {
rkaiisp_config_rdchannel(aidev, model_cfg, run_idx);
dma_addr = aidev->aiispbuf[aidev->curr_idxbuf.aiisp_index].dma_addr;
buffer_index = aidev->curr_idxbuf.aibnr_st.aiisp_index;
dma_addr = aidev->aiispbuf[buffer_index].dma_addr;
rkaiisp_write(aidev, AIISP_MI_CHN0_WR_BASE, dma_addr, false);
rkaiisp_gen_slice_param(aidev, model_cfg, ispbuf->sig_width[0]);
@@ -1115,8 +1294,9 @@ static int rkaiisp_update_buf(struct rkaiisp_device *aidev)
{
struct kfifo *fifo = &aidev->idxbuf_kfifo;
struct rkaiisp_hw_dev *hw_dev = aidev->hw_dev;
struct rkisp_aiisp_st idxbuf = {0};
union rkaiisp_queue_buf idxbuf = {0};
unsigned long flags = 0;
int sequence = 0;
int ret = 0;
spin_lock_irqsave(&hw_dev->hw_lock, flags);
@@ -1127,8 +1307,13 @@ static int rkaiisp_update_buf(struct rkaiisp_device *aidev)
} else {
ret = 0;
aidev->curr_idxbuf = idxbuf;
if (aidev->exealgo == AIBNR)
sequence = aidev->curr_idxbuf.aibnr_st.sequence;
else if (aidev->exealgo == AIRMS)
sequence = aidev->curr_idxbuf.airms_st.sequence;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"idxbuf fifo out: %d\n", idxbuf.sequence);
"idxbuf fifo out: %d\n", sequence);
}
spin_unlock_irqrestore(&hw_dev->hw_lock, flags);
@@ -1214,10 +1399,16 @@ static void rkaiisp_get_new_iqparam(struct rkaiisp_device *aidev)
void rkaiisp_trigger(struct rkaiisp_device *aidev)
{
struct rkaiisp_ispbuf_info *ispbuf = &aidev->ispbuf;
int sequence = 0;
if (aidev->exealgo == AIBNR)
sequence = aidev->curr_idxbuf.aibnr_st.sequence;
else if (aidev->exealgo == AIRMS)
sequence = aidev->curr_idxbuf.airms_st.sequence;
if (!rkaiisp_update_buf(aidev)) {
aidev->run_idx = 0;
aidev->frame_id = aidev->curr_idxbuf.sequence;
aidev->frame_id = sequence;
aidev->pre_frm_st = aidev->frm_st;
aidev->frm_st = ktime_get_ns();
rkaiisp_get_new_iqparam(aidev);
@@ -1228,18 +1419,24 @@ void rkaiisp_trigger(struct rkaiisp_device *aidev)
}
}
static void rkaiisp_event_queue(struct rkaiisp_device *aidev, struct rkisp_aiisp_st *idxbuf)
static void rkaiisp_event_queue(struct rkaiisp_device *aidev, union rkaiisp_queue_buf *idxbuf)
{
struct rkisp_aiisp_st *rundone;
union rkaiisp_queue_buf *rundone;
struct v4l2_event event = {0};
int sequence = 0;
if (aidev->exealgo == AIBNR)
sequence = idxbuf->aibnr_st.sequence;
else if (aidev->exealgo == AIRMS)
sequence = idxbuf->airms_st.sequence;
if (aidev->subdev.is_subs_evt && aidev->exemode != BOTHEVENT_IN_KERNEL) {
event.type = RKAIISP_V4L2_EVENT_AIISP_DONE;
rundone = (struct rkisp_aiisp_st *)&event.u.data[0];
rundone = (union rkaiisp_queue_buf *)&event.u.data[0];
*rundone = *idxbuf;
v4l2_event_queue(aidev->subdev.sd.devnode, &event);
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"aiisp done: %d\n", rundone->sequence);
"aiisp done: %d\n", sequence);
} else {
// call isp api to inform
}
@@ -1250,13 +1447,13 @@ int rkaiisp_get_idxbuf_len(struct rkaiisp_device *aidev)
struct kfifo *fifo = &aidev->idxbuf_kfifo;
int len = 0;
len = kfifo_len(fifo) / sizeof(struct rkisp_aiisp_st);
len = kfifo_len(fifo) / sizeof(union rkaiisp_queue_buf);
return len;
}
enum rkaiisp_irqhdl_ret rkaiisp_irq_hdl(struct rkaiisp_device *aidev, u32 mi_mis)
{
struct rkisp_aiisp_st *idxbuf = NULL;
union rkaiisp_queue_buf *idxbuf = NULL;
u64 frm_hdntim = 0;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
@@ -1266,11 +1463,13 @@ enum rkaiisp_irqhdl_ret rkaiisp_irq_hdl(struct rkaiisp_device *aidev, u32 mi_mis
if (mi_mis & AIISP_MI_ISR_BUSERR) {
v4l2_err(&aidev->v4l2_dev, "buserr 0x%x\n", mi_mis);
rkaiisp_write(aidev, AIISP_MI_ICR, AIISP_MI_ISR_BUSERR, true);
aidev->isr_buserr_cnt++;
}
if (!(mi_mis & AIISP_MI_ISR_WREND))
return NOT_WREND;
rkaiisp_write(aidev, AIISP_MI_ICR, AIISP_MI_ISR_WREND, true);
aidev->isr_wrend_cnt++;
if (aidev->run_idx < aidev->model_runcnt - 1) {
aidev->run_idx++;
@@ -1427,6 +1626,7 @@ static long rkaiisp_ioctl_default(struct file *file, void *fh,
if ((param_info->para_size > 0) &&
(param_info->max_runcnt > 0) &&
(param_info->max_runcnt <= RKAIISP_MAX_RUNCNT)) {
aidev->exealgo = param_info->exealgo;
aidev->exemode = param_info->exemode;
aidev->para_size = param_info->para_size;
aidev->max_runcnt = param_info->max_runcnt;
@@ -1446,6 +1646,9 @@ static long rkaiisp_ioctl_default(struct file *file, void *fh,
case RKAIISP_CMD_QUEUE_BUF:
ret = rkaiisp_queue_ispbuf(aidev, arg);
break;
case RKAIISP_CMD_INIT_AIRMS_BUFPOOL:
ret = rkaiisp_init_airms_pool(aidev, arg);
break;
default:
ret = -EINVAL;
}
@@ -1584,6 +1787,8 @@ rkaiisp_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
atomic_inc(&hw_dev->refcnt);
aidev->frm_oversdtim_cnt = 0;
aidev->isr_buserr_cnt = 0;
aidev->isr_wrend_cnt = 0;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"start streaming %d\n", aidev->streamon);
@@ -1685,7 +1890,7 @@ int rkaiisp_register_vdev(struct rkaiisp_device *aidev, struct v4l2_device *v4l2
aidev->mem_ops = aidev->hw_dev->mem_ops;
ret = kfifo_alloc(&aidev->idxbuf_kfifo,
16 * sizeof(struct rkisp_aiisp_st), GFP_KERNEL);
16 * sizeof(union rkaiisp_queue_buf), GFP_KERNEL);
if (ret < 0) {
v4l2_err(v4l2_dev, "Failed to alloc kfifo %d", ret);
return ret;

View File

@@ -35,6 +35,8 @@
#define RKAIISP_DEFAULT_PARASIZE (16 * 1024)
#define RKAIISP_SW_REG_SIZE 0x3000
#define RKAIISP_SW_MAX_SIZE (RKAIISP_SW_REG_SIZE * 2)
#define RKAIISP_AIRMS_BUF_MAXCNT 8
#define RKAIISP_MIN(a, b) ((a) < (b) ? (a) : (b))
enum rkaiisp_irqhdl_ret {
NOT_WREND = (0 << 0),
@@ -71,6 +73,9 @@ struct rkaiisp_dummy_buffer {
void *vaddr;
u32 size;
void *mem_priv;
bool is_need_vaddr;
bool is_need_dbuf;
bool is_need_dmafd;
};
struct rkaiisp_buffer_size {
@@ -113,8 +118,14 @@ struct rkaiisp_device {
struct rkaiisp_dummy_buffer temp_buf[RKAIISP_TMP_BUF_CNT];
u32 outbuf_idx;
struct rkaiisp_rmsbuf_info rmsbuf;
struct rkaiisp_dummy_buffer rms_inbuf[RKAIISP_AIRMS_BUF_MAXCNT];
struct rkaiisp_dummy_buffer rms_outbuf[RKAIISP_AIRMS_BUF_MAXCNT];
struct rkaiisp_dummy_buffer sigma_buf;
struct rkaiisp_dummy_buffer narmap_buf;
struct kfifo idxbuf_kfifo;
struct rkisp_aiisp_st curr_idxbuf;
union rkaiisp_queue_buf curr_idxbuf;
struct rkaiisp_vdev_node vnode;
struct list_head params;
@@ -123,6 +134,7 @@ struct rkaiisp_device {
struct rkaiisp_buffer_size outbuf_size[RKAIISP_MAX_RUNCNT];
struct rkaiisp_buffer_size chn_size[RKAIISP_MAX_CHANNEL];
enum rkaiisp_exealgo exealgo;
enum rkaiisp_exemode exemode;
enum rkaiisp_model_mode model_mode;
enum rkaiisp_hwstate hwstate;
@@ -137,6 +149,8 @@ struct rkaiisp_device {
u64 frm_ed;
u32 frm_interval;
u32 frm_oversdtim_cnt;
u32 isr_buserr_cnt;
u32 isr_wrend_cnt;
bool streamon;
bool showreg;
@@ -178,7 +192,7 @@ static inline u32 rkaiisp_read(struct rkaiisp_device *aidev, u32 reg, bool is_di
}
extern struct platform_driver rkaiisp_plat_drv;
int rkaiisp_queue_ispbuf(struct rkaiisp_device *aidev, struct rkisp_aiisp_st *idxbuf);
int rkaiisp_queue_ispbuf(struct rkaiisp_device *aidev, union rkaiisp_queue_buf *idxbuf);
void rkaiisp_update_list_reg(struct rkaiisp_device *aidev);
void rkaiisp_trigger(struct rkaiisp_device *aidev);
int rkaiisp_get_idxbuf_len(struct rkaiisp_device *aidev);

View File

@@ -120,6 +120,7 @@ int rkaiisp_ispidx_queue(int dev_id, struct rkisp_aiisp_st *idxbuf)
{
struct rkaiisp_hw_dev *hw_dev = rkaiisp_hwdev;
struct rkaiisp_device *aidev = NULL;
union rkaiisp_queue_buf queue_buf;
int i;
if (!hw_dev) {
@@ -146,7 +147,8 @@ int rkaiisp_ispidx_queue(int dev_id, struct rkisp_aiisp_st *idxbuf)
return -EINVAL;
}
return rkaiisp_queue_ispbuf(aidev, idxbuf);
queue_buf.aibnr_st = *idxbuf;
return rkaiisp_queue_ispbuf(aidev, &queue_buf);
}
EXPORT_SYMBOL(rkaiisp_ispidx_queue);

View File

@@ -16,14 +16,27 @@ static int rkaiisp_show(struct seq_file *p, void *v)
struct rkaiisp_device *aidev = p->private;
struct rkaiisp_hw_dev *hw_dev = aidev->hw_dev;
unsigned long flags = 0;
u32 image_width;
u32 image_height;
u32 frm_rate;
int idx_buf_len;
int i, idx_buf_len;
seq_printf(p, "%-18s Version:v%02x.%02x.%02x\n", aidev->v4l2_dev.name,
RKAIISP_DRIVER_VERSION >> 16,
(RKAIISP_DRIVER_VERSION & 0xff00) >> 8,
RKAIISP_DRIVER_VERSION & 0x00ff);
for (i = 0; i < hw_dev->num_clks; i++) {
seq_printf(p, "%-18s %ld\n",
hw_dev->match_data->clks[i],
clk_get_rate(hw_dev->clks[i]));
}
seq_printf(p, "%-18s wrend cnt:%d buserr cnt:%d\n",
"interrupt",
aidev->isr_wrend_cnt,
aidev->isr_buserr_cnt);
seq_printf(p, "%-18s %d\n", "dev id", aidev->dev_id);
seq_printf(p, "%-18s %d\n", "frame id", aidev->frame_id);
seq_printf(p, "%-18s %d\n", "run idx", aidev->run_idx);
@@ -31,13 +44,21 @@ static int rkaiisp_show(struct seq_file *p, void *v)
seq_printf(p, "%-18s %d\n", "frm rate", frm_rate / 1000 / 1000);
seq_printf(p, "%-18s %d\n", "frm hdltime", aidev->frm_interval / 1000 / 1000);
seq_printf(p, "%-18s %d\n", "frm_oversdtim_cnt", aidev->frm_oversdtim_cnt);
seq_printf(p, "%-18s %d\n", "execute algo", aidev->exealgo);
seq_printf(p, "%-18s %d\n", "model mode", aidev->model_mode);
seq_printf(p, "%-18s %d\n", "model runcnt", aidev->model_runcnt);
seq_printf(p, "%-18s %d\n", "max runcnt", aidev->max_runcnt);
seq_printf(p, "%-18s %d\n", "para size", aidev->para_size);
seq_printf(p, "%-18s %d\n", "hw state", aidev->hwstate);
seq_printf(p, "%-18s %d\n", "iir width", aidev->ispbuf.iir_width);
seq_printf(p, "%-18s %d\n", "iir height", aidev->ispbuf.iir_height);
if (aidev->exealgo == AIRMS) {
image_width = aidev->rmsbuf.image_width;
image_height = aidev->rmsbuf.image_height;
} else {
image_width = aidev->ispbuf.iir_width;
image_height = aidev->ispbuf.iir_height;
}
seq_printf(p, "%-18s %d\n", "image width", image_width);
seq_printf(p, "%-18s %d\n", "image height", image_height);
spin_lock_irqsave(&hw_dev->hw_lock, flags);
idx_buf_len = rkaiisp_get_idxbuf_len(aidev);

View File

@@ -25,7 +25,10 @@
_IO('V', BASE_VIDIOC_PRIVATE + 2)
#define RKAIISP_CMD_QUEUE_BUF \
_IOW('V', BASE_VIDIOC_PRIVATE + 3, struct rkisp_aiisp_st)
_IOW('V', BASE_VIDIOC_PRIVATE + 3, union rkaiisp_queue_buf)
#define RKAIISP_CMD_INIT_AIRMS_BUFPOOL \
_IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct rkaiisp_rmsbuf_info)
/**********************EVENT_PRIVATE***************************/
#define RKAIISP_V4L2_EVENT_AIISP_DONE (V4L2_EVENT_PRIVATE_START + 1)
@@ -44,13 +47,23 @@ enum rkaiisp_chn_src {
VPSL_SIG_CHN3,
VPSL_SIG_CHN4,
ISP_AIPRE_NARMAP,
AIISP_LAST_OUT
AIISP_LAST_OUT,
VICAP_BAYER_RAW,
ALLZERO_SIGMA,
ALLZERO_NARMAP
};
enum rkaiisp_exealgo {
AIBNR,
AIRMS,
AIYNR
};
enum rkaiisp_model_mode {
SINGLE_MODE,
COMBO_MODE,
SINGLEX2_MODE
SINGLEX2_MODE,
REMOSAIC_MODE
};
enum rkaiisp_exemode {
@@ -59,7 +72,19 @@ enum rkaiisp_exemode {
BOTHEVENT_IN_KERNEL
};
struct rkaiisp_airms_st {
int sequence;
int inbuf_idx;
int outbuf_idx;
} __attribute__ ((packed));
union rkaiisp_queue_buf {
struct rkisp_aiisp_st aibnr_st;
struct rkaiisp_airms_st airms_st;
} __attribute__ ((packed));
struct rkaiisp_param_info {
enum rkaiisp_exealgo exealgo;
enum rkaiisp_exemode exemode;
__u32 para_size;
__u32 max_runcnt;
@@ -77,6 +102,19 @@ struct rkaiisp_ispbuf_info {
__u32 narmap_height;
} __attribute__ ((packed));
struct rkaiisp_rmsbuf_info {
__u32 image_width;
__u32 image_height;
__u32 sigma_width;
__u32 sigma_height;
__u32 narmap_width;
__u32 narmap_height;
__u32 inbuf_num;
__u32 outbuf_num;
int inbuf_fd[6];
int outbuf_fd[6];
} __attribute__ ((packed));
struct rkaiisp_other_cfg {
__u16 sw_neg_noiselimit;
__u16 sw_pos_noiselimit;