mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
media: rockchip: isp: support multi dev for isp21
Change-Id: I5973f952d0b744448025496c29a1c6b4c5316db3 Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user