diff --git a/drivers/media/platform/rockchip/isp/csi.c b/drivers/media/platform/rockchip/isp/csi.c index bad3c5ce4fae..452ebef32af0 100644 --- a/drivers/media/platform/rockchip/isp/csi.c +++ b/drivers/media/platform/rockchip/isp/csi.c @@ -571,10 +571,11 @@ int rkisp_csi_config_patch(struct rkisp_device *dev) memset(&hdr_cfg, 0, sizeof(hdr_cfg)); ret = rkisp_csi_get_hdr_cfg(dev, &hdr_cfg); if (dev->isp_inp & INP_CIF) { - struct rkisp_vicap_mode mode = { - .name = dev->name, - .is_rdbk = true, - }; + struct rkisp_vicap_mode mode; + + memset(&mode, 0, sizeof(mode)); + mode.name = dev->name; + mode.is_rdbk = true; get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_PROC_VIDEO_COMPOSER); dev->hdr.op_mode = HDR_NORMAL; @@ -593,6 +594,7 @@ int rkisp_csi_config_patch(struct rkisp_device *dev) mode.is_rdbk = false; v4l2_subdev_call(mipi_sensor, core, ioctl, RKISP_VICAP_CMD_MODE, &mode); + dev->vicap_in = mode.input; /* vicap direct to isp */ if ((dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32) && !mode.is_rdbk) { diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index 827ea956aedf..817277e903d6 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -303,14 +303,21 @@ static int rkisp_pipeline_set_stream(struct rkisp_pipeline *p, bool on) goto err; /* phy -> sensor */ for (i = 0; i < p->num_subdevs; ++i) { + if ((dev->vicap_in.merge_num > 1) && + (p->subdevs[i]->entity.function == MEDIA_ENT_F_CAM_SENSOR)) + continue; ret = v4l2_subdev_call(p->subdevs[i], video, s_stream, on); if (on && ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) goto err_stream_off; } } else { /* sensor -> phy */ - for (i = p->num_subdevs - 1; i >= 0; --i) + for (i = p->num_subdevs - 1; i >= 0; --i) { + if ((dev->vicap_in.merge_num > 1) && + (p->subdevs[i]->entity.function == MEDIA_ENT_F_CAM_SENSOR)) + continue; v4l2_subdev_call(p->subdevs[i], video, s_stream, on); + } if (dev->vs_irq >= 0) disable_irq(dev->vs_irq); v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, false); diff --git a/drivers/media/platform/rockchip/isp/dev.h b/drivers/media/platform/rockchip/isp/dev.h index eb5455501bb4..eb14b1ee4898 100644 --- a/drivers/media/platform/rockchip/isp/dev.h +++ b/drivers/media/platform/rockchip/isp/dev.h @@ -236,5 +236,7 @@ struct rkisp_device { bool is_cmsk_upd; bool is_hw_link; bool is_bigmode; + + struct rkisp_vicap_input vicap_in; }; #endif diff --git a/drivers/media/platform/rockchip/isp/dmarx.c b/drivers/media/platform/rockchip/isp/dmarx.c index cb486f5f84e0..650266b1c292 100644 --- a/drivers/media/platform/rockchip/isp/dmarx.c +++ b/drivers/media/platform/rockchip/isp/dmarx.c @@ -366,10 +366,15 @@ static void update_rawrd(struct rkisp_stream *stream) struct rkisp_device *dev = stream->ispdev; void __iomem *base = dev->base_addr; struct capture_fmt *fmt = &stream->out_isp_fmt; - u32 val; + u32 val = 0; if (stream->curr_buf) { - val = stream->curr_buf->buff_addr[RKISP_PLANE_Y]; + if (dev->vicap_in.merge_num > 1) { + val = stream->out_fmt.plane_fmt[0].bytesperline; + val /= dev->vicap_in.merge_num; + val *= dev->vicap_in.index; + } + val += stream->curr_buf->buff_addr[RKISP_PLANE_Y]; rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false); if (dev->hw_dev->is_unite) { val += (stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL) * @@ -743,7 +748,10 @@ static int rkisp_set_fmt(struct rkisp_stream *stream, bytesperline = ALIGN(width * fmt->bpp[i] / 8, 256); else bytesperline = width * DIV_ROUND_UP(fmt->bpp[i], 8); - /* stride is only available for sp stream and y plane */ + + if (stream->ispdev->vicap_in.merge_num > 1) + bytesperline *= stream->ispdev->vicap_in.merge_num; + if (i != 0 || plane_fmt->bytesperline < bytesperline) plane_fmt->bytesperline = bytesperline; diff --git a/drivers/media/platform/rockchip/isp/isp_external.h b/drivers/media/platform/rockchip/isp/isp_external.h index 655c4b943835..b7447cef83b7 100644 --- a/drivers/media/platform/rockchip/isp/isp_external.h +++ b/drivers/media/platform/rockchip/isp/isp_external.h @@ -6,7 +6,7 @@ #define RKISP_VICAP_CMD_MODE \ - _IOW('V', BASE_VIDIOC_PRIVATE + 0, struct rkisp_vicap_mode) + _IOWR('V', BASE_VIDIOC_PRIVATE + 0, struct rkisp_vicap_mode) #define RKISP_VICAP_CMD_INIT_BUF \ _IOW('V', BASE_VIDIOC_PRIVATE + 1, int) @@ -14,9 +14,16 @@ #define RKISP_VICAP_BUF_CNT 1 #define RKISP_RX_BUF_POOL_MAX (RKISP_VICAP_BUF_CNT * 3) +struct rkisp_vicap_input { + u8 merge_num; + u8 index; +}; + struct rkisp_vicap_mode { char *name; bool is_rdbk; + + struct rkisp_vicap_input input; }; enum rx_buf_type { diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 0e451ffad125..988ed3d82ab3 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -2925,6 +2925,7 @@ static int rkisp_subdev_link_setup(struct media_entity *entity, struct v4l2_subdev *remote = get_remote_sensor(sd); struct rkisp_vicap_mode mode; + memset(&mode, 0, sizeof(mode)); mode.name = dev->name; mode.is_rdbk = !!(dev->isp_inp & rawrd); /* read back mode only */ @@ -2932,6 +2933,7 @@ static int rkisp_subdev_link_setup(struct media_entity *entity, mode.is_rdbk = true; v4l2_subdev_call(remote, core, ioctl, RKISP_VICAP_CMD_MODE, &mode); + dev->vicap_in = mode.input; } if (!dev->isp_inp)