From 80bbd6e06d9d70871f043469e0e6ef05528be0a7 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Fri, 12 Mar 2021 16:16:34 +0800 Subject: [PATCH] media: rockchip: isp: support multi dev for isp21 Change-Id: I5973f952d0b744448025496c29a1c6b4c5316db3 Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/capture.c | 5 +- drivers/media/platform/rockchip/isp/capture.h | 1 + .../media/platform/rockchip/isp/capture_v20.c | 16 +- .../media/platform/rockchip/isp/capture_v21.c | 308 +++++++++--------- drivers/media/platform/rockchip/isp/common.c | 6 +- drivers/media/platform/rockchip/isp/csi.c | 15 +- drivers/media/platform/rockchip/isp/dmarx.c | 5 +- drivers/media/platform/rockchip/isp/hw.c | 7 +- .../platform/rockchip/isp/isp_params_v21.c | 6 +- drivers/media/platform/rockchip/isp/regs.c | 162 +++++---- drivers/media/platform/rockchip/isp/regs.h | 3 + .../media/platform/rockchip/isp/regs_v2x.h | 1 + drivers/media/platform/rockchip/isp/rkisp.c | 16 +- 13 files changed, 284 insertions(+), 267 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/capture.c b/drivers/media/platform/rockchip/isp/capture.c index 35be8b75ded9..8ace78bb0bbc 100644 --- a/drivers/media/platform/rockchip/isp/capture.c +++ b/drivers/media/platform/rockchip/isp/capture.c @@ -452,6 +452,7 @@ struct stream_config rkisp_mp_stream_config = { .y_offs_cnt_init = CIF_MI_MP_Y_OFFS_CNT_INIT, .cb_offs_cnt_init = CIF_MI_MP_CB_OFFS_CNT_INIT, .cr_offs_cnt_init = CIF_MI_MP_CR_OFFS_CNT_INIT, + .y_base_ad_shd = CIF_MI_MP_Y_BASE_AD_SHD, }, }; @@ -508,6 +509,7 @@ struct stream_config rkisp_sp_stream_config = { .y_offs_cnt_init = CIF_MI_SP_Y_OFFS_CNT_INIT, .cb_offs_cnt_init = CIF_MI_SP_CB_OFFS_CNT_INIT, .cr_offs_cnt_init = CIF_MI_SP_CR_OFFS_CNT_INIT, + .y_base_ad_shd = CIF_MI_SP_Y_BASE_AD_SHD, }, }; @@ -1013,6 +1015,7 @@ int rkisp_register_stream_vdev(struct rkisp_stream *stream) struct media_entity *source, *sink; int ret = 0, pad; + mutex_init(&stream->apilock); node = vdev_to_node(vdev); vdev->ioctl_ops = &rkisp_v4l2_ioctl_ops; @@ -1020,7 +1023,7 @@ int rkisp_register_stream_vdev(struct rkisp_stream *stream) vdev->fops = &rkisp_fops; vdev->minor = -1; vdev->v4l2_dev = v4l2_dev; - vdev->lock = &dev->apilock; + vdev->lock = &stream->apilock; vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING; video_set_drvdata(vdev, stream); diff --git a/drivers/media/platform/rockchip/isp/capture.h b/drivers/media/platform/rockchip/isp/capture.h index 8e95fe0e6b46..17b5b3c70c55 100644 --- a/drivers/media/platform/rockchip/isp/capture.h +++ b/drivers/media/platform/rockchip/isp/capture.h @@ -214,6 +214,7 @@ struct rkisp_stream { struct list_head buf_queue; struct rkisp_buffer *curr_buf; struct rkisp_buffer *next_buf; + struct mutex apilock; bool streaming; bool stopping; bool frame_end; diff --git a/drivers/media/platform/rockchip/isp/capture_v20.c b/drivers/media/platform/rockchip/isp/capture_v20.c index a2ad1c8d4549..97a08a707306 100644 --- a/drivers/media/platform/rockchip/isp/capture_v20.c +++ b/drivers/media/platform/rockchip/isp/capture_v20.c @@ -1685,21 +1685,7 @@ static void rkisp_buf_queue(struct vb2_buffer *vb) rkisp_bridge_sendtopp_buffer(stream->ispdev, stream->ispdev->dev_id, vb->index); spin_lock_irqsave(&stream->vbq_lock, lock_flags); - - /* XXX: replace dummy to speed up */ - if (stream->streaming && - !stream->next_buf && - !stream->interlaced && - stream->id != RKISP_STREAM_DMATX0 && - stream->id != RKISP_STREAM_DMATX1 && - stream->id != RKISP_STREAM_DMATX2 && - stream->id != RKISP_STREAM_DMATX3 && - atomic_read(&stream->ispdev->isp_sdev.frm_sync_seq) == 0) { - stream->next_buf = ispbuf; - stream->ops->update_mi(stream); - } else { - list_add_tail(&ispbuf->queue, &stream->buf_queue); - } + list_add_tail(&ispbuf->queue, &stream->buf_queue); spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); } diff --git a/drivers/media/platform/rockchip/isp/capture_v21.c b/drivers/media/platform/rockchip/isp/capture_v21.c index 5f7794ae30de..b6c71a240cb9 100644 --- a/drivers/media/platform/rockchip/isp/capture_v21.c +++ b/drivers/media/platform/rockchip/isp/capture_v21.c @@ -33,6 +33,18 @@ static bool is_rdbk_stream(struct rkisp_stream *stream) return en; } +static bool is_hdr_stream(struct rkisp_stream *stream) +{ + struct rkisp_device *dev = stream->ispdev; + bool en = false; + + if (stream->id == RKISP_STREAM_DMATX0 && + (dev->hdr.op_mode == HDR_FRAMEX2_DDR || + dev->hdr.op_mode == HDR_LINEX2_DDR)) + en = true; + return en; +} + /* configure dual-crop unit */ static int rkisp_stream_config_dcrop(struct rkisp_stream *stream, bool async) { @@ -147,20 +159,17 @@ static u32 calc_burst_len(struct rkisp_stream *stream) cb_offs = y_size; cr_offs = cr_size ? (cb_size + cb_offs) : 0; - if (!(cb_offs % (bus * 16)) && - !(cr_offs % (bus * 16))) + if (!(cb_offs % (bus * 16)) && !(cr_offs % (bus * 16))) burst = CIF_MI_CTRL_BURST_LEN_LUM_16 | CIF_MI_CTRL_BURST_LEN_CHROM_16; - else if (!(cb_offs % (bus * 8)) && - !(cr_offs % (bus * 8))) + else if (!(cb_offs % (bus * 8)) && !(cr_offs % (bus * 8))) burst = CIF_MI_CTRL_BURST_LEN_LUM_8 | CIF_MI_CTRL_BURST_LEN_CHROM_8; else burst = CIF_MI_CTRL_BURST_LEN_LUM_4 | CIF_MI_CTRL_BURST_LEN_CHROM_4; - if (cb_offs % (bus * 4) || - cr_offs % (bus * 4)) + if (cb_offs % (bus * 4) || cr_offs % (bus * 4)) v4l2_warn(&dev->v4l2_dev, "%dx%d fmt:0x%x not support, should be %d aligned\n", stream->out_fmt.width, @@ -169,7 +178,7 @@ static u32 calc_burst_len(struct rkisp_stream *stream) (cr_offs == 0) ? bus * 4 : bus * 16); stream->burst = burst; - for (i = 0; i < RKISP_MAX_STREAM; i++) + for (i = 0; i <= RKISP_STREAM_SP; i++) if (burst > dev->cap_dev.stream[i].burst) burst = dev->cap_dev.stream[i].burst; @@ -200,24 +209,28 @@ static u32 calc_burst_len(struct rkisp_stream *stream) */ static int mp_config_mi(struct rkisp_stream *stream) { - void __iomem *base = stream->ispdev->base_addr; + struct rkisp_device *dev = stream->ispdev; /* * NOTE: plane_fmt[0].sizeimage is total size of all planes for single * memory plane formats, so calculate the size explicitly. */ - mi_set_y_size(stream, stream->out_fmt.plane_fmt[0].bytesperline * - stream->out_fmt.height); - mi_set_cb_size(stream, stream->out_fmt.plane_fmt[1].sizeimage); - mi_set_cr_size(stream, stream->out_fmt.plane_fmt[2].sizeimage); + rkisp_write(dev, stream->config->mi.y_size_init, + stream->out_fmt.plane_fmt[0].bytesperline * + stream->out_fmt.height, false); + rkisp_write(dev, stream->config->mi.cb_size_init, + stream->out_fmt.plane_fmt[1].sizeimage, false); + rkisp_write(dev, stream->config->mi.cr_size_init, + stream->out_fmt.plane_fmt[2].sizeimage, false); + + rkisp_set_bits(dev, CIF_MI_XTD_FORMAT_CTRL, CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP, + stream->out_isp_fmt.uv_swap ? CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP : 0, false); + + rkisp_set_bits(dev, CIF_MI_CTRL, GENMASK(19, 16) | MI_CTRL_MP_FMT_MASK, + calc_burst_len(stream) | CIF_MI_CTRL_INIT_BASE_EN | + CIF_MI_CTRL_INIT_OFFSET_EN | CIF_MI_MP_AUTOUPDATE_ENABLE | + stream->out_isp_fmt.write_format, false); mi_frame_end_int_enable(stream); - if (stream->out_isp_fmt.uv_swap) - mp_set_uv_swap(base); - - config_mi_ctrl(stream, calc_burst_len(stream)); - mp_mi_ctrl_set_format(base, stream->out_isp_fmt.write_format); - mp_mi_ctrl_autoupdate_en(base); - /* set up first buffer */ mi_frame_end(stream); return 0; @@ -252,12 +265,11 @@ static int mbus_code_sp_in_fmt(u32 in_mbus_code, u32 out_fourcc, u32 *format) */ static int sp_config_mi(struct rkisp_stream *stream) { - void __iomem *base = stream->ispdev->base_addr; struct rkisp_device *dev = stream->ispdev; struct capture_fmt *output_isp_fmt = &stream->out_isp_fmt; struct ispsd_out_fmt *input_isp_fmt = rkisp_get_ispsd_out_fmt(&dev->isp_sdev); - u32 sp_in_fmt; + u32 sp_in_fmt, mul = 1; if (mbus_code_sp_in_fmt(input_isp_fmt->mbus_code, output_isp_fmt->fourcc, &sp_in_fmt)) { @@ -269,32 +281,30 @@ static int sp_config_mi(struct rkisp_stream *stream) * NOTE: plane_fmt[0].sizeimage is total size of all planes for single * memory plane formats, so calculate the size explicitly. */ - mi_set_y_size(stream, stream->out_fmt.plane_fmt[0].bytesperline * - stream->out_fmt.height); - mi_set_cb_size(stream, stream->out_fmt.plane_fmt[1].sizeimage); - mi_set_cr_size(stream, stream->out_fmt.plane_fmt[2].sizeimage); - - sp_set_y_width(base, stream->out_fmt.width); + rkisp_write(dev, stream->config->mi.y_size_init, + stream->out_fmt.plane_fmt[0].bytesperline * + stream->out_fmt.height, false); + rkisp_write(dev, stream->config->mi.cb_size_init, + stream->out_fmt.plane_fmt[1].sizeimage, false); + rkisp_write(dev, stream->config->mi.cr_size_init, + stream->out_fmt.plane_fmt[2].sizeimage, false); + rkisp_write(dev, CIF_MI_SP_Y_PIC_WIDTH, stream->out_fmt.width, false); if (stream->interlaced) { - stream->u.sp.vir_offs = - stream->out_fmt.plane_fmt[0].bytesperline; - sp_set_y_height(base, stream->out_fmt.height / 2); - sp_set_y_line_length(base, stream->u.sp.y_stride * 2); - } else { - sp_set_y_height(base, stream->out_fmt.height); - sp_set_y_line_length(base, stream->u.sp.y_stride); + mul = 2; + stream->u.sp.vir_offs = stream->out_fmt.plane_fmt[0].bytesperline; } + rkisp_write(dev, CIF_MI_SP_Y_PIC_HEIGHT, stream->out_fmt.height / mul, false); + rkisp_write(dev, CIF_MI_SP_Y_LLENGTH, stream->u.sp.y_stride * mul, false); + rkisp_set_bits(dev, CIF_MI_XTD_FORMAT_CTRL, CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP, + output_isp_fmt->uv_swap ? CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP : 0, false); + + rkisp_set_bits(dev, CIF_MI_CTRL, GENMASK(19, 16) | MI_CTRL_SP_FMT_MASK, + calc_burst_len(stream) | CIF_MI_CTRL_INIT_BASE_EN | + CIF_MI_CTRL_INIT_OFFSET_EN | stream->out_isp_fmt.write_format | + sp_in_fmt | output_isp_fmt->output_format | + CIF_MI_SP_AUTOUPDATE_ENABLE, false); mi_frame_end_int_enable(stream); - if (output_isp_fmt->uv_swap) - sp_set_uv_swap(base); - - config_mi_ctrl(stream, calc_burst_len(stream)); - sp_mi_ctrl_set_format(base, stream->out_isp_fmt.write_format | - sp_in_fmt | output_isp_fmt->output_format); - - sp_mi_ctrl_autoupdate_en(base); - /* set up first buffer */ mi_frame_end(stream); return 0; @@ -308,8 +318,7 @@ static int dmatx3_config_mi(struct rkisp_stream *stream) u32 in_size; u8 vc; - if (!csi->sink[CSI_SRC_CH4 - 1].linked || - stream->streaming) + if (!csi->sink[CSI_SRC_CH4 - 1].linked || stream->streaming) return -EBUSY; if (!dev->active_sensor || @@ -325,17 +334,17 @@ static int dmatx3_config_mi(struct rkisp_stream *stream) stream->out_fmt.width, stream->out_fmt.height); raw_wr_set_pic_offs(stream, 0); - - vc = csi->sink[CSI_SRC_CH4 - 1].index; - raw_wr_ctrl(stream, - SW_CSI_RAW_WR_CH_EN(vc) | - csi->memory | - SW_CSI_RAW_WR_EN_ORG); mi_set_y_size(stream, in_size); mi_frame_end(stream); mi_frame_end_int_enable(stream); mi_wr_ctrl2(base, SW_RAW3_WR_AUTOUPD); mi_raw_length(stream); + vc = csi->sink[CSI_SRC_CH4 - 1].index; + raw_wr_ctrl(stream, + SW_CSI_RAW_WR_CH_EN(vc) | + csi->memory | + SW_CSI_RAW_WR_EN_ORG); + stream->u.dmatx.is_config = true; v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "rawwr3 %dx%d ctrl:0x%x\n", stream->out_fmt.width, @@ -352,8 +361,7 @@ static int dmatx2_config_mi(struct rkisp_stream *stream) u32 val, in_size; u8 vc; - if (!csi->sink[CSI_SRC_CH3 - 1].linked || - stream->streaming) + if (!csi->sink[CSI_SRC_CH3 - 1].linked || stream->streaming) return -EBUSY; if (!dev->active_sensor || @@ -365,24 +373,24 @@ static int dmatx2_config_mi(struct rkisp_stream *stream) } if (!stream->u.dmatx.is_config) { + stream->u.dmatx.is_config = true; atomic_set(&stream->sequence, 0); in_size = stream->out_fmt.plane_fmt[0].sizeimage; raw_wr_set_pic_size(stream, stream->out_fmt.width, stream->out_fmt.height); raw_wr_set_pic_offs(stream, 0); + mi_set_y_size(stream, in_size); + mi_frame_end(stream); + mi_frame_end_int_enable(stream); + mi_wr_ctrl2(base, SW_RAW1_WR_AUTOUPD); + mi_raw_length(stream); vc = csi->sink[CSI_SRC_CH3 - 1].index; val = SW_CSI_RAW_WR_CH_EN(vc); val |= csi->memory; if (dev->hdr.op_mode != HDR_NORMAL) val |= SW_CSI_RAW_WR_EN_ORG; raw_wr_ctrl(stream, val); - mi_set_y_size(stream, in_size); - mi_frame_end(stream); - mi_frame_end_int_enable(stream); - mi_wr_ctrl2(base, SW_RAW1_WR_AUTOUPD); - mi_raw_length(stream); - stream->u.dmatx.is_config = true; } return 0; } @@ -392,13 +400,10 @@ static int dmatx0_config_mi(struct rkisp_stream *stream) void __iomem *base = stream->ispdev->base_addr; struct rkisp_device *dev = stream->ispdev; struct rkisp_csi_device *csi = &dev->csi_dev; - struct rkisp_stream *dmatx = - &dev->cap_dev.stream[RKISP_STREAM_DMATX0]; u32 val, in_size; u8 vc; - if (!csi->sink[CSI_SRC_CH1 - 1].linked || - dmatx->streaming) + if (!csi->sink[CSI_SRC_CH1 - 1].linked || stream->streaming) return -EBUSY; if (!dev->active_sensor || @@ -410,27 +415,25 @@ static int dmatx0_config_mi(struct rkisp_stream *stream) return -EINVAL; } - in_size = dmatx->out_fmt.plane_fmt[0].sizeimage; if (!stream->u.dmatx.is_config) { - if (dmatx->u.dmatx.is_config) - return 0; - atomic_set(&dmatx->sequence, 0); - raw_wr_set_pic_size(dmatx, - dmatx->out_fmt.width, - dmatx->out_fmt.height); - raw_wr_set_pic_offs(dmatx, 0); + stream->u.dmatx.is_config = true; + atomic_set(&stream->sequence, 0); + in_size = stream->out_fmt.plane_fmt[0].sizeimage; + raw_wr_set_pic_size(stream, + stream->out_fmt.width, + stream->out_fmt.height); + raw_wr_set_pic_offs(stream, 0); + mi_set_y_size(stream, in_size); + mi_frame_end(stream); + mi_frame_end_int_enable(stream); + mi_wr_ctrl2(base, SW_RAW0_WR_AUTOUPD); + mi_raw_length(stream); vc = csi->sink[CSI_SRC_CH1 - 1].index; val = SW_CSI_RAW_WR_CH_EN(vc); val |= csi->memory; if (dev->hdr.op_mode != HDR_NORMAL) val |= SW_CSI_RAW_WR_EN_ORG; - raw_wr_ctrl(dmatx, val); - mi_set_y_size(dmatx, in_size); - mi_frame_end(dmatx); - mi_frame_end_int_enable(dmatx); - mi_wr_ctrl2(base, SW_RAW0_WR_AUTOUPD); - mi_raw_length(stream); - dmatx->u.dmatx.is_config = true; + raw_wr_ctrl(stream, val); } return 0; @@ -438,21 +441,19 @@ static int dmatx0_config_mi(struct rkisp_stream *stream) static void mp_enable_mi(struct rkisp_stream *stream) { - void __iomem *base = stream->ispdev->base_addr; struct capture_fmt *isp_fmt = &stream->out_isp_fmt; + u32 val = CIF_MI_CTRL_MP_ENABLE; - mi_ctrl_mp_disable(base); if (isp_fmt->fmt_type == FMT_BAYER) - mi_ctrl_mpraw_enable(base); - else if (isp_fmt->fmt_type == FMT_YUV) - mi_ctrl_mpyuv_enable(base); + val = CIF_MI_CTRL_RAW_ENABLE; + rkisp_set_bits(stream->ispdev, CIF_MI_CTRL, + CIF_MI_CTRL_MP_ENABLE | CIF_MI_CTRL_RAW_ENABLE, val, false); } static void sp_enable_mi(struct rkisp_stream *stream) { - void __iomem *base = stream->ispdev->base_addr; - - mi_ctrl_spyuv_enable(base); + rkisp_set_bits(stream->ispdev, CIF_MI_CTRL, 0, + CIF_MI_CTRL_SP_ENABLE, false); } static void dmatx_enable_mi(struct rkisp_stream *stream) @@ -462,29 +463,23 @@ static void dmatx_enable_mi(struct rkisp_stream *stream) static void mp_disable_mi(struct rkisp_stream *stream) { - struct rkisp_device *dev = stream->ispdev; - void __iomem *base = dev->base_addr; - - mi_ctrl_mp_disable(base); + rkisp_clear_bits(stream->ispdev, CIF_MI_CTRL, + CIF_MI_CTRL_MP_ENABLE | CIF_MI_CTRL_RAW_ENABLE, false); } static void sp_disable_mi(struct rkisp_stream *stream) { - void __iomem *base = stream->ispdev->base_addr; - - mi_ctrl_spyuv_disable(base); + rkisp_clear_bits(stream->ispdev, CIF_MI_CTRL, CIF_MI_CTRL_SP_ENABLE, false); } static void update_dmatx_v2(struct rkisp_stream *stream) { struct rkisp_device *dev = stream->ispdev; - void __iomem *base = dev->base_addr; struct rkisp_dummy_buffer *buf = NULL; u8 index; if (stream->next_buf) { - mi_set_y_addr(stream, - stream->next_buf->buff_addr[RKISP_PLANE_Y]); + mi_set_y_addr(stream, stream->next_buf->buff_addr[RKISP_PLANE_Y]); } else { if (stream->id == RKISP_STREAM_DMATX0) index = dev->hdr.index[HDR_DMA0]; @@ -508,56 +503,59 @@ static void update_dmatx_v2(struct rkisp_stream *stream) v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, "%s stream:%d Y:0x%x SHD:0x%x\n", __func__, stream->id, - readl(base + stream->config->mi.y_base_ad_init), - readl(base + stream->config->mi.y_base_ad_shd)); + rkisp_read(dev, stream->config->mi.y_base_ad_init, true), + rkisp_read(dev, stream->config->mi.y_base_ad_shd, true)); } /* Update buffer info to memory interface, it's called in interrupt */ static void update_mi(struct rkisp_stream *stream) { struct rkisp_dummy_buffer *dummy_buf = &stream->ispdev->hw_dev->dummy_buf; - void __iomem *base = stream->ispdev->base_addr; + struct rkisp_device *dev = stream->ispdev; /* The dummy space allocated by dma_alloc_coherent is used, we can * throw data to it if there is no available buffer. */ if (stream->next_buf) { - mi_set_y_addr(stream, - stream->next_buf->buff_addr[RKISP_PLANE_Y]); - mi_set_cb_addr(stream, - stream->next_buf->buff_addr[RKISP_PLANE_CB]); - mi_set_cr_addr(stream, - stream->next_buf->buff_addr[RKISP_PLANE_CR]); + rkisp_write(dev, stream->config->mi.y_base_ad_init, + stream->next_buf->buff_addr[RKISP_PLANE_Y], false); + rkisp_write(dev, stream->config->mi.cb_base_ad_init, + stream->next_buf->buff_addr[RKISP_PLANE_CB], false); + rkisp_write(dev, stream->config->mi.cr_base_ad_init, + stream->next_buf->buff_addr[RKISP_PLANE_CR], false); + /* mp/sp single buf updated at readback for multidevice */ + if (!dev->hw_dev->is_single) { + stream->curr_buf = stream->next_buf; + stream->next_buf = NULL; + } } else if (dummy_buf->mem_priv) { - mi_set_y_addr(stream, dummy_buf->dma_addr); - mi_set_cb_addr(stream, dummy_buf->dma_addr); - mi_set_cr_addr(stream, dummy_buf->dma_addr); + rkisp_write(dev, stream->config->mi.y_base_ad_init, + dummy_buf->dma_addr, false); + rkisp_write(dev, stream->config->mi.cb_base_ad_init, + dummy_buf->dma_addr, false); + rkisp_write(dev, stream->config->mi.cr_base_ad_init, + dummy_buf->dma_addr, false); } mi_set_y_offset(stream, 0); mi_set_cb_offset(stream, 0); mi_set_cr_offset(stream, 0); v4l2_dbg(2, rkisp_debug, &stream->ispdev->v4l2_dev, - "%s stream:%d Y:0x%x CB:0x%x CR:0x%x\n", + "%s stream:%d Y:0x%x CB:0x%x CR:0x%x | Y_SHD:0x%x\n", __func__, stream->id, - readl(base + stream->config->mi.y_base_ad_init), - readl(base + stream->config->mi.cb_base_ad_init), - readl(base + stream->config->mi.cr_base_ad_init)); + rkisp_read(dev, stream->config->mi.y_base_ad_init, false), + rkisp_read(dev, stream->config->mi.cb_base_ad_init, false), + rkisp_read(dev, stream->config->mi.cr_base_ad_init, false), + rkisp_read(dev, stream->config->mi.y_base_ad_shd, true)); } static void mp_stop_mi(struct rkisp_stream *stream) { - if (!stream->streaming) - return; - mi_frame_end_int_clear(stream); stream->ops->disable_mi(stream); } static void sp_stop_mi(struct rkisp_stream *stream) { - if (!stream->streaming) - return; - mi_frame_end_int_clear(stream); stream->ops->disable_mi(stream); } @@ -819,20 +817,21 @@ static void rkisp_stream_stop(struct rkisp_stream *stream) int ret = 0; if (!dev->dmarx_dev.trigger && - is_rdbk_stream(stream)) { + (is_rdbk_stream(stream) || is_hdr_stream(stream))) { stream->streaming = false; return; } stream->stopping = true; - stream->ops->stop_mi(stream); - if (atomic_read(&dev->cap_dev.refcnt) == 1) + if ((!dev->hw_dev->is_single && stream->id != RKISP_STREAM_MP && + stream->id != RKISP_STREAM_SP) || dev->hw_dev->is_single) + stream->ops->stop_mi(stream); + if (atomic_read(&dev->cap_dev.refcnt) == 1) hdr_stop_dmatx(dev); - if ((dev->isp_state & ISP_START) && - dev->isp_inp != INP_DMARX_ISP) { + if (dev->isp_state & ISP_START) { ret = wait_event_timeout(stream->done, !stream->streaming, - msecs_to_jiffies(1000)); + msecs_to_jiffies(500)); if (!ret) v4l2_warn(v4l2_dev, "%s id:%d timeout\n", __func__, stream->id); @@ -840,9 +839,8 @@ static void rkisp_stream_stop(struct rkisp_stream *stream) stream->stopping = false; stream->streaming = false; - - if (stream->id == RKISP_STREAM_MP || - stream->id == RKISP_STREAM_SP) { + if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP) { + stream->ops->disable_mi(stream); rkisp_disable_dcrop(stream, true); rkisp_disable_rsz(stream, true); ret = (stream->id == RKISP_STREAM_MP) ? @@ -869,8 +867,7 @@ static int rkisp_start(struct rkisp_stream *stream) bool is_update = false; int ret; - if (stream->id == RKISP_STREAM_MP || - stream->id == RKISP_STREAM_SP) { + if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP) { is_update = (stream->id == RKISP_STREAM_MP) ? !dev->cap_dev.stream[RKISP_STREAM_SP].streaming : !dev->cap_dev.stream[RKISP_STREAM_MP].streaming; @@ -895,12 +892,17 @@ static int rkisp_start(struct rkisp_stream *stream) if (is_update) { rkisp_stats_first_ddr_config(&dev->stats_vdev); hdr_config_dmatx(dev); - force_cfg_update(dev); - mi_frame_end(stream); - hdr_update_dmatx_buf(dev); dev->irq_ends_mask |= (stream->id == RKISP_STREAM_MP) ? ISP_FRAME_MP : ISP_FRAME_SP; } + mutex_lock(&dev->hw_dev->dev_lock); + if (!dev->hw_dev->is_mi_update && is_update) { + force_cfg_update(dev); + if (dev->hw_dev->is_single) + mi_frame_end(stream); + hdr_update_dmatx_buf(dev); + } + mutex_unlock(&dev->hw_dev->dev_lock); stream->streaming = true; return 0; @@ -988,21 +990,7 @@ static void rkisp_buf_queue(struct vb2_buffer *vb) stream->id, ispbuf->buff_addr[0]); spin_lock_irqsave(&stream->vbq_lock, lock_flags); - - /* XXX: replace dummy to speed up */ - if (stream->streaming && - !stream->next_buf && - !stream->interlaced && - stream->id != RKISP_STREAM_DMATX0 && - stream->id != RKISP_STREAM_DMATX1 && - stream->id != RKISP_STREAM_DMATX2 && - stream->id != RKISP_STREAM_DMATX3 && - atomic_read(&stream->ispdev->isp_sdev.frm_sync_seq) == 0) { - stream->next_buf = ispbuf; - stream->ops->update_mi(stream); - } else { - list_add_tail(&ispbuf->queue, &stream->buf_queue); - } + list_add_tail(&ispbuf->queue, &stream->buf_queue); spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); } @@ -1073,11 +1061,15 @@ static void rkisp_stop_streaming(struct vb2_queue *queue) struct v4l2_device *v4l2_dev = &dev->v4l2_dev; int ret; + mutex_lock(&dev->apilock); + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "%s %d\n", __func__, stream->id); - if (!stream->streaming) + if (!stream->streaming) { + mutex_unlock(&dev->apilock); return; + } rkisp_stream_stop(stream); if (stream->id == RKISP_STREAM_MP || @@ -1098,6 +1090,8 @@ static void rkisp_stop_streaming(struct vb2_queue *queue) v4l2_err(v4l2_dev, "pipeline close failed error:%d\n", ret); rkisp_destroy_dummy_buf(stream); atomic_dec(&dev->cap_dev.refcnt); + + mutex_unlock(&dev->apilock); } static int rkisp_stream_start(struct rkisp_stream *stream) @@ -1147,11 +1141,15 @@ rkisp_start_streaming(struct vb2_queue *queue, unsigned int count) struct v4l2_device *v4l2_dev = &dev->v4l2_dev; int ret = -1; + mutex_lock(&dev->apilock); + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "%s %d\n", __func__, stream->id); - if (WARN_ON(stream->streaming)) + if (WARN_ON(stream->streaming)) { + mutex_unlock(&dev->apilock); return -EBUSY; + } atomic_inc(&dev->cap_dev.refcnt); if (!dev->isp_inp || !stream->linked) { @@ -1213,6 +1211,7 @@ rkisp_start_streaming(struct vb2_queue *queue, unsigned int count) } } + mutex_unlock(&dev->apilock); return 0; pipe_stream_off: @@ -1227,6 +1226,7 @@ buffer_done: destroy_buf_queue(stream, VB2_BUF_STATE_QUEUED); atomic_dec(&dev->cap_dev.refcnt); stream->streaming = false; + mutex_unlock(&dev->apilock); return ret; } @@ -1251,7 +1251,7 @@ static int rkisp_init_vb2_queue(struct vb2_queue *q, q->buf_struct_size = sizeof(struct rkisp_buffer); q->min_buffers_needed = CIF_ISP_REQ_BUFS_MIN; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - q->lock = &stream->ispdev->apilock; + q->lock = &stream->apilock; q->dev = stream->ispdev->hw_dev->dev; q->allow_cache_hints = 1; q->bidirectional = 1; @@ -1413,7 +1413,13 @@ void rkisp_mi_v21_isr(u32 mis_val, struct rkisp_device *dev) * frame end that sync the configurations to shadow * regs. */ - if (stream->ops->is_stream_stopped(dev->base_addr)) { + if (!dev->hw_dev->is_single && + (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP)) { + stream->stopping = false; + stream->streaming = false; + stream->ops->disable_mi(stream); + wake_up(&stream->done); + } else if (stream->ops->is_stream_stopped(dev->base_addr)) { stream->stopping = false; stream->streaming = false; wake_up(&stream->done); diff --git a/drivers/media/platform/rockchip/isp/common.c b/drivers/media/platform/rockchip/isp/common.c index d0a6d5d23eb1..3fd2af6329e7 100644 --- a/drivers/media/platform/rockchip/isp/common.c +++ b/drivers/media/platform/rockchip/isp/common.c @@ -232,8 +232,8 @@ static int rkisp_alloc_page_dummy_buf(struct rkisp_device *dev, u32 size) dummy_buf->mem_priv = sg; dummy_buf->pages = pages; v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, - "%s buf:0x%x map cnt:%d\n", __func__, - (u32)dummy_buf->dma_addr, ret); + "%s buf:0x%x map cnt:%d size:%d\n", __func__, + (u32)dummy_buf->dma_addr, ret, size); return 0; free_sg: kfree(sg); @@ -274,6 +274,8 @@ int rkisp_alloc_common_dummy_buf(struct rkisp_device *dev) if (dummy_buf->mem_priv) goto end; + if (hw->max_in.w && hw->max_in.h) + size = hw->max_in.w * hw->max_in.h * 2; for (i = 0; i < hw->dev_num; i++) { isp = hw->isp[i]; for (j = 0; j < RKISP_MAX_STREAM; j++) { diff --git a/drivers/media/platform/rockchip/isp/csi.c b/drivers/media/platform/rockchip/isp/csi.c index 39168bf18392..d72213bbb4b9 100644 --- a/drivers/media/platform/rockchip/isp/csi.c +++ b/drivers/media/platform/rockchip/isp/csi.c @@ -566,8 +566,21 @@ void rkisp_trigger_read_back(struct rkisp_csi_device *csi, u8 dma2frm, u32 mode) rkisp_update_regs(dev, CTRL_VI_ISP_PATH, SUPER_IMP_COLOR_CR); rkisp_update_regs(dev, DUAL_CROP_M_H_OFFS, DUAL_CROP_S_V_SIZE); rkisp_update_regs(dev, ISP_ACQ_PROP, DUAL_CROP_CTRL); - rkisp_update_regs(dev, ISP_GAMMA_OUT_CTRL, ISP_LSC_CTRL); + rkisp_update_regs(dev, MAIN_RESIZE_SCALE_HY, MI_WR_CTRL); + rkisp_update_regs(dev, SELF_RESIZE_SCALE_HY, MAIN_RESIZE_CTRL); + rkisp_update_regs(dev, ISP_GAMMA_OUT_CTRL, SELF_RESIZE_CTRL); + rkisp_update_regs(dev, MI_RD_CTRL2, ISP_LSC_CTRL); + rkisp_update_regs(dev, MI_MP_WR_Y_BASE, MI_MP_WR_Y_LLENGTH); rkisp_update_regs(dev, ISP_LSC_XGRAD_01, ISP_RAWAWB_RAM_DATA); + if (dev->isp_ver == ISP_V21) { + val = rkisp_read(dev, MI_WR_CTRL2, false); + rkisp_set_bits(dev, MI_WR_CTRL2, 0, val, true); + rkisp_write(dev, MI_WR_INIT, ISP21_SP_FORCE_UPD | ISP21_MP_FORCE_UPD, true); + /* sensor mode & index */ + rkisp_set_bits(dev, ISP_ACQ_H_OFFS, ISP21_SENSOR_MODE(3) | ISP21_SENSOR_INDEX(3), + ISP21_SENSOR_MODE(hw->dev_num >= 3 ? 2 : hw->dev_num - 1) | + ISP21_SENSOR_INDEX(dev->dev_id), true); + } is_upd = true; } diff --git a/drivers/media/platform/rockchip/isp/dmarx.c b/drivers/media/platform/rockchip/isp/dmarx.c index e8e5dbf40e09..50ef1475c505 100644 --- a/drivers/media/platform/rockchip/isp/dmarx.c +++ b/drivers/media/platform/rockchip/isp/dmarx.c @@ -612,7 +612,7 @@ static int rkisp_init_vb2_queue(struct vb2_queue *q, q->buf_struct_size = sizeof(struct rkisp_buffer); q->min_buffers_needed = CIF_ISP_REQ_BUFS_MIN; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - q->lock = &stream->ispdev->apilock; + q->lock = &stream->apilock; q->dev = stream->ispdev->hw_dev->dev; q->allow_cache_hints = 1; q->bidirectional = 1; @@ -817,13 +817,14 @@ static int rkisp_register_dmarx_video(struct rkisp_stream *stream) struct rkisp_vdev_node *node; int ret = 0; + mutex_init(&stream->apilock); node = vdev_to_node(vdev); vdev->release = video_device_release_empty; vdev->fops = &rkisp_fops; vdev->minor = -1; vdev->v4l2_dev = v4l2_dev; - vdev->lock = &dev->apilock; + vdev->lock = &stream->apilock; video_set_drvdata(vdev, stream); vdev->ioctl_ops = &rkisp_dmarx_ioctl; diff --git a/drivers/media/platform/rockchip/isp/hw.c b/drivers/media/platform/rockchip/isp/hw.c index 494f899bf96f..06102e44940f 100644 --- a/drivers/media/platform/rockchip/isp/hw.c +++ b/drivers/media/platform/rockchip/isp/hw.c @@ -647,7 +647,12 @@ static int rkisp_hw_probe(struct platform_device *pdev) hw_dev->dev = dev; hw_dev->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP); dev_info(dev, "is_thunderboot: %d\n", hw_dev->is_thunderboot); - + hw_dev->max_in.w = 0; + hw_dev->max_in.h = 0; + hw_dev->max_in.fps = 0; + of_property_read_u32_array(node, "max-input", &hw_dev->max_in.w, 3); + dev_info(dev, "max input:%dx%d@%dfps\n", + hw_dev->max_in.w, hw_dev->max_in.h, hw_dev->max_in.fps); hw_dev->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf"); if (IS_ERR(hw_dev->grf)) dev_warn(dev, "Missing rockchip,grf property\n"); diff --git a/drivers/media/platform/rockchip/isp/isp_params_v21.c b/drivers/media/platform/rockchip/isp/isp_params_v21.c index 8d2a92d96f71..626ae17fe4c7 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v21.c @@ -3910,7 +3910,10 @@ rkisp_params_first_cfg_v2x(struct rkisp_isp_params_vdev *params_vdev) (struct rkisp_isp_params_v21_ops *)params_vdev->priv_ops; struct rkisp_isp_params_val_v21 *priv_val = (struct rkisp_isp_params_val_v21 *)params_vdev->priv_val; + struct rkisp_hw_dev *hw = params_vdev->dev->hw_dev; struct v4l2_rect *out_crop = ¶ms_vdev->dev->isp_sdev.out_crop; + u32 width = hw->max_in.w ? hw->max_in.w : out_crop->width; + u32 size = hw->max_in.w ? hw->max_in.w * hw->max_in.h : isp_param_get_insize(params_vdev); rkisp_alloc_bay3d_buf(params_vdev, params_vdev->isp21_params); spin_lock(¶ms_vdev->config_lock); @@ -3933,8 +3936,7 @@ rkisp_params_first_cfg_v2x(struct rkisp_isp_params_vdev *params_vdev) __isp_isr_other_config(params_vdev, params_vdev->isp21_params, RKISP_PARAMS_ALL); __isp_isr_meas_config(params_vdev, params_vdev->isp21_params, RKISP_PARAMS_ALL); __preisp_isr_update_hdrae_para(params_vdev, params_vdev->isp21_params); - if (out_crop->width <= ISP2X_AUTO_BIGMODE_WIDTH && - isp_param_get_insize(params_vdev) > ISP2X_NOBIG_OVERFLOW_SIZE) { + if (width <= ISP2X_AUTO_BIGMODE_WIDTH && size > ISP2X_NOBIG_OVERFLOW_SIZE) { rkisp_set_bits(params_vdev->dev, ISP_CTRL1, ISP2X_SYS_BIGMODE_MANUAL | ISP2X_SYS_BIGMODE_FORCEEN, ISP2X_SYS_BIGMODE_MANUAL | ISP2X_SYS_BIGMODE_FORCEEN, false); diff --git a/drivers/media/platform/rockchip/isp/regs.c b/drivers/media/platform/rockchip/isp/regs.c index e6f4457be172..766bcbe36839 100644 --- a/drivers/media/platform/rockchip/isp/regs.c +++ b/drivers/media/platform/rockchip/isp/regs.c @@ -37,97 +37,90 @@ void rkisp_disable_dcrop(struct rkisp_stream *stream, bool async) { - void __iomem *base = stream->ispdev->base_addr; - void __iomem *dc_ctrl_addr = base + stream->config->dual_crop.ctrl; - u32 dc_ctrl = readl(dc_ctrl_addr); - u32 mask = ~(stream->config->dual_crop.yuvmode_mask | - stream->config->dual_crop.rawmode_mask); - u32 val = dc_ctrl & mask; + struct rkisp_device *dev = stream->ispdev; + u32 mask = stream->config->dual_crop.yuvmode_mask | + stream->config->dual_crop.rawmode_mask; + u32 val = CIF_DUAL_CROP_CFG_UPD; - if (async) - val |= CIF_DUAL_CROP_GEN_CFG_UPD; - else - val |= CIF_DUAL_CROP_CFG_UPD; - writel(val, dc_ctrl_addr); + if (async && dev->hw_dev->is_single) + val = CIF_DUAL_CROP_GEN_CFG_UPD; + rkisp_set_bits(dev, stream->config->dual_crop.ctrl, mask, val, false); } void rkisp_config_dcrop(struct rkisp_stream *stream, struct v4l2_rect *rect, bool async) { - void __iomem *base = stream->ispdev->base_addr; - void __iomem *dc_ctrl_addr = base + stream->config->dual_crop.ctrl; - u32 dc_ctrl = readl(dc_ctrl_addr); + struct rkisp_device *dev = stream->ispdev; + u32 val = stream->config->dual_crop.yuvmode_mask; - writel(rect->left, base + stream->config->dual_crop.h_offset); - writel(rect->top, base + stream->config->dual_crop.v_offset); - writel(rect->width, base + stream->config->dual_crop.h_size); - writel(rect->height, base + stream->config->dual_crop.v_size); - dc_ctrl |= stream->config->dual_crop.yuvmode_mask; - if (async) - dc_ctrl |= CIF_DUAL_CROP_GEN_CFG_UPD; + rkisp_write(dev, stream->config->dual_crop.h_offset, rect->left, false); + rkisp_write(dev, stream->config->dual_crop.v_offset, rect->top, false); + rkisp_write(dev, stream->config->dual_crop.h_size, rect->width, false); + rkisp_write(dev, stream->config->dual_crop.v_size, rect->height, false); + if (async && dev->hw_dev->is_single) + val |= CIF_DUAL_CROP_GEN_CFG_UPD; else - dc_ctrl |= CIF_DUAL_CROP_CFG_UPD; - writel(dc_ctrl, dc_ctrl_addr); + val |= CIF_DUAL_CROP_CFG_UPD; + rkisp_set_bits(dev, stream->config->dual_crop.ctrl, 0, val, false); } void rkisp_dump_rsz_regs(struct rkisp_stream *stream) { - void __iomem *base = stream->ispdev->base_addr; + struct rkisp_device *dev = stream->ispdev; pr_info("RSZ_CTRL 0x%08x/0x%08x\n" - "RSZ_SCALE_HY %d/%d\n" - "RSZ_SCALE_HCB %d/%d\n" - "RSZ_SCALE_HCR %d/%d\n" - "RSZ_SCALE_VY %d/%d\n" - "RSZ_SCALE_VC %d/%d\n" - "RSZ_PHASE_HY %d/%d\n" - "RSZ_PHASE_HC %d/%d\n" - "RSZ_PHASE_VY %d/%d\n" - "RSZ_PHASE_VC %d/%d\n", - readl(base + stream->config->rsz.ctrl), - readl(base + stream->config->rsz.ctrl_shd), - readl(base + stream->config->rsz.scale_hy), - readl(base + stream->config->rsz.scale_hy_shd), - readl(base + stream->config->rsz.scale_hcb), - readl(base + stream->config->rsz.scale_hcb_shd), - readl(base + stream->config->rsz.scale_hcr), - readl(base + stream->config->rsz.scale_hcr_shd), - readl(base + stream->config->rsz.scale_vy), - readl(base + stream->config->rsz.scale_vy_shd), - readl(base + stream->config->rsz.scale_vc), - readl(base + stream->config->rsz.scale_vc_shd), - readl(base + stream->config->rsz.phase_hy), - readl(base + stream->config->rsz.phase_hy_shd), - readl(base + stream->config->rsz.phase_hc), - readl(base + stream->config->rsz.phase_hc_shd), - readl(base + stream->config->rsz.phase_vy), - readl(base + stream->config->rsz.phase_vy_shd), - readl(base + stream->config->rsz.phase_vc), - readl(base + stream->config->rsz.phase_vc_shd)); + "RSZ_SCALE_HY %d/%d\n" + "RSZ_SCALE_HCB %d/%d\n" + "RSZ_SCALE_HCR %d/%d\n" + "RSZ_SCALE_VY %d/%d\n" + "RSZ_SCALE_VC %d/%d\n" + "RSZ_PHASE_HY %d/%d\n" + "RSZ_PHASE_HC %d/%d\n" + "RSZ_PHASE_VY %d/%d\n" + "RSZ_PHASE_VC %d/%d\n", + rkisp_read(dev, stream->config->rsz.ctrl, false), + rkisp_read(dev, stream->config->rsz.ctrl_shd, true), + rkisp_read(dev, stream->config->rsz.scale_hy, false), + rkisp_read(dev, stream->config->rsz.scale_hy_shd, true), + rkisp_read(dev, stream->config->rsz.scale_hcb, false), + rkisp_read(dev, stream->config->rsz.scale_hcb_shd, true), + rkisp_read(dev, stream->config->rsz.scale_hcr, false), + rkisp_read(dev, stream->config->rsz.scale_hcr_shd, true), + rkisp_read(dev, stream->config->rsz.scale_vy, false), + rkisp_read(dev, stream->config->rsz.scale_vy_shd, true), + rkisp_read(dev, stream->config->rsz.scale_vc, false), + rkisp_read(dev, stream->config->rsz.scale_vc_shd, true), + rkisp_read(dev, stream->config->rsz.phase_hy, false), + rkisp_read(dev, stream->config->rsz.phase_hy_shd, true), + rkisp_read(dev, stream->config->rsz.phase_hc, false), + rkisp_read(dev, stream->config->rsz.phase_hc_shd, true), + rkisp_read(dev, stream->config->rsz.phase_vy, false), + rkisp_read(dev, stream->config->rsz.phase_vy_shd, true), + rkisp_read(dev, stream->config->rsz.phase_vc, false), + rkisp_read(dev, stream->config->rsz.phase_vc_shd, true)); } static void update_rsz_shadow(struct rkisp_stream *stream, bool async) { - void *addr = stream->ispdev->base_addr + stream->config->rsz.ctrl; - u32 ctrl_cfg = readl(addr); + struct rkisp_device *dev = stream->ispdev; + u32 val = CIF_RSZ_CTRL_CFG_UPD; - if (async) - writel(CIF_RSZ_CTRL_CFG_UPD_AUTO | ctrl_cfg, addr); - else - writel(CIF_RSZ_CTRL_CFG_UPD | ctrl_cfg, addr); + if (async && dev->hw_dev->is_single) + val = CIF_RSZ_CTRL_CFG_UPD_AUTO; + rkisp_set_bits(dev, stream->config->rsz.ctrl, 0, val, false); } static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y, struct v4l2_rect *in_c, struct v4l2_rect *out_y, struct v4l2_rect *out_c) { - void __iomem *base = stream->ispdev->base_addr; - void __iomem *scale_hy_addr = base + stream->config->rsz.scale_hy; - void __iomem *scale_hcr_addr = base + stream->config->rsz.scale_hcr; - void __iomem *scale_hcb_addr = base + stream->config->rsz.scale_hcb; - void __iomem *scale_vy_addr = base + stream->config->rsz.scale_vy; - void __iomem *scale_vc_addr = base + stream->config->rsz.scale_vc; - void __iomem *rsz_ctrl_addr = base + stream->config->rsz.ctrl; + struct rkisp_device *dev = stream->ispdev; + u32 scale_hy_addr = stream->config->rsz.scale_hy; + u32 scale_hcr_addr = stream->config->rsz.scale_hcr; + u32 scale_hcb_addr = stream->config->rsz.scale_hcb; + u32 scale_vy_addr = stream->config->rsz.scale_vy; + u32 scale_vc_addr = stream->config->rsz.scale_vc; + u32 rsz_ctrl_addr = stream->config->rsz.ctrl; u32 scale_hy, scale_hc, scale_vy, scale_vc, rsz_ctrl = 0; if (in_y->width < out_y->width) { @@ -135,26 +128,26 @@ static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y, CIF_RSZ_CTRL_SCALE_HY_UP; scale_hy = ((in_y->width - 1) * CIF_RSZ_SCALER_FACTOR) / (out_y->width - 1); - writel(scale_hy, scale_hy_addr); + rkisp_write(dev, scale_hy_addr, scale_hy, false); } else if (in_y->width > out_y->width) { rsz_ctrl |= CIF_RSZ_CTRL_SCALE_HY_ENABLE; scale_hy = ((out_y->width - 1) * CIF_RSZ_SCALER_FACTOR) / (in_y->width - 1) + 1; - writel(scale_hy, scale_hy_addr); + rkisp_write(dev, scale_hy_addr, scale_hy, false); } if (in_c->width < out_c->width) { rsz_ctrl |= CIF_RSZ_CTRL_SCALE_HC_ENABLE | CIF_RSZ_CTRL_SCALE_HC_UP; scale_hc = ((in_c->width - 1) * CIF_RSZ_SCALER_FACTOR) / (out_c->width - 1); - writel(scale_hc, scale_hcb_addr); - writel(scale_hc, scale_hcr_addr); + rkisp_write(dev, scale_hcb_addr, scale_hc, false); + rkisp_write(dev, scale_hcr_addr, scale_hc, false); } else if (in_c->width > out_c->width) { rsz_ctrl |= CIF_RSZ_CTRL_SCALE_HC_ENABLE; scale_hc = ((out_c->width - 1) * CIF_RSZ_SCALER_FACTOR) / (in_c->width - 1) + 1; - writel(scale_hc, scale_hcb_addr); - writel(scale_hc, scale_hcr_addr); + rkisp_write(dev, scale_hcb_addr, scale_hc, false); + rkisp_write(dev, scale_hcr_addr, scale_hc, false); } if (in_y->height < out_y->height) { @@ -162,12 +155,12 @@ static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y, CIF_RSZ_CTRL_SCALE_VY_UP; scale_vy = ((in_y->height - 1) * CIF_RSZ_SCALER_FACTOR) / (out_y->height - 1); - writel(scale_vy, scale_vy_addr); + rkisp_write(dev, scale_vy_addr, scale_vy, false); } else if (in_y->height > out_y->height) { rsz_ctrl |= CIF_RSZ_CTRL_SCALE_VY_ENABLE; scale_vy = ((out_y->height - 1) * CIF_RSZ_SCALER_FACTOR) / (in_y->height - 1) + 1; - writel(scale_vy, scale_vy_addr); + rkisp_write(dev, scale_vy_addr, scale_vy, false); } if (in_c->height < out_c->height) { @@ -175,33 +168,34 @@ static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y, CIF_RSZ_CTRL_SCALE_VC_UP; scale_vc = ((in_c->height - 1) * CIF_RSZ_SCALER_FACTOR) / (out_c->height - 1); - writel(scale_vc, scale_vc_addr); + rkisp_write(dev, scale_vc_addr, scale_vc, false); } else if (in_c->height > out_c->height) { rsz_ctrl |= CIF_RSZ_CTRL_SCALE_VC_ENABLE; scale_vc = ((out_c->height - 1) * CIF_RSZ_SCALER_FACTOR) / (in_c->height - 1) + 1; - writel(scale_vc, scale_vc_addr); + rkisp_write(dev, scale_vc_addr, scale_vc, false); } - writel(rsz_ctrl, rsz_ctrl_addr); + rkisp_write(dev, rsz_ctrl_addr, rsz_ctrl, false); } void rkisp_config_rsz(struct rkisp_stream *stream, struct v4l2_rect *in_y, struct v4l2_rect *in_c, struct v4l2_rect *out_y, struct v4l2_rect *out_c, bool async) { + struct rkisp_device *dev = stream->ispdev; int i = 0; /* No phase offset */ - writel(0, stream->ispdev->base_addr + stream->config->rsz.phase_hy); - writel(0, stream->ispdev->base_addr + stream->config->rsz.phase_hc); - writel(0, stream->ispdev->base_addr + stream->config->rsz.phase_vy); - writel(0, stream->ispdev->base_addr + stream->config->rsz.phase_vc); + rkisp_write(dev, stream->config->rsz.phase_hy, 0, true); + rkisp_write(dev, stream->config->rsz.phase_hc, 0, true); + rkisp_write(dev, stream->config->rsz.phase_vy, 0, true); + rkisp_write(dev, stream->config->rsz.phase_vc, 0, true); /* Linear interpolation */ for (i = 0; i < 64; i++) { - writel(i, stream->ispdev->base_addr + stream->config->rsz.scale_lut_addr); - writel(i, stream->ispdev->base_addr + stream->config->rsz.scale_lut); + rkisp_write(dev, stream->config->rsz.scale_lut_addr, i, true); + rkisp_write(dev, stream->config->rsz.scale_lut, i, true); } set_scale(stream, in_y, in_c, out_y, out_c); @@ -211,7 +205,7 @@ void rkisp_config_rsz(struct rkisp_stream *stream, struct v4l2_rect *in_y, void rkisp_disable_rsz(struct rkisp_stream *stream, bool async) { - writel(0, stream->ispdev->base_addr + stream->config->rsz.ctrl); + rkisp_write(stream->ispdev, stream->config->rsz.ctrl, 0, false); if (!async) update_rsz_shadow(stream, async); diff --git a/drivers/media/platform/rockchip/isp/regs.h b/drivers/media/platform/rockchip/isp/regs.h index ef344b995fc2..0e350aa3d3b2 100644 --- a/drivers/media/platform/rockchip/isp/regs.h +++ b/drivers/media/platform/rockchip/isp/regs.h @@ -1905,8 +1905,11 @@ static inline void sp_mi_ctrl_autoupdate_en(void __iomem *base) static inline void force_cfg_update(struct rkisp_device *dev) { void __iomem *base = dev->base_addr; + u32 val = readl(base + CIF_MI_CTRL); dev->hw_dev->is_mi_update = true; + val |= CIF_MI_CTRL_INIT_OFFSET_EN | CIF_MI_CTRL_INIT_BASE_EN; + writel(val, base + CIF_MI_CTRL); writel(CIF_MI_INIT_SOFT_UPD, base + CIF_MI_INIT); } diff --git a/drivers/media/platform/rockchip/isp/regs_v2x.h b/drivers/media/platform/rockchip/isp/regs_v2x.h index d61748737040..36f0e3d55461 100644 --- a/drivers/media/platform/rockchip/isp/regs_v2x.h +++ b/drivers/media/platform/rockchip/isp/regs_v2x.h @@ -427,6 +427,7 @@ #define MI_WR_ID (MI_BASE + 0x00154) #define MI_MP_WR_Y_IRQ_OFFS2 (MI_BASE + 0x001e0) #define MI_MP_WR_Y_IRQ_OFFS2_SHD (MI_BASE + 0x001e4) +#define MI_MP_WR_Y_LLENGTH (MI_BASE + 0x001e8) #define MI_WR_CTRL2 (MI_BASE + 0x00400) #define MI_WR_ID2 (MI_BASE + 0x00404) #define MI_RD_CTRL2 (MI_BASE + 0x00408) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 67bb47e17fd5..dc54fc9ff58c 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -1587,14 +1587,6 @@ static int rkisp_isp_sd_set_selection(struct v4l2_subdev *sd, isp_sd->out_crop = *crop; } - /* change size of MP/SP */ - rkisp_set_stream_def_fmt(dev, RKISP_STREAM_MP, - isp_sd->out_crop.width, - isp_sd->out_crop.height, 0); - if (dev->isp_ver != ISP_V10_1) - rkisp_set_stream_def_fmt(dev, RKISP_STREAM_SP, - isp_sd->out_crop.width, - isp_sd->out_crop.height, 0); return 0; err: return -EINVAL; @@ -1778,6 +1770,14 @@ static int rkisp_subdev_link_setup(struct media_entity *entity, dev->active_sensor = NULL; dev->isp_inp &= ~INP_LVDS; } + } else if (strstr(remote->entity->name, "rkcif")) { + if (flags & MEDIA_LNK_FL_ENABLED) { + if (dev->isp_inp & ~(INP_CIF | rawrd)) + goto err; + dev->isp_inp |= INP_CIF; + } else { + dev->isp_inp &= ~INP_CIF; + } } else { if (flags & MEDIA_LNK_FL_ENABLED) { if (dev->isp_inp & ~INP_DVP)