diff options
Diffstat (limited to 'drivers/staging/media/rkisp1/rkisp1-capture.c')
-rw-r--r-- | drivers/staging/media/rkisp1/rkisp1-capture.c | 101 |
1 files changed, 41 insertions, 60 deletions
diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c index 24fe6a7888aa..f69235f82c45 100644 --- a/drivers/staging/media/rkisp1/rkisp1-capture.c +++ b/drivers/staging/media/rkisp1/rkisp1-capture.c @@ -52,7 +52,6 @@ enum rkisp1_plane { */ struct rkisp1_capture_fmt_cfg { u32 fourcc; - u8 fmt_type; u8 uv_swap; u32 write_format; u32 output_format; @@ -87,133 +86,106 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = { /* yuv422 */ { .fourcc = V4L2_PIX_FMT_YUYV, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT, }, { .fourcc = V4L2_PIX_FMT_YVYU, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT, }, { .fourcc = V4L2_PIX_FMT_VYUY, - .fmt_type = RKISP1_FMT_YUV, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT, }, { .fourcc = V4L2_PIX_FMT_YUV422P, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8, }, { .fourcc = V4L2_PIX_FMT_NV16, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA, }, { .fourcc = V4L2_PIX_FMT_NV61, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA, }, { .fourcc = V4L2_PIX_FMT_YVU422M, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8, }, /* yuv420 */ { .fourcc = V4L2_PIX_FMT_NV21, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA, }, { .fourcc = V4L2_PIX_FMT_NV12, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA, }, { .fourcc = V4L2_PIX_FMT_NV21M, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA, }, { .fourcc = V4L2_PIX_FMT_NV12M, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA, }, { .fourcc = V4L2_PIX_FMT_YUV420, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8, }, { .fourcc = V4L2_PIX_FMT_YVU420, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8, }, /* yuv444 */ { .fourcc = V4L2_PIX_FMT_YUV444M, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8, }, /* yuv400 */ { .fourcc = V4L2_PIX_FMT_GREY, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT, }, /* raw */ { .fourcc = V4L2_PIX_FMT_SRGGB8, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8, }, { .fourcc = V4L2_PIX_FMT_SGRBG8, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8, }, { .fourcc = V4L2_PIX_FMT_SGBRG8, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8, }, { .fourcc = V4L2_PIX_FMT_SBGGR8, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8, }, { .fourcc = V4L2_PIX_FMT_SRGGB10, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12, }, { .fourcc = V4L2_PIX_FMT_SGRBG10, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12, }, { .fourcc = V4L2_PIX_FMT_SGBRG10, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12, }, { .fourcc = V4L2_PIX_FMT_SBGGR10, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12, }, { .fourcc = V4L2_PIX_FMT_SRGGB12, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12, }, { .fourcc = V4L2_PIX_FMT_SGRBG12, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12, }, { .fourcc = V4L2_PIX_FMT_SGBRG12, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12, }, { .fourcc = V4L2_PIX_FMT_SBGGR12, - .fmt_type = RKISP1_FMT_BAYER, .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12, }, }; @@ -222,43 +194,36 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = { /* yuv422 */ { .fourcc = V4L2_PIX_FMT_YUYV, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_SP_WRITE_INT, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422, }, { .fourcc = V4L2_PIX_FMT_YVYU, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_SP_WRITE_INT, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422, }, { .fourcc = V4L2_PIX_FMT_VYUY, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_SP_WRITE_INT, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422, }, { .fourcc = V4L2_PIX_FMT_YUV422P, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422, }, { .fourcc = V4L2_PIX_FMT_NV16, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422, }, { .fourcc = V4L2_PIX_FMT_NV61, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422, }, { .fourcc = V4L2_PIX_FMT_YVU422M, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422, @@ -266,37 +231,31 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = { /* yuv420 */ { .fourcc = V4L2_PIX_FMT_NV21, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420, }, { .fourcc = V4L2_PIX_FMT_NV12, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420, }, { .fourcc = V4L2_PIX_FMT_NV21M, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420, }, { .fourcc = V4L2_PIX_FMT_NV12M, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420, }, { .fourcc = V4L2_PIX_FMT_YUV420, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420, }, { .fourcc = V4L2_PIX_FMT_YVU420, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 1, .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420, @@ -304,7 +263,6 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = { /* yuv444 */ { .fourcc = V4L2_PIX_FMT_YUV444M, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV444, @@ -312,7 +270,6 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = { /* yuv400 */ { .fourcc = V4L2_PIX_FMT_GREY, - .fmt_type = RKISP1_FMT_YUV, .uv_swap = 0, .write_format = RKISP1_MI_CTRL_SP_WRITE_INT, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV400, @@ -320,17 +277,14 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = { /* rgb */ { .fourcc = V4L2_PIX_FMT_RGB24, - .fmt_type = RKISP1_FMT_RGB, .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB888, }, { .fourcc = V4L2_PIX_FMT_RGB565, - .fmt_type = RKISP1_FMT_RGB, .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB565, }, { .fourcc = V4L2_PIX_FMT_BGR666, - .fmt_type = RKISP1_FMT_RGB, .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB666, }, @@ -429,11 +383,14 @@ static void rkisp1_mp_config(struct rkisp1_capture *cap) cap->config->mi.cr_size_init); rkisp1_irq_frame_end_enable(cap); - if (cap->pix.cfg->uv_swap) { - reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL); - reg = (reg & ~BIT(0)) | - RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP; + /* set uv swapping for semiplanar formats */ + if (cap->pix.info->comp_planes == 2) { + reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL); + if (cap->pix.cfg->uv_swap) + reg |= RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP; + else + reg &= ~RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP; rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_XTD_FORMAT_CTRL); } @@ -453,7 +410,7 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap) { const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt; struct rkisp1_device *rkisp1 = cap->rkisp1; - u32 mi_ctrl; + u32 mi_ctrl, reg; rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y), cap->config->mi.y_size_init); @@ -467,11 +424,15 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap) rkisp1_write(rkisp1, cap->sp_y_stride, RKISP1_CIF_MI_SP_Y_LLENGTH); rkisp1_irq_frame_end_enable(cap); - if (cap->pix.cfg->uv_swap) { - u32 reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL); - rkisp1_write(rkisp1, reg & ~BIT(1), - RKISP1_CIF_MI_XTD_FORMAT_CTRL); + /* set uv swapping for semiplanar formats */ + if (cap->pix.info->comp_planes == 2) { + reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL); + if (cap->pix.cfg->uv_swap) + reg |= RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP; + else + reg &= ~RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP; + rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_XTD_FORMAT_CTRL); } rkisp1_mi_config_ctrl(cap); @@ -504,13 +465,12 @@ static void rkisp1_sp_disable(struct rkisp1_capture *cap) static void rkisp1_mp_enable(struct rkisp1_capture *cap) { - const struct rkisp1_capture_fmt_cfg *isp_fmt = cap->pix.cfg; u32 mi_ctrl; rkisp1_mp_disable(cap); mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL); - if (isp_fmt->fmt_type == RKISP1_FMT_BAYER) + if (v4l2_is_format_bayer(cap->pix.info)) mi_ctrl |= RKISP1_CIF_MI_CTRL_RAW_ENABLE; /* YUV */ else @@ -778,6 +738,14 @@ static void rkisp1_vb2_buf_queue(struct vb2_buffer *vb) rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB); } + /* + * uv swap can be supported for planar formats by switching + * the address of cb and cr + */ + if (cap->pix.info->comp_planes == 3 && cap->pix.cfg->uv_swap) + swap(ispbuf->buff_addr[RKISP1_PLANE_CR], + ispbuf->buff_addr[RKISP1_PLANE_CB]); + spin_lock_irqsave(&cap->buf.lock, flags); /* @@ -927,6 +895,8 @@ static void rkisp1_vb2_stop_streaming(struct vb2_queue *queue) struct rkisp1_device *rkisp1 = cap->rkisp1; int ret; + mutex_lock(&cap->rkisp1->stream_lock); + rkisp1_stream_stop(cap); media_pipeline_stop(&node->vdev.entity); ret = rkisp1_pipeline_sink_walk(&node->vdev.entity, NULL, @@ -939,10 +909,12 @@ static void rkisp1_vb2_stop_streaming(struct vb2_queue *queue) v4l2_pipeline_pm_put(&node->vdev.entity); ret = pm_runtime_put(rkisp1->dev); - if (ret) + if (ret < 0) dev_err(rkisp1->dev, "power down failed error:%d\n", ret); rkisp1_dummy_buf_destroy(cap); + + mutex_unlock(&cap->rkisp1->stream_lock); } /* @@ -987,12 +959,14 @@ rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count) struct media_entity *entity = &cap->vnode.vdev.entity; int ret; + mutex_lock(&cap->rkisp1->stream_lock); + ret = rkisp1_dummy_buf_create(cap); if (ret) goto err_ret_buffers; ret = pm_runtime_get_sync(cap->rkisp1->dev); - if (ret) { + if (ret < 0) { dev_err(cap->rkisp1->dev, "power up failed %d\n", ret); goto err_destroy_dummy; } @@ -1016,6 +990,8 @@ rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count) goto err_pipe_disable; } + mutex_unlock(&cap->rkisp1->stream_lock); + return 0; err_pipe_disable: @@ -1029,6 +1005,7 @@ err_destroy_dummy: rkisp1_dummy_buf_destroy(cap); err_ret_buffers: rkisp1_return_all_buffers(cap, VB2_BUF_STATE_QUEUED); + mutex_unlock(&cap->rkisp1->stream_lock); return ret; } @@ -1250,6 +1227,8 @@ static int rkisp1_capture_link_validate(struct media_link *link) media_entity_to_v4l2_subdev(link->source->entity); struct rkisp1_capture *cap = video_get_drvdata(vdev); struct rkisp1_isp *isp = &cap->rkisp1->isp; + u8 isp_pix_enc = isp->src_fmt->pixel_enc; + u8 cap_pix_enc = cap->pix.info->pixel_enc; struct v4l2_subdev_format sd_fmt; int ret; @@ -1260,7 +1239,9 @@ static int rkisp1_capture_link_validate(struct media_link *link) return -EPIPE; } - if (cap->pix.cfg->fmt_type != isp->src_fmt->fmt_type) { + if (cap_pix_enc != isp_pix_enc && + !(isp_pix_enc == V4L2_PIXEL_ENC_YUV && + cap_pix_enc == V4L2_PIXEL_ENC_RGB)) { dev_err(cap->rkisp1->dev, "format type mismatch in link '%s:%d->%s:%d'\n", link->source->entity->name, link->source->index, |