media: rockchip: isp: isp32 support mirror and flip

Change-Id: I8e067cddee9bb314d97e2fd09b62886e8f9b222d
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2022-02-14 17:41:10 +08:00
committed by Tao Huang
parent 5409c91052
commit c76be98cdc
5 changed files with 156 additions and 13 deletions

View File

@@ -443,6 +443,7 @@ static const struct capture_fmt mp_fmts[] = {
.mplanes = 1,
.uv_swap = 0,
.write_format = MI_CTRL_MP_WRITE_YUVINT,
.output_format = ISP32_MI_OUTPUT_YUV422,
}, {
.fourcc = V4L2_PIX_FMT_YUV422P,
.fmt_type = FMT_YUV,
@@ -451,6 +452,7 @@ static const struct capture_fmt mp_fmts[] = {
.mplanes = 1,
.uv_swap = 0,
.write_format = MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
.output_format = ISP32_MI_OUTPUT_YUV422,
}, {
.fourcc = V4L2_PIX_FMT_NV16,
.fmt_type = FMT_YUV,
@@ -459,6 +461,7 @@ static const struct capture_fmt mp_fmts[] = {
.mplanes = 1,
.uv_swap = 0,
.write_format = MI_CTRL_MP_WRITE_YUV_SPLA,
.output_format = ISP32_MI_OUTPUT_YUV422,
}, {
.fourcc = V4L2_PIX_FMT_NV61,
.fmt_type = FMT_YUV,
@@ -467,6 +470,7 @@ static const struct capture_fmt mp_fmts[] = {
.mplanes = 1,
.uv_swap = 1,
.write_format = MI_CTRL_MP_WRITE_YUV_SPLA,
.output_format = ISP32_MI_OUTPUT_YUV422,
}, {
.fourcc = V4L2_PIX_FMT_YUV422M,
.fmt_type = FMT_YUV,
@@ -475,6 +479,7 @@ static const struct capture_fmt mp_fmts[] = {
.mplanes = 3,
.uv_swap = 0,
.write_format = MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
.output_format = ISP32_MI_OUTPUT_YUV422,
},
/* yuv420 */
{
@@ -485,6 +490,7 @@ static const struct capture_fmt mp_fmts[] = {
.mplanes = 1,
.uv_swap = 1,
.write_format = MI_CTRL_MP_WRITE_YUV_SPLA,
.output_format = ISP32_MI_OUTPUT_YUV420,
}, {
.fourcc = V4L2_PIX_FMT_NV12,
.fmt_type = FMT_YUV,
@@ -493,6 +499,7 @@ static const struct capture_fmt mp_fmts[] = {
.mplanes = 1,
.uv_swap = 0,
.write_format = MI_CTRL_MP_WRITE_YUV_SPLA,
.output_format = ISP32_MI_OUTPUT_YUV420,
}, {
.fourcc = V4L2_PIX_FMT_NV21M,
.fmt_type = FMT_YUV,
@@ -501,6 +508,7 @@ static const struct capture_fmt mp_fmts[] = {
.mplanes = 2,
.uv_swap = 1,
.write_format = MI_CTRL_MP_WRITE_YUV_SPLA,
.output_format = ISP32_MI_OUTPUT_YUV420,
}, {
.fourcc = V4L2_PIX_FMT_NV12M,
.fmt_type = FMT_YUV,
@@ -509,6 +517,7 @@ static const struct capture_fmt mp_fmts[] = {
.mplanes = 2,
.uv_swap = 0,
.write_format = MI_CTRL_MP_WRITE_YUV_SPLA,
.output_format = ISP32_MI_OUTPUT_YUV420,
}, {
.fourcc = V4L2_PIX_FMT_YUV420,
.fmt_type = FMT_YUV,
@@ -517,6 +526,7 @@ static const struct capture_fmt mp_fmts[] = {
.mplanes = 1,
.uv_swap = 0,
.write_format = MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
.output_format = ISP32_MI_OUTPUT_YUV420,
},
/* yuv444 */
{
@@ -527,6 +537,7 @@ static const struct capture_fmt mp_fmts[] = {
.mplanes = 3,
.uv_swap = 0,
.write_format = MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
.output_format = 0,
},
/* raw */
{
@@ -535,72 +546,84 @@ static const struct capture_fmt mp_fmts[] = {
.bpp = { 8 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
.output_format = 0,
}, {
.fourcc = V4L2_PIX_FMT_SGRBG8,
.fmt_type = FMT_BAYER,
.bpp = { 8 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
.output_format = 0,
}, {
.fourcc = V4L2_PIX_FMT_SGBRG8,
.fmt_type = FMT_BAYER,
.bpp = { 8 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
.output_format = 0,
}, {
.fourcc = V4L2_PIX_FMT_SBGGR8,
.fmt_type = FMT_BAYER,
.bpp = { 8 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
.output_format = 0,
}, {
.fourcc = V4L2_PIX_FMT_SRGGB10,
.fmt_type = FMT_BAYER,
.bpp = { 10 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_RAW12,
.output_format = 0,
}, {
.fourcc = V4L2_PIX_FMT_SGRBG10,
.fmt_type = FMT_BAYER,
.bpp = { 10 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_RAW12,
.output_format = 0,
}, {
.fourcc = V4L2_PIX_FMT_SGBRG10,
.fmt_type = FMT_BAYER,
.bpp = { 10 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_RAW12,
.output_format = 0,
}, {
.fourcc = V4L2_PIX_FMT_SBGGR10,
.fmt_type = FMT_BAYER,
.bpp = { 10 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_RAW12,
.output_format = 0,
}, {
.fourcc = V4L2_PIX_FMT_SRGGB12,
.fmt_type = FMT_BAYER,
.bpp = { 12 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_RAW12,
.output_format = 0,
}, {
.fourcc = V4L2_PIX_FMT_SGRBG12,
.fmt_type = FMT_BAYER,
.bpp = { 12 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_RAW12,
.output_format = 0,
}, {
.fourcc = V4L2_PIX_FMT_SGBRG12,
.fmt_type = FMT_BAYER,
.bpp = { 12 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_RAW12,
.output_format = 0,
}, {
.fourcc = V4L2_PIX_FMT_SBGGR12,
.fmt_type = FMT_BAYER,
.bpp = { 12 },
.mplanes = 1,
.write_format = MI_CTRL_MP_WRITE_RAW12,
.output_format = 0,
},
};
@@ -804,6 +827,7 @@ struct stream_config rkisp_mp_stream_config = {
.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,
.y_pic_size = ISP3X_MI_MP_WR_Y_PIC_SIZE,
},
};
@@ -861,6 +885,7 @@ struct stream_config rkisp_sp_stream_config = {
.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,
.y_pic_size = ISP3X_MI_SP_WR_Y_PIC_SIZE,
},
};
@@ -1339,6 +1364,33 @@ static int rkisp_get_stream_info(struct rkisp_stream *stream,
return 0;
}
static int rkisp_get_mirror_flip(struct rkisp_stream *stream,
struct rkisp_mirror_flip *cfg)
{
struct rkisp_device *dev = stream->ispdev;
if (dev->isp_ver != ISP_V32)
return -EINVAL;
cfg->mirror = dev->cap_dev.is_mirror;
cfg->flip = stream->is_flip;
return 0;
}
static int rkisp_set_mirror_flip(struct rkisp_stream *stream,
struct rkisp_mirror_flip *cfg)
{
struct rkisp_device *dev = stream->ispdev;
if (dev->isp_ver != ISP_V32)
return -EINVAL;
dev->cap_dev.is_mirror = cfg->mirror;
stream->is_flip = cfg->flip;
stream->is_mf_upd = true;
return 0;
}
static long rkisp_ioctl_default(struct file *file, void *fh,
bool valid_prio, unsigned int cmd, void *arg)
{
@@ -1385,6 +1437,12 @@ static long rkisp_ioctl_default(struct file *file, void *fh,
case RKISP_CMD_GET_STREAM_INFO:
ret = rkisp_get_stream_info(stream, arg);
break;
case RKISP_CMD_GET_MIRROR_FLIP:
ret = rkisp_get_mirror_flip(stream, arg);
break;
case RKISP_CMD_SET_MIRROR_FLIP:
ret = rkisp_set_mirror_flip(stream, arg);
break;
default:
ret = -EINVAL;
}

View File

@@ -192,6 +192,7 @@ struct stream_config {
u32 y_base_ad_shd;
u32 length;
u32 ctrl;
u32 y_pic_size;
} mi;
struct {
u32 ctrl;
@@ -253,6 +254,8 @@ struct rkisp_stream {
bool frame_end;
bool linked;
bool start_stream;
bool is_mf_upd;
bool is_flip;
wait_queue_head_t done;
unsigned int burst;
atomic_t sequence;
@@ -283,6 +286,7 @@ struct rkisp_capture_device {
u32 wait_line;
u32 wrap_line;
bool is_done_early;
bool is_mirror;
};
extern struct stream_config rkisp_mp_stream_config;

View File

@@ -109,6 +109,7 @@ static struct stream_config rkisp_bp_stream_config = {
.y_offs_cnt_init = ISP3X_MI_BP_WR_Y_OFFS_CNT,
.cb_offs_cnt_init = ISP3X_MI_BP_WR_CB_OFFS_CNT,
.y_base_ad_shd = ISP3X_MI_BP_WR_Y_BASE_SHD,
.y_pic_size = ISP3X_MI_BP_WR_Y_PIC_SIZE,
},
};
@@ -126,6 +127,7 @@ static struct stream_config rkisp_bpds_stream_config = {
.y_offs_cnt_init = ISP32_MI_BPDS_WR_Y_OFFS_CNT,
.cb_offs_cnt_init = ISP32_MI_BPDS_WR_CB_OFFS_CNT,
.y_base_ad_shd = ISP32_MI_BPDS_WR_Y_BASE_SHD,
.y_pic_size = ISP32_MI_BPDS_WR_Y_PIC_SIZE,
},
};
@@ -143,6 +145,7 @@ static struct stream_config rkisp_mpds_stream_config = {
.y_offs_cnt_init = ISP32_MI_MPDS_WR_Y_OFFS_CNT,
.cb_offs_cnt_init = ISP32_MI_MPDS_WR_CB_OFFS_CNT,
.y_base_ad_shd = ISP32_MI_MPDS_WR_Y_BASE_SHD,
.y_pic_size = ISP32_MI_MPDS_WR_Y_PIC_SIZE,
},
};
@@ -336,6 +339,7 @@ static u32 calc_burst_len(struct rkisp_stream *stream)
static int mp_config_mi(struct rkisp_stream *stream)
{
struct rkisp_device *dev = stream->ispdev;
struct capture_fmt *fmt = &stream->out_isp_fmt;
struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt;
u32 val, mask, height = out_fmt->height;
@@ -347,6 +351,11 @@ static int mp_config_mi(struct rkisp_stream *stream)
height = dev->cap_dev.wrap_line;
rkisp_clear_bits(dev, 0x1814, BIT(0), false);
}
val = out_fmt->plane_fmt[0].bytesperline;
rkisp_write(dev, ISP3X_MI_MP_WR_Y_LLENGTH, val, false);
val /= DIV_ROUND_UP(fmt->bpp[0], 8);
val *= height;
rkisp_write(dev, stream->config->mi.y_pic_size, val, false);
val = out_fmt->plane_fmt[0].bytesperline * height;
rkisp_write(dev, stream->config->mi.y_size_init, val, false);
@@ -356,9 +365,6 @@ static int mp_config_mi(struct rkisp_stream *stream)
val = out_fmt->plane_fmt[2].sizeimage;
rkisp_write(dev, stream->config->mi.cr_size_init, val, false);
val = ALIGN(out_fmt->plane_fmt[0].bytesperline, 16);
rkisp_write(dev, ISP3X_MI_MP_WR_Y_LLENGTH, val, false);
val = stream->out_isp_fmt.uv_swap ? ISP3X_MI_XTD_FORMAT_MP_UV_SWAP : 0;
mask = ISP3X_MI_XTD_FORMAT_MP_UV_SWAP;
rkisp_set_bits(dev, ISP3X_MI_WR_XTD_FORMAT_CTRL, mask, val, false);
@@ -375,6 +381,9 @@ static int mp_config_mi(struct rkisp_stream *stream)
val |= ISP3X_SEPERATE_YUV_CFG | ISP3X_MP_YUV_MODE;
rkisp_write(dev, ISP3X_MPFBC_CTRL, val, false);
val = stream->out_isp_fmt.output_format;
rkisp_write(dev, ISP32_MI_MP_WR_CTRL, val, false);
val = 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;
@@ -432,6 +441,10 @@ 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.
*/
val = stream->u.sp.y_stride;
rkisp_write(dev, ISP3X_MI_SP_WR_Y_LLENGTH, val, false);
val *= out_fmt->height;
rkisp_write(dev, stream->config->mi.y_pic_size, val, false);
val = out_fmt->plane_fmt[0].bytesperline * out_fmt->height;
rkisp_write(dev, stream->config->mi.y_size_init, val, false);
@@ -441,9 +454,6 @@ static int sp_config_mi(struct rkisp_stream *stream)
val = out_fmt->plane_fmt[2].sizeimage;
rkisp_write(dev, stream->config->mi.cr_size_init, val, false);
val = ALIGN(out_fmt->plane_fmt[0].bytesperline, 16);
rkisp_write(dev, ISP3X_MI_SP_WR_Y_LLENGTH, val, false);
val = stream->out_isp_fmt.uv_swap ? ISP3X_MI_XTD_FORMAT_SP_UV_SWAP : 0;
mask = ISP3X_MI_XTD_FORMAT_SP_UV_SWAP;
rkisp_set_bits(dev, ISP3X_MI_WR_XTD_FORMAT_CTRL, mask, val, false);
@@ -476,6 +486,7 @@ static int sp_config_mi(struct rkisp_stream *stream)
static int bp_config_mi(struct rkisp_stream *stream)
{
struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt;
struct capture_fmt *fmt = &stream->out_isp_fmt;
struct rkisp_device *dev = stream->ispdev;
u32 val, mask;
@@ -483,15 +494,17 @@ static int bp_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.
*/
val = out_fmt->plane_fmt[0].bytesperline;
rkisp_write(dev, ISP3X_MI_BP_WR_Y_LLENGTH, val, false);
val /= DIV_ROUND_UP(fmt->bpp[0], 8);
val *= out_fmt->height;
rkisp_write(dev, stream->config->mi.y_pic_size, val, false);
val = out_fmt->plane_fmt[0].bytesperline * out_fmt->height;
rkisp_write(dev, stream->config->mi.y_size_init, val, false);
val = out_fmt->plane_fmt[1].sizeimage;
rkisp_write(dev, stream->config->mi.cb_size_init, val, false);
val = ALIGN(out_fmt->plane_fmt[0].bytesperline, 16);
rkisp_write(dev, ISP3X_MI_BP_WR_Y_LLENGTH, val, false);
mask = ISP3X_MPFBC_FORCE_UPD | ISP3X_BP_YUV_MODE;
val = rkisp_read_reg_cache(dev, ISP3X_MPFBC_CTRL) & ~mask;
@@ -511,19 +524,22 @@ static int bp_config_mi(struct rkisp_stream *stream)
static int ds_config_mi(struct rkisp_stream *stream)
{
struct capture_fmt *fmt = &stream->out_isp_fmt;
struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt;
struct rkisp_device *dev = stream->ispdev;
u32 val;
val = out_fmt->plane_fmt[0].bytesperline;
rkisp_write(dev, stream->config->mi.length, val, false);
val /= DIV_ROUND_UP(fmt->bpp[0], 8);
val *= out_fmt->height;
rkisp_write(dev, stream->config->mi.y_pic_size, val, false);
val = out_fmt->plane_fmt[0].bytesperline * out_fmt->height;
rkisp_write(dev, stream->config->mi.y_size_init, val, false);
val = out_fmt->plane_fmt[1].sizeimage;
rkisp_write(dev, stream->config->mi.cb_size_init, val, false);
val = ALIGN(out_fmt->plane_fmt[0].bytesperline, 16);
rkisp_write(dev, stream->config->mi.length, val, false);
val = CIF_MI_CTRL_INIT_BASE_EN | CIF_MI_CTRL_INIT_OFFSET_EN;
rkisp_set_bits(dev, ISP3X_MI_WR_CTRL, 0, val, false);
@@ -684,6 +700,49 @@ static void update_mi(struct rkisp_stream *stream)
rkisp_read(dev, stream->config->mi.y_base_ad_shd, true));
}
static int set_mirror_flip(struct rkisp_stream *stream)
{
struct rkisp_device *dev = stream->ispdev;
u32 val = 0;
if (!stream->is_mf_upd)
return 0;
stream->is_mf_upd = false;
if (dev->cap_dev.is_mirror)
rkisp_set_bits(dev, ISP3X_ISP_CTRL0, 0, ISP32_MIR_ENABLE, false);
else
rkisp_clear_bits(dev, ISP3X_ISP_CTRL0, ISP32_MIR_ENABLE, false);
switch (stream->id) {
case RKISP_STREAM_SP:
val = ISP32_SP_WR_V_FLIP;
break;
case RKISP_STREAM_BP:
val = ISP32_BP_WR_V_FLIP;
break;
case RKISP_STREAM_MPDS:
val = ISP32_MPDS_WR_V_FLIP;
break;
case RKISP_STREAM_BPDS:
val = ISP32_BPDS_WR_V_FIIP;
break;
default:
val = ISP32_MP_WR_V_FLIP;
if (dev->cap_dev.wrap_line) {
stream->is_flip = false;
v4l2_warn(&dev->v4l2_dev, "flip not support width wrap function\n");
return -EINVAL;
}
}
if (stream->is_flip)
rkisp_set_bits(dev, ISP32_MI_WR_VFLIP_CTRL, 0, val, false);
else
rkisp_clear_bits(dev, ISP32_MI_WR_VFLIP_CTRL, val, false);
return 0;
}
static struct streams_ops rkisp_mp_streams_ops = {
.config_mi = mp_config_mi,
.enable_mi = mp_enable_mi,
@@ -743,6 +802,7 @@ static int mi_frame_end(struct rkisp_stream *stream)
u64 ns = 0;
u32 i, seq;
set_mirror_flip(stream);
rkisp_dmarx_get_frame(dev, &seq, NULL, &ns, true);
/* hold one buf for hw dma write */

View File

@@ -1904,6 +1904,12 @@
#define ISP3X_DBR_ST_MODE BIT(30)
#define ISP3X_DBR_ST BIT(31)
/* WR_OUTPUT_FORMAT */
#define ISP32_MI_OUTPUT_MASK GENMASK(10, 8)
#define ISP32_MI_OUTPUT_YUV400 0
#define ISP32_MI_OUTPUT_YUV420 BIT(8)
#define ISP32_MI_OUTPUT_YUV422 BIT(9)
/* MI_WR_CTRL2_SHD */
#define ISP32_BP_EN_IN_SHD BIT(4)
#define ISP32_DBR_WR_EN_IN_SHD BIT(5)
@@ -1966,7 +1972,7 @@
#define ISP32_MPDS_WR_FRMEND_UPD_DIS BIT(27)
#define ISP32_BPDS_WR_FRMEND_UPD_DIS BIT(28)
/* WRAP_CTRL */
/* VFLIP_CTRL */
#define ISP32_MP_WR_V_FLIP BIT(0)
#define ISP32_SP_WR_V_FLIP BIT(1)
#define ISP32_BP_WR_V_FLIP BIT(2)

View File

@@ -58,6 +58,12 @@
#define RKISP_CMD_GET_STREAM_INFO \
_IOR('V', BASE_VIDIOC_PRIVATE + 104, struct rkisp_stream_info)
#define RKISP_CMD_GET_MIRROR_FLIP \
_IOR('V', BASE_VIDIOC_PRIVATE + 105, struct rkisp_mirror_flip)
#define RKISP_CMD_SET_MIRROR_FLIP \
_IOW('V', BASE_VIDIOC_PRIVATE + 106, struct rkisp_mirror_flip)
/*************************************************************/
#define ISP2X_ID_DPCC (0)
@@ -311,6 +317,15 @@ struct rkisp_stream_info {
unsigned char stream_on;
} __attribute__ ((packed));
/* struct rkisp_mirror_flip
* mirror: global for all output stream
* flip: independent for all output stream
*/
struct rkisp_mirror_flip {
unsigned char mirror;
unsigned char flip;
} __attribute__ ((packed));
/* trigger event mode
* T_TRY: trigger maybe with retry
* T_TRY_YES: trigger to retry