mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
media: rockchip: aiisp: support picture width over 4096 in airms algo
Change-Id: I5115494f57fc5a745ba066d32fc9e16b3911eb15 Signed-off-by: Hu Kejun <william.hu@rock-chips.com>
This commit is contained in:
@@ -174,8 +174,8 @@ static void rkaiisp_dumpreg(struct rkaiisp_device *aidev, u32 start, u32 end)
|
||||
|
||||
static void rkaiisp_dump_list_reg(struct rkaiisp_device *aidev)
|
||||
{
|
||||
dev_info(aidev->dev, "frame_id: %d, run_idx: %d\n",
|
||||
aidev->frame_id, aidev->run_idx);
|
||||
dev_info(aidev->dev, "frame_id: %d, run_idx: %d, parthdl %d\n",
|
||||
aidev->frame_id, aidev->run_idx, aidev->parthdl_idx);
|
||||
|
||||
rkaiisp_dumpreg(aidev, AIISP_CORE_CTRL, AIISP_CORE_NOISE_LMT);
|
||||
rkaiisp_dumpreg(aidev, AIISP_CORE_COMP0, AIISP_CORE_DECOMP16);
|
||||
@@ -669,6 +669,7 @@ static int rkaiisp_init_pool(struct rkaiisp_device *aidev, struct rkaiisp_ispbuf
|
||||
|
||||
aidev->ispbuf = *ispbuf;
|
||||
aidev->outbuf_idx = 0;
|
||||
aidev->parthdl_num = 1;
|
||||
aidev->init_buf = true;
|
||||
|
||||
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev, "init buf poll\n");
|
||||
@@ -720,7 +721,25 @@ static int rkaiisp_init_airms_pool(struct rkaiisp_device *aidev, struct rkaiisp_
|
||||
rmsbuf->inbuf_fd[i] = aidev->rms_inbuf[i].dma_fd;
|
||||
}
|
||||
|
||||
size = rmsbuf->image_width * rmsbuf->image_height * 2;
|
||||
aidev->rmsbuf = *rmsbuf;
|
||||
aidev->part_rmsbuf = aidev->rmsbuf;
|
||||
if (rmsbuf->image_width > RKAIISP_AIRMS_MAX_WIDTH) {
|
||||
int proc_width;
|
||||
|
||||
aidev->is_parthdl = true;
|
||||
aidev->parthdl_num = 2;
|
||||
proc_width = aidev->part_rmsbuf.image_width / 2 + RKAIISP_AIRMS_EXTEND_PIXEL;
|
||||
aidev->part_rmsbuf.image_width = CEIL_BY(proc_width, 16);
|
||||
aidev->part_rmsbuf.sigma_width = aidev->part_rmsbuf.image_width / 2;
|
||||
aidev->part_rmsbuf.narmap_width = (aidev->part_rmsbuf.image_width + 7) / 8 * 2;
|
||||
aidev->parthdl_image_oft = aidev->rmsbuf.image_width - aidev->part_rmsbuf.image_width;
|
||||
size = (CEIL_BY(rmsbuf->image_width, 2) + 2 * RKAIISP_AIRMS_EXTEND_PIXEL) * rmsbuf->image_height * 2;
|
||||
} else {
|
||||
aidev->is_parthdl = false;
|
||||
aidev->parthdl_num = 1;
|
||||
size = rmsbuf->image_width * rmsbuf->image_height * 2;
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -736,13 +755,12 @@ static int rkaiisp_init_airms_pool(struct rkaiisp_device *aidev, struct rkaiisp_
|
||||
rmsbuf->outbuf_fd[i] = aidev->rms_outbuf[i].dma_fd;
|
||||
}
|
||||
|
||||
aidev->narmap_buf.size = rmsbuf->narmap_width * rmsbuf->narmap_height;
|
||||
aidev->narmap_buf.size = aidev->rmsbuf.narmap_width * aidev->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");
|
||||
@@ -896,6 +914,13 @@ static void rkaiisp_gen_slice_param(struct rkaiisp_device *aidev,
|
||||
}
|
||||
}
|
||||
|
||||
if (slice_idx > 8) {
|
||||
aidev->is_state_err = true;
|
||||
v4l2_err(&aidev->v4l2_dev,
|
||||
"slice num %d is too big, input width %d\n", slice_idx, width);
|
||||
return;
|
||||
}
|
||||
|
||||
if (slice_idx >= 1)
|
||||
slice_num = slice_idx - 1;
|
||||
value = slice_mode[0] |
|
||||
@@ -1006,6 +1031,9 @@ static int rkaiisp_determine_size(struct rkaiisp_device *aidev,
|
||||
if (n == 3 && model_cfg->sw_mi_chn3_sel == 0)
|
||||
bits = 8;
|
||||
|
||||
if (aidev->chn_size[n].stride != 0 && aidev->exealgo == AIRMS)
|
||||
cols = aidev->chn_size[n].stride;
|
||||
|
||||
sw_mi_chn_stride[n] = CEIL_BY(cols * chns * bits, 16 * 8) / 32;
|
||||
}
|
||||
|
||||
@@ -1146,6 +1174,7 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
|
||||
{
|
||||
struct rkaiisp_ispbuf_info *ispbuf = &aidev->ispbuf;
|
||||
struct rkaiisp_rmsbuf_info *rmsbuf = &aidev->rmsbuf;
|
||||
struct rkaiisp_rmsbuf_info *part_rmsbuf = &aidev->part_rmsbuf;
|
||||
struct rkaiisp_dummy_buffer *vpsl_buf;
|
||||
dma_addr_t dma_addr;
|
||||
u32 width, height, stride;
|
||||
@@ -1255,14 +1284,29 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
|
||||
dma_addr = aidev->lastout_buf[aidev->outbuf_idx]->dma_addr;
|
||||
break;
|
||||
case VICAP_BAYER_RAW:
|
||||
width = rmsbuf->image_width;
|
||||
height = rmsbuf->image_height;
|
||||
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
|
||||
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr;
|
||||
if (aidev->is_parthdl) {
|
||||
width = part_rmsbuf->image_width;
|
||||
height = part_rmsbuf->image_height;
|
||||
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
|
||||
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr;
|
||||
if (aidev->parthdl_idx == 1)
|
||||
dma_addr += aidev->parthdl_image_oft * 2;
|
||||
stride = rmsbuf->image_width;
|
||||
} else {
|
||||
width = rmsbuf->image_width;
|
||||
height = rmsbuf->image_height;
|
||||
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
|
||||
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr;
|
||||
}
|
||||
break;
|
||||
case ALLZERO_NARMAP:
|
||||
width = rmsbuf->narmap_width;
|
||||
height = rmsbuf->narmap_height;
|
||||
if (aidev->is_parthdl) {
|
||||
width = part_rmsbuf->narmap_width;
|
||||
height = part_rmsbuf->narmap_height;
|
||||
} else {
|
||||
width = rmsbuf->narmap_width;
|
||||
height = rmsbuf->narmap_height;
|
||||
}
|
||||
dma_addr = aidev->narmap_buf.dma_addr;
|
||||
break;
|
||||
case ISP_FINAL_Y:
|
||||
@@ -1272,13 +1316,26 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
|
||||
dma_addr = aidev->ynrinbuf[buffer_index].dma_addr;
|
||||
break;
|
||||
case VICAP_BAYER_RAW_DOWN:
|
||||
width = rmsbuf->image_width;
|
||||
height = rmsbuf->image_height;
|
||||
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
|
||||
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr + width * height * 2;
|
||||
width = CEIL_BY(CEIL_DOWN(rmsbuf->image_width, 2), 2);
|
||||
height = CEIL_BY(CEIL_DOWN(rmsbuf->image_height, 2), 2);
|
||||
sig_width = width;
|
||||
if (aidev->is_parthdl) {
|
||||
width = rmsbuf->image_width;
|
||||
height = rmsbuf->image_height;
|
||||
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
|
||||
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr + width * height * 2;
|
||||
if (aidev->parthdl_idx == 1)
|
||||
dma_addr += aidev->parthdl_image_oft / 2;
|
||||
width = CEIL_BY(CEIL_DOWN(part_rmsbuf->image_width, 2), 2);
|
||||
height = CEIL_BY(CEIL_DOWN(part_rmsbuf->image_height, 2), 2);
|
||||
sig_width = width;
|
||||
stride = CEIL_BY(CEIL_DOWN(rmsbuf->image_width, 2), 2);
|
||||
} else {
|
||||
width = rmsbuf->image_width;
|
||||
height = rmsbuf->image_height;
|
||||
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
|
||||
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr + width * height * 2;
|
||||
width = CEIL_BY(CEIL_DOWN(rmsbuf->image_width, 2), 2);
|
||||
height = CEIL_BY(CEIL_DOWN(rmsbuf->image_height, 2), 2);
|
||||
sig_width = width;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
width = 0;
|
||||
@@ -1290,7 +1347,7 @@ 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;
|
||||
aidev->chn_size[i].stride = stride > 0 ? stride : width;
|
||||
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);
|
||||
|
||||
@@ -1308,6 +1365,7 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
|
||||
static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
|
||||
{
|
||||
struct rkaiisp_ispbuf_info *ispbuf = &aidev->ispbuf;
|
||||
struct rkaiisp_rmsbuf_info *rmsbuf = &aidev->rmsbuf;
|
||||
struct rkaiisp_params *cur_params;
|
||||
struct rkaiisp_model_cfg *model_cfg;
|
||||
int lastlv, lv_mode, out_chns, i;
|
||||
@@ -1329,6 +1387,7 @@ static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
|
||||
"run frame id: %d, run_idx: %d, model_mode %d\n",
|
||||
sequence, run_idx, aidev->model_mode);
|
||||
|
||||
aidev->is_state_err = false;
|
||||
cur_params = (struct rkaiisp_params *)aidev->cur_params->vaddr[0];
|
||||
model_cfg = &cur_params->model_cfg[run_idx];
|
||||
|
||||
@@ -1370,10 +1429,17 @@ static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
|
||||
sig_width = rkaiisp_config_rdchannel(aidev, model_cfg, run_idx);
|
||||
|
||||
dma_addr = aidev->rms_outbuf[aidev->curr_idxbuf.airms_st.outbuf_idx].dma_addr;
|
||||
if (aidev->parthdl_idx == 1)
|
||||
dma_addr += 2 * (CEIL_BY(rmsbuf->image_width, 2) / 2 + RKAIISP_AIRMS_EXTEND_PIXEL);
|
||||
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);
|
||||
|
||||
iir_stride = CEIL_BY(rmsbuf->image_width, 2);
|
||||
if (aidev->is_parthdl)
|
||||
iir_stride += 2 * RKAIISP_AIRMS_EXTEND_PIXEL;
|
||||
rkaiisp_write(aidev, AIISP_MI_CHN0_WR_STRIDE, iir_stride / 2, false);
|
||||
} else if (aidev->model_mode == SINGLEX2_MODE) {
|
||||
if (run_idx == 0) {
|
||||
sig_width = rkaiisp_config_rdchannel(aidev, model_cfg, run_idx);
|
||||
@@ -1529,16 +1595,25 @@ static void rkaiisp_run_start(struct rkaiisp_device *aidev)
|
||||
{
|
||||
struct rkaiisp_hw_dev *hw_dev = aidev->hw_dev;
|
||||
|
||||
if (aidev->is_state_err) {
|
||||
v4l2_err(&aidev->v4l2_dev,
|
||||
"aiisp status is error!\n");
|
||||
rkaiisp_dump_list_reg(aidev);
|
||||
return;
|
||||
}
|
||||
|
||||
rkaiisp_write(aidev, AIISP_MI_IMSC, AIISP_MI_ISR_ALL, false);
|
||||
rkaiisp_write(aidev, AIISP_MI_WR_INIT, AIISP_MI_CHN0SELF_FORCE_UPD, false);
|
||||
|
||||
if ((aidev->run_idx == 0) && (rkaiisp_showreg != 0))
|
||||
if ((aidev->run_idx == 0) && (aidev->parthdl_idx == 0) && (rkaiisp_showreg != 0))
|
||||
aidev->showreg = true;
|
||||
|
||||
if (aidev->showreg)
|
||||
rkaiisp_dump_list_reg(aidev);
|
||||
|
||||
if ((aidev->run_idx == aidev->model_runcnt - 1) && aidev->showreg) {
|
||||
if ((aidev->run_idx + 1 == aidev->model_runcnt) &&
|
||||
(aidev->parthdl_idx + 1 == aidev->parthdl_num) &&
|
||||
aidev->showreg) {
|
||||
aidev->showreg = false;
|
||||
rkaiisp_showreg = 0;
|
||||
}
|
||||
@@ -1613,6 +1688,7 @@ void rkaiisp_trigger(struct rkaiisp_device *aidev)
|
||||
|
||||
if (!rkaiisp_update_buf(aidev)) {
|
||||
aidev->run_idx = 0;
|
||||
aidev->parthdl_idx = 0;
|
||||
aidev->frame_id = sequence;
|
||||
aidev->pre_frm_st = aidev->frm_st;
|
||||
aidev->frm_st = ktime_get_ns();
|
||||
@@ -1663,8 +1739,9 @@ enum rkaiisp_irqhdl_ret rkaiisp_irq_hdl(struct rkaiisp_device *aidev, u32 mi_mis
|
||||
u64 frm_hdntim = 0;
|
||||
|
||||
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
|
||||
"irq val: 0x%x, run_idx %d, model_runcnt %d\n",
|
||||
mi_mis, aidev->run_idx, aidev->model_runcnt);
|
||||
"irq val: 0x%x, run_idx %d, model_runcnt %d, parthdl %d, %d\n",
|
||||
mi_mis, aidev->run_idx, aidev->model_runcnt,
|
||||
aidev->parthdl_idx, aidev->parthdl_num);
|
||||
|
||||
if (mi_mis & AIISP_MI_ISR_BUSERR) {
|
||||
v4l2_err(&aidev->v4l2_dev, "buserr 0x%x\n", mi_mis);
|
||||
@@ -1677,11 +1754,17 @@ enum rkaiisp_irqhdl_ret rkaiisp_irq_hdl(struct rkaiisp_device *aidev, u32 mi_mis
|
||||
rkaiisp_write(aidev, AIISP_MI_ICR, AIISP_MI_ISR_WREND, true);
|
||||
aidev->isr_wrend_cnt++;
|
||||
|
||||
if (aidev->run_idx < aidev->model_runcnt - 1) {
|
||||
if (aidev->run_idx + 1 < aidev->model_runcnt) {
|
||||
aidev->run_idx++;
|
||||
rkaiisp_run_cfg(aidev, aidev->run_idx);
|
||||
rkaiisp_run_start(aidev);
|
||||
return CONTINUE_RUN;
|
||||
} else if (aidev->is_parthdl && (aidev->parthdl_idx + 1 < aidev->parthdl_num)) {
|
||||
aidev->parthdl_idx++;
|
||||
aidev->run_idx = 0;
|
||||
rkaiisp_run_cfg(aidev, aidev->run_idx);
|
||||
rkaiisp_run_start(aidev);
|
||||
return CONTINUE_RUN;
|
||||
}
|
||||
|
||||
aidev->frm_ed = ktime_get_ns();
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#define RKAIISP_SW_REG_SIZE 0x3000
|
||||
#define RKAIISP_SW_MAX_SIZE (RKAIISP_SW_REG_SIZE * 2)
|
||||
#define RKAIISP_AIRMS_BUF_MAXCNT 8
|
||||
#define RKAIISP_AIRMS_MAX_WIDTH 4096
|
||||
#define RKAIISP_AIRMS_EXTEND_PIXEL 16
|
||||
#define RKAIISP_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
enum rkaiisp_irqhdl_ret {
|
||||
@@ -121,7 +123,9 @@ struct rkaiisp_device {
|
||||
struct rkaiisp_dummy_buffer *lastout_buf[RKAIISP_LASTOUT_BUF_CNT];
|
||||
u32 outbuf_idx;
|
||||
|
||||
bool is_parthdl;
|
||||
struct rkaiisp_rmsbuf_info rmsbuf;
|
||||
struct rkaiisp_rmsbuf_info part_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 narmap_buf;
|
||||
@@ -149,6 +153,10 @@ struct rkaiisp_device {
|
||||
u32 run_idx;
|
||||
u32 frame_id;
|
||||
|
||||
u32 parthdl_idx;
|
||||
u32 parthdl_num;
|
||||
u32 parthdl_image_oft;
|
||||
|
||||
u64 pre_frm_st;
|
||||
u64 frm_st;
|
||||
u64 frm_ed;
|
||||
@@ -160,6 +168,7 @@ struct rkaiisp_device {
|
||||
bool streamon;
|
||||
bool showreg;
|
||||
bool init_buf;
|
||||
bool is_state_err;
|
||||
};
|
||||
|
||||
extern int rkaiisp_debug;
|
||||
|
||||
Reference in New Issue
Block a user