media: rockchip: aiisp: modify for aiynr algo

Change-Id: If8189c7ea66ac572ad4f8ac335d7f365c24d29f7
Signed-off-by: hkj <william.hu@rock-chips.com>
This commit is contained in:
hkj
2025-05-15 17:33:54 +08:00
committed by Tao Huang
parent 77c92aee86
commit 8faaf5ea8a
5 changed files with 311 additions and 47 deletions

View File

@@ -123,7 +123,7 @@ static void rkaiisp_update_regs(struct rkaiisp_device *aidev, u32 start, u32 end
}
}
void rkaiisp_update_list_reg(struct rkaiisp_device *aidev)
static void rkaiisp_update_list_reg(struct rkaiisp_device *aidev)
{
rkaiisp_update_regs(aidev, AIISP_MI_CTRL, AIISP_MI_CTRL);
rkaiisp_update_regs(aidev, AIISP_MI_SLICE_CTRL, AIISP_MI_MANUAL_CTRL);
@@ -355,8 +355,8 @@ static void rkaiisp_detach_dmabuf(struct rkaiisp_device *aidev,
{
if (buffer->dma_fd >= 0) {
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"%s buf:%pad size:%d\n", __func__,
&buffer->dma_addr, buffer->size);
"%s dma_fd:%d, buf:%pad size:%d\n", __func__,
buffer->dma_fd, &buffer->dma_addr, buffer->size);
dma_buf_unmap_attachment(buffer->dba, buffer->sgt, DMA_BIDIRECTIONAL);
dma_buf_detach(buffer->dmabuf, buffer->dba);
dma_buf_put(buffer->dmabuf);
@@ -365,6 +365,36 @@ static void rkaiisp_detach_dmabuf(struct rkaiisp_device *aidev,
}
}
static void rkaiisp_free_aiynr_ybuf(struct rkaiisp_device *aidev)
{
struct aiisp_aiynr_ybuf_cfg *buf_cfg = &aidev->ynr_ybuf_cfg;
struct rkaiisp_dummy_buffer *ynroutbuf = &aidev->ynroutbuf[0];
int i;
for (i = 0; i < buf_cfg->buf_cnt; i++) {
if (buf_cfg->buf[i]) {
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"%s buf:%pad size:%zu dmabuf:%p\n", __func__,
&ynroutbuf[i].dma_addr, ynroutbuf[i].dmabuf->size,
buf_cfg->buf[i]);
if (ynroutbuf[i].dba) {
if (ynroutbuf[i].sgt) {
dma_buf_unmap_attachment(ynroutbuf[i].dba,
ynroutbuf[i].sgt,
DMA_BIDIRECTIONAL);
ynroutbuf[i].sgt = NULL;
}
dma_buf_detach(ynroutbuf[i].dmabuf, ynroutbuf[i].dba);
dma_buf_put(ynroutbuf[i].dmabuf);
ynroutbuf[i].dba = NULL;
}
buf_cfg->buf[i] = NULL;
}
}
buf_cfg->buf_cnt = 0;
}
static void rkaiisp_free_tempbuf(struct rkaiisp_device *aidev)
{
rkaiisp_free_buffer(aidev, &aidev->temp_buf[0]);
@@ -394,7 +424,13 @@ static int rkaiisp_free_pool(struct rkaiisp_device *aidev)
for (i = 0; i < ispbuf->bnr_buf.u.v35.aiisp.buf_cnt; i++)
rkaiisp_detach_dmabuf(aidev, &aidev->aiispbuf[i]);
for (i = 0; i < ispbuf->bnr_buf.u.v35.y_src.buf_cnt; i++)
rkaiisp_detach_dmabuf(aidev, &aidev->ynrinbuf[i]);
rkaiisp_free_tempbuf(aidev);
if (aidev->exealgo == AIYNR)
rkaiisp_free_aiynr_ybuf(aidev);
aidev->init_buf = false;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"free buf poll\n");
@@ -432,9 +468,10 @@ static int rkaiisp_attach_dmabuf(struct rkaiisp_device *aidev,
buffer->sgt = sgt;
buffer->dma_addr = sg_dma_address(sgt->sgl);
buffer->size = sg_dma_len(sgt->sgl);
buffer->vaddr = NULL;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"%s buf:%pad size:%d\n", __func__,
&buffer->dma_addr, buffer->size);
"%s dma_fd:%d, buf:%pad size:%d\n", __func__,
buffer->dma_fd, &buffer->dma_addr, buffer->size);
return ret;
}
@@ -446,6 +483,26 @@ static void rkaiisp_calc_outbuf_size(struct rkaiisp_device *aidev, u32 raw_hgt,
if (aidev->model_mode == REMOSAIC_MODE)
return;
if (aidev->model_mode == AIYNR_MODE) {
for (i = 0; i < RKAIISP_AIYNR_LAYER_NUM; i++) {
if (i == 0) {
aidev->outbuf_size[i].height = raw_hgt;
aidev->outbuf_size[i].width = raw_wid;
aidev->outbuf_size[i].channel = 1;
aidev->outbuf_size[i].stride = raw_wid;
} else {
aidev->outbuf_size[i].height = raw_hgt / 2;
aidev->outbuf_size[i].width = raw_wid / 2;
aidev->outbuf_size[i].channel = 8;
aidev->outbuf_size[i].stride = raw_wid * 8;
}
raw_hgt = CEIL_BY(CEIL_DOWN(raw_hgt, 2), 2);
raw_wid = CEIL_BY(CEIL_DOWN(raw_wid, 2), 2);
}
return;
}
if (aidev->model_mode == SINGLEX2_MODE) {
for (i = 0; i < RKAIISP_PYRAMID_LAYER_NUM; i++) {
if (i == 0) {
@@ -494,7 +551,7 @@ static void rkaiisp_calc_outbuf_size(struct rkaiisp_device *aidev, u32 raw_hgt,
static int rkaiisp_init_pool(struct rkaiisp_device *aidev, struct rkaiisp_ispbuf_info *ispbuf)
{
int i, ret = 0;
u32 stride;
u32 stride, size;
for (i = 0; i < ispbuf->bnr_buf.iir.buf_cnt; i++) {
aidev->iirbuf[i].dma_fd = ispbuf->bnr_buf.iir.buf_fd[i];
@@ -536,9 +593,25 @@ static int rkaiisp_init_pool(struct rkaiisp_device *aidev, struct rkaiisp_ispbuf
return -EINVAL;
}
}
for (i = 0; i < ispbuf->bnr_buf.u.v35.y_src.buf_cnt; i++) {
aidev->ynrinbuf[i].dma_fd = ispbuf->bnr_buf.u.v35.y_src.buf_fd[i];
ret = rkaiisp_attach_dmabuf(aidev, &aidev->ynrinbuf[i]);
stride = ((ispbuf->iir_width + 1) / 2 * 15 * 11 + 7) >> 3;
aidev->temp_buf[0].size = stride * (ispbuf->iir_height + 1) / 2;
if (ret) {
rkaiisp_free_pool(aidev);
v4l2_err(&aidev->v4l2_dev, "attach dmabuf failed: %d\n", ret);
return -EINVAL;
}
}
if (aidev->exealgo == AIYNR) {
stride = ((ispbuf->iir_width + 3) / 4 * 8 * 11 + 7) >> 3;
size = stride * (ispbuf->iir_height + 3) / 4;
} else {
stride = ((ispbuf->iir_width + 1) / 2 * 15 * 11 + 7) >> 3;
size = stride * (ispbuf->iir_height + 1) / 2;
}
aidev->temp_buf[0].size = size;
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;
@@ -635,7 +708,7 @@ static int rkaiisp_init_airms_pool(struct rkaiisp_device *aidev, struct rkaiisp_
return ret;
}
int rkaiisp_queue_ispbuf(struct rkaiisp_device *aidev, union rkaiisp_queue_buf *idxbuf)
static 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;
@@ -656,10 +729,10 @@ int rkaiisp_queue_ispbuf(struct rkaiisp_device *aidev, 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)
if (aidev->exealgo == AIRMS)
sequence = idxbuf->airms_st.sequence;
else
sequence = idxbuf->aibnr_st.sequence;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"idxbuf fifo in: %d\n", sequence);
@@ -676,6 +749,40 @@ int rkaiisp_queue_ispbuf(struct rkaiisp_device *aidev, union rkaiisp_queue_buf *
return ret;
}
static int rkaiisp_get_ynrbuf_info(struct rkaiisp_device *aidev,
struct rkaiisp_ynrbuf_info *ynrbuf_info)
{
struct aiisp_aiynr_ybuf_cfg *buf_cfg = &aidev->ynr_ybuf_cfg;
struct rkaiisp_dummy_buffer *ynroutbuf = &aidev->ynroutbuf[0];
u32 buf_cnt;
int i;
buf_cnt = buf_cfg->buf_cnt;
if (buf_cnt > RKAIISP_AIYNR_YBUF_NUM_MAX) {
v4l2_err(&aidev->v4l2_dev,
"%s ynroutbuf cnt(%d) is too big\n", __func__,
buf_cnt);
buf_cnt = RKAIISP_AIYNR_YBUF_NUM_MAX;
}
ynrbuf_info->width = buf_cfg->width;
ynrbuf_info->height = buf_cfg->height;
ynrbuf_info->buf_cnt = 0;
for (i = 0; i < buf_cnt; i++) {
if (buf_cfg->buf[i]) {
ynroutbuf[i].dma_fd = dma_buf_fd(ynroutbuf[i].dmabuf, O_CLOEXEC);
if (ynroutbuf[i].dma_fd < 0)
return -EINVAL;
get_dma_buf(ynroutbuf[i].dmabuf);
ynrbuf_info->dma_fd[i] = ynroutbuf[i].dma_fd;
ynrbuf_info->buf_cnt++;
}
}
return 0;
}
static void rkaiisp_gen_slice_param(struct rkaiisp_device *aidev,
struct rkaiisp_model_cfg *model_cfg, int width)
{
@@ -759,7 +866,7 @@ static void rkaiisp_gen_slice_param(struct rkaiisp_device *aidev,
slice_mode[6] << 12 |
slice_mode[7] << 14 |
slice_num << 24 |
AIISP_MODE_MODE1 << 30;
model_cfg->sw_aiisp_mode << 30;
rkaiisp_write(aidev, AIISP_MI_SLICE_CTRL, value, false);
lext_num_sel = ext_tab[model_cfg->sw_aiisp_op_mode][slice_mode[slice_num]];
@@ -1000,7 +1107,7 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
struct rkaiisp_rmsbuf_info *rmsbuf = &aidev->rmsbuf;
struct rkaiisp_dummy_buffer *vpsl_buf;
dma_addr_t dma_addr;
u32 width, height;
u32 width, height, stride;
u32 sig_width = 0;
int buffer_index;
int i;
@@ -1010,6 +1117,7 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
if (model_cfg->sw_mi_chn_en[i] == 0)
continue;
stride = 0;
switch (model_cfg->mi_chn_src[i]) {
case ISP_IIR:
width = CEIL_BY(ispbuf->iir_width, 16);
@@ -1022,60 +1130,71 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
width = ispbuf->raw_width[0];
height = ispbuf->raw_height[0];
dma_addr = vpsl_buf->dma_addr + ispbuf->bnr_buf.u.v35.vpsl_yraw_offs[0];
stride = ispbuf->bnr_buf.u.v35.vpsl_yraw_stride[0];
break;
case VPSL_YRAW_CHN1:
width = ispbuf->raw_width[1];
height = ispbuf->raw_height[1];
dma_addr = vpsl_buf->dma_addr + ispbuf->bnr_buf.u.v35.vpsl_yraw_offs[1];
stride = ispbuf->bnr_buf.u.v35.vpsl_yraw_stride[1];
break;
case VPSL_YRAW_CHN2:
width = ispbuf->raw_width[2];
height = ispbuf->raw_height[2];
dma_addr = vpsl_buf->dma_addr + ispbuf->bnr_buf.u.v35.vpsl_yraw_offs[2];
stride = ispbuf->bnr_buf.u.v35.vpsl_yraw_stride[2];
break;
case VPSL_YRAW_CHN3:
width = ispbuf->raw_width[3];
height = ispbuf->raw_height[3];
dma_addr = vpsl_buf->dma_addr + ispbuf->bnr_buf.u.v35.vpsl_yraw_offs[3];
stride = ispbuf->bnr_buf.u.v35.vpsl_yraw_stride[3];
break;
case VPSL_YRAW_CHN4:
width = ispbuf->raw_width[4];
height = ispbuf->raw_height[4];
dma_addr = vpsl_buf->dma_addr + ispbuf->bnr_buf.u.v35.vpsl_yraw_offs[4];
stride = ispbuf->bnr_buf.u.v35.vpsl_yraw_stride[4];
break;
case VPSL_YRAW_CHN5:
width = ispbuf->raw_width[5];
height = ispbuf->raw_height[5];
dma_addr = vpsl_buf->dma_addr + ispbuf->bnr_buf.u.v35.vpsl_yraw_offs[5];
stride = ispbuf->bnr_buf.u.v35.vpsl_yraw_stride[5];
break;
case VPSL_SIG_CHN0:
width = ispbuf->sig_width[0];
height = ispbuf->sig_height[0];
dma_addr = vpsl_buf->dma_addr + ispbuf->bnr_buf.u.v35.vpsl_sig_offs[0];
stride = ispbuf->bnr_buf.u.v35.vpsl_sig_stride[0];
sig_width = width;
break;
case VPSL_SIG_CHN1:
width = ispbuf->sig_width[1];
height = ispbuf->sig_height[1];
dma_addr = vpsl_buf->dma_addr + ispbuf->bnr_buf.u.v35.vpsl_sig_offs[1];
stride = ispbuf->bnr_buf.u.v35.vpsl_sig_stride[1];
sig_width = width;
break;
case VPSL_SIG_CHN2:
width = ispbuf->sig_width[2];
height = ispbuf->sig_height[2];
dma_addr = vpsl_buf->dma_addr + ispbuf->bnr_buf.u.v35.vpsl_sig_offs[2];
stride = ispbuf->bnr_buf.u.v35.vpsl_sig_stride[2];
sig_width = width;
break;
case VPSL_SIG_CHN3:
width = ispbuf->sig_width[3];
height = ispbuf->sig_height[3];
dma_addr = vpsl_buf->dma_addr + ispbuf->bnr_buf.u.v35.vpsl_sig_offs[3];
stride = ispbuf->bnr_buf.u.v35.vpsl_sig_stride[3];
sig_width = width;
break;
case VPSL_SIG_CHN4:
width = ispbuf->sig_width[4];
height = ispbuf->sig_height[4];
dma_addr = vpsl_buf->dma_addr + ispbuf->bnr_buf.u.v35.vpsl_sig_offs[4];
stride = ispbuf->bnr_buf.u.v35.vpsl_sig_stride[4];
sig_width = width;
break;
case ISP_AIPRE_NARMAP:
@@ -1097,7 +1216,8 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
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;
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr;
break;
case ALLZERO_SIGMA:
width = rmsbuf->sigma_width;
@@ -1110,6 +1230,12 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
height = rmsbuf->narmap_height;
dma_addr = aidev->narmap_buf.dma_addr;
break;
case ISP_FINAL_Y:
width = ispbuf->iir_width;
height = ispbuf->iir_height;
buffer_index = aidev->curr_idxbuf.aibnr_st.y_src_index;
dma_addr = aidev->ynrinbuf[buffer_index].dma_addr;
break;
default:
width = 0;
height = 0;
@@ -1120,12 +1246,15 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
if (width > 0) {
aidev->chn_size[i].width = width;
aidev->chn_size[i].height = height;
aidev->chn_size[i].stride = stride;
rkaiisp_write(aidev, AIISP_MI_RD_CH0_BASE + 0x100 * i, dma_addr, false);
rkaiisp_write(aidev, AIISP_MI_RD_CH0_HEIGHT + 0x100 * i, height, false);
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"configure channel %d, width %d, height %d, dma_addr %pad\n",
i, aidev->chn_size[i].width, aidev->chn_size[i].height, &dma_addr);
"configure channel %d, width %d, height %d, stride %d, dma_addr %pad, mi_chn_src %d\n",
i, aidev->chn_size[i].width, aidev->chn_size[i].height,
aidev->chn_size[i].stride, &dma_addr,
model_cfg->mi_chn_src[i]);
}
}
@@ -1147,14 +1276,14 @@ static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
int buffer_index;
int sequence = 0;
if (aidev->exealgo == AIBNR)
sequence = aidev->curr_idxbuf.aibnr_st.sequence;
else if (aidev->exealgo == AIRMS)
if (aidev->exealgo == AIRMS)
sequence = aidev->curr_idxbuf.airms_st.sequence;
else
sequence = aidev->curr_idxbuf.aibnr_st.sequence;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"run frame id: %d, run_idx: %d\n",
sequence, run_idx);
"run frame id: %d, run_idx: %d, model_mode %d\n",
sequence, run_idx, aidev->model_mode);
cur_params = (struct rkaiisp_params *)aidev->cur_params->vaddr[0];
model_cfg = &cur_params->model_cfg[run_idx];
@@ -1162,7 +1291,38 @@ 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 == REMOSAIC_MODE) {
if (aidev->model_mode == AIYNR_MODE) {
if (run_idx == 0) {
sig_width = rkaiisp_config_rdchannel(aidev, model_cfg, run_idx);
outbuf_idx = 0;
aidev->outbuf_idx = outbuf_idx;
rkaiisp_write(aidev, AIISP_MI_CHN0_WR_BASE,
aidev->temp_buf[outbuf_idx].dma_addr, false);
rkaiisp_gen_slice_param(aidev, model_cfg, sig_width);
rkaiisp_determine_size(aidev, model_cfg);
} else if (run_idx < aidev->model_runcnt-1) {
outbuf_idx = aidev->outbuf_idx;
sig_width = rkaiisp_config_rdchannel(aidev, model_cfg, run_idx);
rkaiisp_gen_slice_param(aidev, model_cfg, sig_width);
rkaiisp_determine_size(aidev, model_cfg);
outbuf_idx = (outbuf_idx + 1) % 2;
aidev->outbuf_idx = outbuf_idx;
rkaiisp_write(aidev, AIISP_MI_CHN0_WR_BASE,
aidev->temp_buf[outbuf_idx].dma_addr, false);
} else {
sig_width = rkaiisp_config_rdchannel(aidev, model_cfg, run_idx);
buffer_index = aidev->curr_idxbuf.aibnr_st.y_dest_index;
dma_addr = aidev->ynroutbuf[buffer_index].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 == 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;
@@ -1307,10 +1467,10 @@ 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)
if (aidev->exealgo == AIRMS)
sequence = aidev->curr_idxbuf.airms_st.sequence;
else
sequence = aidev->curr_idxbuf.aibnr_st.sequence;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"idxbuf fifo out: %d\n", sequence);
@@ -1401,10 +1561,10 @@ 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)
if (aidev->exealgo == AIRMS)
sequence = aidev->curr_idxbuf.airms_st.sequence;
else
sequence = aidev->curr_idxbuf.aibnr_st.sequence;
if (!rkaiisp_update_buf(aidev)) {
aidev->run_idx = 0;
@@ -1425,10 +1585,10 @@ static void rkaiisp_event_queue(struct rkaiisp_device *aidev, union rkaiisp_queu
struct v4l2_event event = {0};
int sequence = 0;
if (aidev->exealgo == AIBNR)
sequence = idxbuf->aibnr_st.sequence;
else if (aidev->exealgo == AIRMS)
if (aidev->exealgo == AIRMS)
sequence = idxbuf->airms_st.sequence;
else
sequence = idxbuf->aibnr_st.sequence;
if (aidev->subdev.is_subs_evt && aidev->exemode != BOTHEVENT_IN_KERNEL) {
event.type = RKAIISP_V4L2_EVENT_AIISP_DONE;
@@ -1649,6 +1809,9 @@ static long rkaiisp_ioctl_default(struct file *file, void *fh,
case RKAIISP_CMD_INIT_AIRMS_BUFPOOL:
ret = rkaiisp_init_airms_pool(aidev, arg);
break;
case RKAIISP_CMD_GET_YNRBUF_INFO:
ret = rkaiisp_get_ynrbuf_info(aidev, arg);
break;
default:
ret = -EINVAL;
}
@@ -1953,3 +2116,54 @@ void rkaiisp_unregister_vdev(struct rkaiisp_device *aidev)
vb2_queue_release(vdev->queue);
}
int rkaiisp_set_aiynr_ybuf(struct rkaiisp_device *aidev, struct aiisp_aiynr_ybuf_cfg *buf_cfg)
{
struct rkaiisp_dummy_buffer *ynroutbuf = &aidev->ynroutbuf[0];
u32 buf_cnt;
int i;
mutex_lock(&aidev->apilock);
if (aidev->ynr_ybuf_cfg.buf_cnt > 0)
rkaiisp_free_aiynr_ybuf(aidev);
buf_cnt = buf_cfg->buf_cnt;
if (buf_cnt > RKAIISP_AIYNR_YBUF_NUM_MAX) {
v4l2_err(&aidev->v4l2_dev,
"%s input ynroutbuf cnt(%d) is too big\n", __func__,
buf_cnt);
buf_cnt = RKAIISP_AIYNR_YBUF_NUM_MAX;
}
for (i = 0; i < buf_cnt; i++) {
struct dma_buf_attachment *dba;
struct sg_table *sgt;
dba = dma_buf_attach(buf_cfg->buf[i], aidev->hw_dev->dev);
if (IS_ERR(dba)) {
mutex_unlock(&aidev->apilock);
return PTR_ERR(dba);
}
sgt = dma_buf_map_attachment(dba, DMA_BIDIRECTIONAL);
if (IS_ERR(sgt)) {
dma_buf_detach(buf_cfg->buf[i], dba);
mutex_unlock(&aidev->apilock);
return PTR_ERR(sgt);
}
ynroutbuf[i].vaddr = NULL;
ynroutbuf[i].dma_addr = sg_dma_address(sgt->sgl);
get_dma_buf(buf_cfg->buf[i]);
ynroutbuf[i].dmabuf = buf_cfg->buf[i];
ynroutbuf[i].dba = dba;
ynroutbuf[i].sgt = sgt;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"%s buf:%pad size:%zu dmabuf:%p\n", __func__,
&ynroutbuf[i].dma_addr, ynroutbuf[i].dmabuf->size,
buf_cfg->buf[i]);
}
aidev->ynr_ybuf_cfg = *buf_cfg;
mutex_unlock(&aidev->apilock);
return 0;
}

View File

@@ -22,6 +22,7 @@
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-core.h>
#include <media/v4l2-event.h>
#include <soc/rockchip/rockchip_aiisp.h>
#include "hw.h"
#define DRIVER_NAME "rkaiisp"
@@ -115,6 +116,7 @@ struct rkaiisp_device {
struct rkaiisp_dummy_buffer aiprebuf[RKISP_BUFFER_MAX];
struct rkaiisp_dummy_buffer vpslbuf[RKISP_BUFFER_MAX];
struct rkaiisp_dummy_buffer aiispbuf[RKISP_BUFFER_MAX];
struct rkaiisp_dummy_buffer ynrinbuf[RKISP_BUFFER_MAX];
struct rkaiisp_dummy_buffer temp_buf[RKAIISP_TMP_BUF_CNT];
u32 outbuf_idx;
@@ -124,6 +126,9 @@ struct rkaiisp_device {
struct rkaiisp_dummy_buffer sigma_buf;
struct rkaiisp_dummy_buffer narmap_buf;
struct aiisp_aiynr_ybuf_cfg ynr_ybuf_cfg;
struct rkaiisp_dummy_buffer ynroutbuf[RKAIISP_AIYNR_YBUF_NUM_MAX];
struct kfifo idxbuf_kfifo;
union rkaiisp_queue_buf curr_idxbuf;
@@ -192,8 +197,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, union rkaiisp_queue_buf *idxbuf);
void rkaiisp_update_list_reg(struct rkaiisp_device *aidev);
int rkaiisp_set_aiynr_ybuf(struct rkaiisp_device *aidev, struct aiisp_aiynr_ybuf_cfg *buf_cfg);
void rkaiisp_trigger(struct rkaiisp_device *aidev);
int rkaiisp_get_idxbuf_len(struct rkaiisp_device *aidev);
enum rkaiisp_irqhdl_ret rkaiisp_irq_hdl(struct rkaiisp_device *aidev, u32 mi_mis);

View File

@@ -21,6 +21,7 @@
#include <media/videobuf2-cma-sg.h>
#include <media/videobuf2-dma-sg.h>
#include <soc/rockchip/rockchip_iommu.h>
#include <soc/rockchip/rockchip_aiisp.h>
#include "regs.h"
#include "hw.h"
@@ -116,11 +117,11 @@ static int rkaiisp_register_irq(struct rkaiisp_hw_dev *hw_dev)
return 0;
}
int rkaiisp_ispidx_queue(int dev_id, struct rkisp_aiisp_st *idxbuf)
int rkaiisp_cfg_aiynr_yuvbuf(struct aiisp_aiynr_ybuf_cfg *buf_cfg)
{
struct rkaiisp_hw_dev *hw_dev = rkaiisp_hwdev;
struct rkaiisp_device *aidev = NULL;
union rkaiisp_queue_buf queue_buf;
int dev_id;
int i;
if (!hw_dev) {
@@ -128,9 +129,16 @@ int rkaiisp_ispidx_queue(int dev_id, struct rkisp_aiisp_st *idxbuf)
return -EINVAL;
}
if (!buf_cfg) {
pr_err("Input buf_cfg is NULL!");
return -EINVAL;
}
dev_id = buf_cfg->dev_id;
for (i = 0; i < hw_dev->dev_num; i++) {
if (hw_dev->aidev[i]) {
if ((hw_dev->aidev[i]->is_hw_link) && hw_dev->aidev[i]->dev_id == dev_id) {
if ((hw_dev->aidev[i]->is_hw_link) &&
hw_dev->aidev[i]->dev_id == dev_id) {
aidev = hw_dev->aidev[i];
break;
}
@@ -142,15 +150,9 @@ int rkaiisp_ispidx_queue(int dev_id, struct rkisp_aiisp_st *idxbuf)
return -EINVAL;
}
if (aidev->exemode != BOTHEVENT_TO_AIQ) {
pr_err("aidev %d exemode(%d) is not right!", dev_id, aidev->exemode);
return -EINVAL;
}
queue_buf.aibnr_st = *idxbuf;
return rkaiisp_queue_ispbuf(aidev, &queue_buf);
return rkaiisp_set_aiynr_ybuf(aidev, buf_cfg);
}
EXPORT_SYMBOL(rkaiisp_ispidx_queue);
EXPORT_SYMBOL(rkaiisp_cfg_aiynr_yuvbuf);
static const char * const rv1126b_clks[] = {
"clk_aiisp_core",

View File

@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#ifndef __SOC_ROCKCHIP_AIISP_H
#define __SOC_ROCKCHIP_AIISP_H
#include <linux/dma-buf.h>
#include <linux/rk-aiisp-config.h>
struct aiisp_aiynr_ybuf_cfg {
int dev_id;
int width;
int height;
u32 buf_cnt;
struct dma_buf *buf[RKAIISP_AIYNR_YBUF_NUM_MAX];
};
#if IS_REACHABLE(CONFIG_VIDEO_ROCKCHIP_AIISP)
int rkaiisp_cfg_aiynr_yuvbuf(struct aiisp_aiynr_ybuf_cfg *buf_cfg);
#else
static inline int rkaiisp_cfg_aiynr_yuvbuf(struct aiisp_aiynr_ybuf_cfg *buf_cfg)
{
return -EINVAL;
}
#endif
#endif

View File

@@ -10,10 +10,12 @@
#include <linux/rk-isp2-config.h>
#define RKAIISP_PYRAMID_LAYER_NUM 4
#define RKAIISP_AIYNR_LAYER_NUM 5
#define RKAIISP_MAX_RUNCNT 8
#define RKAIISP_MAX_ISPBUF 8
#define RKAIISP_MODEL_UPDATE 0x01
#define RKAIISP_OTHER_UPDATE 0x02
#define RKAIISP_AIYNR_YBUF_NUM_MAX 8
#define RKAIISP_CMD_SET_PARAM_INFO \
_IOW('V', BASE_VIDIOC_PRIVATE + 0, struct rkaiisp_param_info)
@@ -30,6 +32,9 @@
#define RKAIISP_CMD_INIT_AIRMS_BUFPOOL \
_IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct rkaiisp_rmsbuf_info)
#define RKAIISP_CMD_GET_YNRBUF_INFO \
_IOR('V', BASE_VIDIOC_PRIVATE + 5, struct rkaiisp_ynrbuf_info)
/**********************EVENT_PRIVATE***************************/
#define RKAIISP_V4L2_EVENT_AIISP_DONE (V4L2_EVENT_PRIVATE_START + 1)
@@ -50,7 +55,8 @@ enum rkaiisp_chn_src {
AIISP_LAST_OUT,
VICAP_BAYER_RAW,
ALLZERO_SIGMA,
ALLZERO_NARMAP
ALLZERO_NARMAP,
ISP_FINAL_Y
};
enum rkaiisp_exealgo {
@@ -63,7 +69,8 @@ enum rkaiisp_model_mode {
SINGLE_MODE,
COMBO_MODE,
SINGLEX2_MODE,
REMOSAIC_MODE
REMOSAIC_MODE,
AIYNR_MODE
};
enum rkaiisp_exemode {
@@ -115,6 +122,13 @@ struct rkaiisp_rmsbuf_info {
int outbuf_fd[6];
} __attribute__ ((packed));
struct rkaiisp_ynrbuf_info {
int width;
int height;
__u32 buf_cnt;
int dma_fd[RKAIISP_AIYNR_YBUF_NUM_MAX];
} __attribute__ ((packed));
struct rkaiisp_other_cfg {
__u16 sw_neg_noiselimit;
__u16 sw_pos_noiselimit;