From fdf982794718edd8a6c4feec481fd30f619af6c6 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Sun, 25 Jul 2021 22:22:36 +0800 Subject: [PATCH] media: rockchip: isp: fbc support crop Change-Id: Idd2ddb7412870bfe7174f414463e03878eb8944f Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/capture.c | 34 ++++++++++++++----- .../media/platform/rockchip/isp/capture_v30.c | 21 ++++++++---- drivers/media/platform/rockchip/isp/regs.c | 7 +++- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/capture.c b/drivers/media/platform/rockchip/isp/capture.c index 89423487d701..cec089b55a1a 100644 --- a/drivers/media/platform/rockchip/isp/capture.c +++ b/drivers/media/platform/rockchip/isp/capture.c @@ -906,7 +906,7 @@ static int rkisp_set_fmt(struct rkisp_stream *stream, fmt = find_fmt(stream, pixm->pixelformat); if (!fmt) { - v4l2_err(&stream->ispdev->v4l2_dev, + v4l2_err(&dev->v4l2_dev, "nonsupport pixelformat:%c%c%c%c\n", pixm->pixelformat, pixm->pixelformat >> 8, @@ -924,10 +924,27 @@ static int rkisp_set_fmt(struct rkisp_stream *stream, config->min_rsz_width, max_rsz.width); pixm->height = clamp_t(u32, pixm->height, config->min_rsz_height, max_rsz.height); - } else if (stream->id == RKISP_STREAM_FBC || stream->id == RKISP_STREAM_BP) { - /* full resolution equal to isp output size */ - pixm->width = dev->isp_sdev.out_crop.width; - pixm->height = dev->isp_sdev.out_crop.height; + } else if (dev->isp_ver == ISP_V30) { + if (stream->id == RKISP_STREAM_BP && + pixm->width != dev->isp_sdev.out_crop.width && + pixm->height != dev->isp_sdev.out_crop.height) { + v4l2_warn(&dev->v4l2_dev, + "fullpath %dx%d no equal to isp output %dx%d\n", + pixm->width, pixm->height, + dev->isp_sdev.out_crop.width, + dev->isp_sdev.out_crop.height); + pixm->width = dev->isp_sdev.out_crop.width; + pixm->height = dev->isp_sdev.out_crop.height; + } else if (stream->id == RKISP_STREAM_FBC && + pixm->width != stream->dcrop.width && + pixm->height != stream->dcrop.height) { + v4l2_warn(&dev->v4l2_dev, + "fbcpatch no scale %dx%d should equal to crop %dx%d\n", + pixm->width, pixm->height, + stream->dcrop.width, stream->dcrop.height); + pixm->width = stream->dcrop.width; + pixm->height = stream->dcrop.height; + } } pixm->num_planes = fmt->mplanes; @@ -1058,14 +1075,15 @@ void rkisp_set_stream_def_fmt(struct rkisp_device *dev, u32 id, pixm.pixelformat = stream->out_isp_fmt.fourcc; if (!pixm.pixelformat) return; - pixm.width = width; - pixm.height = height; - rkisp_set_fmt(stream, &pixm, false); stream->dcrop.left = 0; stream->dcrop.top = 0; stream->dcrop.width = width; stream->dcrop.height = height; + + pixm.width = width; + pixm.height = height; + rkisp_set_fmt(stream, &pixm, false); } /************************* v4l2_file_operations***************************/ diff --git a/drivers/media/platform/rockchip/isp/capture_v30.c b/drivers/media/platform/rockchip/isp/capture_v30.c index 6fcdeb72cb4b..c091e9cfde27 100644 --- a/drivers/media/platform/rockchip/isp/capture_v30.c +++ b/drivers/media/platform/rockchip/isp/capture_v30.c @@ -73,6 +73,7 @@ struct stream_config rkisp_fbc_stream_config = { .frame_end_id = ISP3X_MI_MPFBC_FRAME, .dual_crop = { .ctrl = ISP3X_DUAL_CROP_CTRL, + .yuvmode_mask = ISP3X_DUAL_CROP_FBC_MODE, .h_offset = ISP3X_DUAL_CROP_FBC_H_OFFS, .v_offset = ISP3X_DUAL_CROP_FBC_V_OFFS, .h_size = ISP3X_DUAL_CROP_FBC_H_SIZE, @@ -89,6 +90,14 @@ struct stream_config rkisp_bp_stream_config = { .fmts = bp_fmts, .fmt_size = ARRAY_SIZE(bp_fmts), .frame_end_id = ISP3X_MI_BP_FRAME, + .dual_crop = { + .ctrl = ISP3X_DUAL_CROP_CTRL, + .yuvmode_mask = ISP3X_DUAL_CROP_FBC_MODE, + .h_offset = ISP3X_DUAL_CROP_FBC_H_OFFS, + .v_offset = ISP3X_DUAL_CROP_FBC_V_OFFS, + .h_size = ISP3X_DUAL_CROP_FBC_H_SIZE, + .v_size = ISP3X_DUAL_CROP_FBC_V_SIZE, + }, .mi = { .y_size_init = ISP3X_MI_BP_WR_Y_SIZE, .cb_size_init = ISP3X_MI_BP_WR_CB_SIZE, @@ -751,10 +760,9 @@ static void rkisp_stream_stop(struct rkisp_stream *stream) stream->stopping = false; stream->streaming = false; stream->ops->disable_mi(stream); - if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP) { - rkisp_disable_dcrop(stream, true); + rkisp_disable_dcrop(stream, true); + if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP) rkisp_disable_rsz(stream, true); - } ret = get_stream_irq_mask(stream); dev->irq_ends_mask &= ~ret; @@ -962,10 +970,6 @@ static int rkisp_stream_start(struct rkisp_stream *stream) bool async = false; int ret; - /* TODO: STREAM don't have rsz and dcrop */ - if (stream->id != RKISP_STREAM_MP && stream->id != RKISP_STREAM_SP) - goto end; - async = (stream->id == RKISP_STREAM_MP) ? dev->cap_dev.stream[RKISP_STREAM_SP].streaming : dev->cap_dev.stream[RKISP_STREAM_MP].streaming; @@ -980,6 +984,9 @@ static int rkisp_stream_start(struct rkisp_stream *stream) return ret; } + if (stream->id == RKISP_STREAM_FBC || stream->id == RKISP_STREAM_BP) + goto end; + ret = rkisp_stream_config_rsz(stream, async); if (ret < 0) { v4l2_err(v4l2_dev, "config rsz failed with error %d\n", ret); diff --git a/drivers/media/platform/rockchip/isp/regs.c b/drivers/media/platform/rockchip/isp/regs.c index 753247f4dc7c..ea449eb10fa8 100644 --- a/drivers/media/platform/rockchip/isp/regs.c +++ b/drivers/media/platform/rockchip/isp/regs.c @@ -58,8 +58,11 @@ void rkisp_config_dcrop(struct rkisp_stream *stream, struct v4l2_rect tmp = *rect; u32 reg; - if (is_unite) + if (is_unite) { tmp.width /= 2; + if (stream->id == RKISP_STREAM_FBC) + tmp.width &= ~0xf; + } reg = stream->config->dual_crop.h_offset; rkisp_write(dev, reg, tmp.left, false); reg = stream->config->dual_crop.h_size; @@ -78,6 +81,8 @@ void rkisp_config_dcrop(struct rkisp_stream *stream, reg = stream->config->dual_crop.h_offset; rkisp_next_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, false); reg = stream->config->dual_crop.h_size; + if (stream->id == RKISP_STREAM_FBC) + tmp.width = rect->width - tmp.width; rkisp_next_write(dev, reg, tmp.width, false); reg = stream->config->dual_crop.ctrl;