mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 22:52:35 +02:00
media: rk-isp10: support bt656 signal interlace
odd and even field interlace generating a frame image. fix cif_isp10_img_src_v4l2_subdev_enum_strm_fmts defrect info get error. fix cif_isp10_rk3399 cif_clk_pll info doesn't match with dts config. Change-Id: I44159c0dd4e676334221b5d5682e29d3280aa9fd Signed-off-by: zhoupeng <benjo.zhou@rock-chips.com>
This commit is contained in:
parent
49418c68f6
commit
3565b1e7e8
|
|
@ -460,6 +460,8 @@ static const char *cif_isp10_interface_string(
|
|||
return "DVP_BT601_16Bit";
|
||||
case PLTFRM_CAM_ITF_BT656_16:
|
||||
return "DVP_BT656_16Bit";
|
||||
case PLTFRM_CAM_ITF_BT656_8_INTERLACE:
|
||||
return "DVP_BT656_8Bit_interlace";
|
||||
default:
|
||||
return "UNKNOWN/UNSUPPORTED";
|
||||
}
|
||||
|
|
@ -1333,6 +1335,9 @@ static void cif_isp10_config_ism(struct cif_isp10_device *dev, bool async)
|
|||
dev->config.base_addr + CIF_ISP_IS_H_SIZE);
|
||||
cif_iowrite32(dev->config.isp_config.output.height,
|
||||
dev->config.base_addr + CIF_ISP_IS_V_SIZE);
|
||||
if (PLTFRM_CAM_ITF_INTERLACE(dev->config.cam_itf.type))
|
||||
cif_iowrite32(dev->config.isp_config.output.height / 2,
|
||||
dev->config.base_addr + CIF_ISP_IS_V_SIZE);
|
||||
cif_iowrite32(0,
|
||||
dev->config.base_addr + CIF_ISP_IS_CTRL);
|
||||
}
|
||||
|
|
@ -1851,6 +1856,21 @@ static int cif_isp10_config_isp(
|
|||
dev->config.base_addr + CIF_ISP_OUT_H_SIZE);
|
||||
cif_iowrite32(output->height,
|
||||
dev->config.base_addr + CIF_ISP_OUT_V_SIZE);
|
||||
if (PLTFRM_CAM_ITF_INTERLACE(cam_itf->type)) {
|
||||
cif_isp10_pltfrm_pr_info(dev->dev,
|
||||
"type %s: input.size %dx%d, output.size %dx%d\n",
|
||||
cif_isp10_interface_string(cam_itf->type),
|
||||
dev->config.isp_config.input->defrect.width,
|
||||
dev->config.isp_config.input->defrect.height,
|
||||
output->width,
|
||||
output->height);
|
||||
cif_iowrite32(
|
||||
dev->config.isp_config.input->defrect.height / 2,
|
||||
dev->config.base_addr + CIF_ISP_ACQ_V_SIZE);
|
||||
cif_iowrite32(
|
||||
output->height / 2,
|
||||
dev->config.base_addr + CIF_ISP_OUT_V_SIZE);
|
||||
}
|
||||
|
||||
dev->isp_dev.input_width =
|
||||
dev->config.isp_config.input->defrect.width;
|
||||
|
|
@ -2213,6 +2233,7 @@ static int cif_isp10_config_mi_sp(
|
|||
u32 size = llength * height * bpp / 8;
|
||||
u32 input_format = 0;
|
||||
u32 output_format;
|
||||
u32 burst_len;
|
||||
u32 mi_ctrl;
|
||||
|
||||
dev->config.mi_config.sp.input =
|
||||
|
|
@ -2224,6 +2245,17 @@ static int cif_isp10_config_mi_sp(
|
|||
width,
|
||||
height,
|
||||
llength);
|
||||
if (PLTFRM_CAM_ITF_INTERLACE(dev->config.cam_itf.type)) {
|
||||
llength = 2 * llength;
|
||||
height = height / 2;
|
||||
dev->config.mi_config.sp.vir_len_offset =
|
||||
width;
|
||||
burst_len = CIF_MI_CTRL_BURST_LEN_LUM_16 |
|
||||
CIF_MI_CTRL_BURST_LEN_CHROM_16;
|
||||
} else {
|
||||
burst_len = CIF_MI_CTRL_BURST_LEN_LUM_64 |
|
||||
CIF_MI_CTRL_BURST_LEN_CHROM_64;
|
||||
}
|
||||
|
||||
if (!CIF_ISP10_PIX_FMT_IS_YUV(in_pix_fmt)) {
|
||||
cif_isp10_pltfrm_pr_err(dev->dev,
|
||||
|
|
@ -2268,12 +2300,16 @@ static int cif_isp10_config_mi_sp(
|
|||
(CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 0))
|
||||
output_format = CIF_MI_CTRL_SP_OUTPUT_FMT_YUV400;
|
||||
else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 2) &&
|
||||
(CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 2))
|
||||
(CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 2)) {
|
||||
output_format = CIF_MI_CTRL_SP_OUTPUT_FMT_YUV420;
|
||||
else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 2) &&
|
||||
(CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 4))
|
||||
dev->config.mi_config.sp.vir_len_offset =
|
||||
width;
|
||||
} else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 2) &&
|
||||
(CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 4)) {
|
||||
output_format = CIF_MI_CTRL_SP_OUTPUT_FMT_YUV422;
|
||||
else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 4) &&
|
||||
dev->config.mi_config.sp.vir_len_offset =
|
||||
width * 2;
|
||||
} else if ((CIF_ISP10_PIX_FMT_YUV_GET_X_SUBS(out_pix_fmt) == 4) &&
|
||||
(CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(out_pix_fmt) == 4))
|
||||
output_format = CIF_MI_CTRL_SP_OUTPUT_FMT_YUV444;
|
||||
else {
|
||||
|
|
@ -2378,8 +2414,7 @@ static int cif_isp10_config_mi_sp(
|
|||
CIF_MI_CTRL_SP_WRITE_FMT(writeformat) |
|
||||
input_format |
|
||||
output_format |
|
||||
CIF_MI_CTRL_BURST_LEN_LUM_64 |
|
||||
CIF_MI_CTRL_BURST_LEN_CHROM_64 |
|
||||
burst_len |
|
||||
CIF_MI_CTRL_INIT_BASE_EN |
|
||||
CIF_MI_CTRL_INIT_OFFSET_EN |
|
||||
CIF_MI_SP_AUTOUPDATE_ENABLE;
|
||||
|
|
@ -3766,6 +3801,8 @@ static int cif_isp10_update_mi_mp(
|
|||
static int cif_isp10_update_mi_sp(
|
||||
struct cif_isp10_device *dev)
|
||||
{
|
||||
u32 vir_len_offset = dev->config.mi_config.sp.vir_len_offset;
|
||||
|
||||
cif_isp10_pltfrm_pr_dbg(NULL,
|
||||
"curr 0x%08x next 0x%08x\n",
|
||||
dev->config.mi_config.sp.curr_buff_addr,
|
||||
|
|
@ -3792,6 +3829,56 @@ static int cif_isp10_update_mi_sp(
|
|||
cif_isp10_mi_update_buff_addr(dev, CIF_ISP10_STREAM_SP);
|
||||
dev->config.mi_config.sp.curr_buff_addr =
|
||||
dev->config.mi_config.sp.next_buff_addr;
|
||||
} else if (PLTFRM_CAM_ITF_INTERLACE(dev->config.cam_itf.type)) {
|
||||
cif_iowrite32_verify(dev->config.mi_config.sp.next_buff_addr +
|
||||
vir_len_offset,
|
||||
dev->config.base_addr +
|
||||
CIF_MI_SP_Y_BASE_AD_INIT, CIF_MI_ADDR_SIZE_ALIGN_MASK);
|
||||
cif_iowrite32_verify(dev->config.mi_config.sp.next_buff_addr +
|
||||
vir_len_offset +
|
||||
dev->config.mi_config.sp.cb_offs,
|
||||
dev->config.base_addr +
|
||||
CIF_MI_SP_CB_BASE_AD_INIT, CIF_MI_ADDR_SIZE_ALIGN_MASK);
|
||||
cif_iowrite32_verify(dev->config.mi_config.sp.next_buff_addr +
|
||||
vir_len_offset +
|
||||
dev->config.mi_config.sp.cr_offs,
|
||||
dev->config.base_addr +
|
||||
CIF_MI_SP_CR_BASE_AD_INIT, CIF_MI_ADDR_SIZE_ALIGN_MASK);
|
||||
/*
|
||||
* There have bee repeatedly issues with
|
||||
* the offset registers, it is safer to write
|
||||
* them each time, even though it is always
|
||||
* 0 and even though that is the
|
||||
* register's default value
|
||||
*/
|
||||
cif_iowrite32_verify(0,
|
||||
dev->config.base_addr +
|
||||
CIF_MI_SP_Y_OFFS_CNT_INIT,
|
||||
CIF_MI_ADDR_SIZE_ALIGN_MASK);
|
||||
cif_iowrite32_verify(0,
|
||||
dev->config.base_addr +
|
||||
CIF_MI_SP_CB_OFFS_CNT_INIT,
|
||||
CIF_MI_ADDR_SIZE_ALIGN_MASK);
|
||||
cif_iowrite32_verify(0,
|
||||
dev->config.base_addr +
|
||||
CIF_MI_SP_CR_OFFS_CNT_INIT,
|
||||
CIF_MI_ADDR_SIZE_ALIGN_MASK);
|
||||
cif_isp10_pltfrm_pr_dbg(dev->dev,
|
||||
"\n MI_SP_Y_BASE_AD 0x%08x/0x%08x\n"
|
||||
" MI_SP_CB_BASE_AD 0x%08x/0x%08x\n"
|
||||
" MI_SP_CR_BASE_AD 0x%08x/0x%08x\n",
|
||||
cif_ioread32(dev->config.base_addr +
|
||||
CIF_MI_SP_Y_BASE_AD_INIT),
|
||||
cif_ioread32(dev->config.base_addr +
|
||||
CIF_MI_SP_Y_BASE_AD_SHD),
|
||||
cif_ioread32(dev->config.base_addr +
|
||||
CIF_MI_SP_CB_BASE_AD_INIT),
|
||||
cif_ioread32(dev->config.base_addr +
|
||||
CIF_MI_SP_CB_BASE_AD_SHD),
|
||||
cif_ioread32(dev->config.base_addr +
|
||||
CIF_MI_SP_CR_BASE_AD_INIT),
|
||||
cif_ioread32(dev->config.base_addr +
|
||||
CIF_MI_SP_CR_BASE_AD_SHD));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -4068,6 +4155,12 @@ static int cif_isp10_mi_frame_end(
|
|||
cif_isp10_pltfrm_pr_dbg(NULL, "%s\n",
|
||||
cif_isp10_stream_id_string(stream_id));
|
||||
|
||||
/* BIT 2(current field information): 0 = odd, 1 = even */
|
||||
if (PLTFRM_CAM_ITF_INTERLACE(dev->config.cam_itf.type))
|
||||
dev->config.mi_config.sp.field_flag =
|
||||
(cif_ioread32(dev->config.base_addr +
|
||||
CIF_ISP_FLAGS_SHD) & 0x4) >> 2;
|
||||
|
||||
if (stream_id == CIF_ISP10_STREAM_MP) {
|
||||
stream = &dev->mp_stream;
|
||||
y_base_addr =
|
||||
|
|
@ -4136,7 +4229,8 @@ static int cif_isp10_mi_frame_end(
|
|||
&stream->next_buf->vb.vb2_buf, 0);
|
||||
tmp_addr = sg_dma_address(sgt->sgl);
|
||||
#endif
|
||||
if (tmp_addr != cif_ioread32(y_base_addr)) {
|
||||
if (tmp_addr != cif_ioread32(y_base_addr) &&
|
||||
!PLTFRM_CAM_ITF_INTERLACE(dev->config.cam_itf.type)) {
|
||||
cif_isp10_pltfrm_pr_warn(dev->dev,
|
||||
"%s buffer queue is not advancing (0x%08x/0x%08x)\n",
|
||||
cif_isp10_stream_id_string(stream_id),
|
||||
|
|
@ -4148,6 +4242,13 @@ static int cif_isp10_mi_frame_end(
|
|||
cif_ioread32(y_base_addr));
|
||||
stream->stall = true;
|
||||
}
|
||||
|
||||
if (PLTFRM_CAM_ITF_INTERLACE(dev->config.cam_itf.type)) {
|
||||
if (dev->config.mi_config.sp.field_flag)
|
||||
stream->stall = true;
|
||||
else
|
||||
stream->stall = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream->stall) {
|
||||
|
|
|
|||
|
|
@ -432,6 +432,11 @@ struct cif_isp10_mi_path_config {
|
|||
u32 cb_size;
|
||||
u32 cr_size;
|
||||
bool busy;
|
||||
|
||||
/* FOR BT655: 0 = ODD, 1 = EVEN */
|
||||
bool field_flag;
|
||||
/* for interlace offset */
|
||||
u32 vir_len_offset;
|
||||
};
|
||||
|
||||
struct cif_isp10_zoom_buffer_info {
|
||||
|
|
|
|||
|
|
@ -70,6 +70,12 @@ static enum cif_isp10_pix_fmt img_src_v4l2_subdev_pix_fmt2cif_isp10_pix_fmt(
|
|||
case MEDIA_BUS_FMT_YUYV8_1X16:
|
||||
case MEDIA_BUS_FMT_YUYV10_1X20:
|
||||
return CIF_YUV422I;
|
||||
case MEDIA_BUS_FMT_YVYU8_1_5X8:
|
||||
case MEDIA_BUS_FMT_YVYU8_2X8:
|
||||
case MEDIA_BUS_FMT_YVYU10_2X10:
|
||||
case MEDIA_BUS_FMT_YVYU8_1X16:
|
||||
case MEDIA_BUS_FMT_YVYU10_1X20:
|
||||
return CIF_YVU422I;
|
||||
case MEDIA_BUS_FMT_UYVY8_1_5X8:
|
||||
case MEDIA_BUS_FMT_UYVY8_2X8:
|
||||
case MEDIA_BUS_FMT_UYVY8_1X16:
|
||||
|
|
@ -132,6 +138,8 @@ static int cif_isp10_pix_fmt2img_src_v4l2_subdev_pix_fmt(
|
|||
switch (cif_isp10_pix_fmt) {
|
||||
case CIF_YUV422I:
|
||||
return MEDIA_BUS_FMT_YUYV8_2X8;
|
||||
case CIF_YVU422I:
|
||||
return MEDIA_BUS_FMT_YVYU8_2X8;
|
||||
case CIF_UYV422I:
|
||||
return MEDIA_BUS_FMT_UYVY8_2X8;
|
||||
case CIF_RGB565:
|
||||
|
|
@ -275,7 +283,7 @@ int cif_isp10_img_src_v4l2_subdev_enum_strm_fmts(
|
|||
|
||||
defrect.width = fie.width;
|
||||
defrect.height = fie.height;
|
||||
memset(&defrect, 0x00, sizeof(struct v4l2_rect));
|
||||
memset(&defrect.defrect, 0x00, sizeof(defrect.defrect));
|
||||
v4l2_subdev_call(subdev,
|
||||
core,
|
||||
ioctl,
|
||||
|
|
|
|||
|
|
@ -567,7 +567,7 @@ static int soc_init(struct pltfrm_soc_init_para *init)
|
|||
clk_rst->cif_clk_out =
|
||||
devm_clk_get(&pdev->dev, "clk_cif_out");
|
||||
clk_rst->cif_clk_pll =
|
||||
devm_clk_get(&pdev->dev, "cif_clk_pll");
|
||||
devm_clk_get(&pdev->dev, "clk_cif_pll");
|
||||
clk_rst->pclk_dphy_ref =
|
||||
devm_clk_get(&pdev->dev, "pclk_dphy_ref");
|
||||
|
||||
|
|
@ -610,7 +610,7 @@ static int soc_init(struct pltfrm_soc_init_para *init)
|
|||
clk_rst->cif_clk_out =
|
||||
devm_clk_get(&pdev->dev, "clk_cif_out");
|
||||
clk_rst->cif_clk_pll =
|
||||
devm_clk_get(&pdev->dev, "cif_clk_pll");
|
||||
devm_clk_get(&pdev->dev, "clk_cif_pll");
|
||||
clk_rst->pclk_dphy_ref =
|
||||
devm_clk_get(&pdev->dev, "pclk_dphy_ref");
|
||||
|
||||
|
|
|
|||
|
|
@ -343,6 +343,8 @@ static enum cif_isp10_pix_fmt cif_isp10_v4l2_pix_fmt2cif_isp10_pix_fmt(
|
|||
return CIF_YVU420SP;
|
||||
case V4L2_PIX_FMT_YUYV:
|
||||
return CIF_YUV422I;
|
||||
case V4L2_PIX_FMT_YVYU:
|
||||
return CIF_YVU422I;
|
||||
case V4L2_PIX_FMT_UYVY:
|
||||
return CIF_UYV422I;
|
||||
case V4L2_PIX_FMT_YUV422P:
|
||||
|
|
|
|||
|
|
@ -65,8 +65,13 @@
|
|||
*v0.1.8:
|
||||
*Fix oops error when soc_clk_disable is called in rk3399.
|
||||
*
|
||||
*v0.1.9:
|
||||
*1. Support bt656 signal interlace: odd and even field interlace generating
|
||||
*a frame image.
|
||||
*2. fix cif_isp10_img_src_v4l2_subdev_enum_strm_fmts defrect info get error.
|
||||
*3. fix cif_isp10_rk3399 cif_clk_pll info doesn't match with dts config.
|
||||
*/
|
||||
|
||||
#define CONFIG_CIFISP10_DRIVER_VERSION KERNEL_VERSION(0, 1, 8)
|
||||
#define CONFIG_CIFISP10_DRIVER_VERSION KERNEL_VERSION(0, 1, 9)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -47,12 +47,14 @@ enum pltfrm_cam_itf_type {
|
|||
PLTFRM_CAM_ITF_BT601_12 = 0x200000B1,
|
||||
PLTFRM_CAM_ITF_BT656_12 = 0x200000B2,
|
||||
PLTFRM_CAM_ITF_BT601_16 = 0x200000F1,
|
||||
PLTFRM_CAM_ITF_BT656_16 = 0x200000F2
|
||||
PLTFRM_CAM_ITF_BT656_16 = 0x200000F2,
|
||||
PLTFRM_CAM_ITF_BT656_8_INTERLACE = 0x20000172
|
||||
};
|
||||
|
||||
#define PLTFRM_CAM_ITF_MAIN_MASK 0xf0000000
|
||||
#define PLTFRM_CAM_ITF_SUB_MASK 0x0000000f
|
||||
#define PLTFRM_CAM_ITF_DVP_BW_MASK 0x000000f0
|
||||
#define PLTFRM_CAM_ITF_INTERLACE_MASK 0x00000100
|
||||
|
||||
#define PLTFRM_CAM_ITF_IS_MIPI(a) \
|
||||
(((a) & PLTFRM_CAM_ITF_MAIN_MASK) == 0x10000000)
|
||||
|
|
@ -64,6 +66,8 @@ enum pltfrm_cam_itf_type {
|
|||
(((a) & PLTFRM_CAM_ITF_SUB_MASK) == 0x01))
|
||||
#define PLTFRM_CAM_ITF_DVP_BW(a) \
|
||||
((((a) & PLTFRM_CAM_ITF_DVP_BW_MASK) >> 4) + 1)
|
||||
#define PLTFRM_CAM_ITF_INTERLACE(a) \
|
||||
(((a) & PLTFRM_CAM_ITF_INTERLACE_MASK) == 0x00000100)
|
||||
|
||||
struct pltfrm_cam_mipi_config {
|
||||
u32 dphy_index;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user