From f3019c0e9244e8df24829195bc76d680941b59b1 Mon Sep 17 00:00:00 2001 From: Jianwei Fan Date: Fri, 29 Mar 2024 17:20:58 +0800 Subject: [PATCH] video: rockchip: vehicle: use hardware interlace for rk3576 when interlace input Signed-off-by: Jianwei Fan Change-Id: I8912cf794963e0f5f315f6e7b958f5194b657151 --- drivers/video/rockchip/vehicle/vehicle_cif.c | 27 +++++++++++++++----- drivers/video/rockchip/vehicle/vehicle_cif.h | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/video/rockchip/vehicle/vehicle_cif.c b/drivers/video/rockchip/vehicle/vehicle_cif.c index 4420c9bd2d3a..082ed3b92881 100644 --- a/drivers/video/rockchip/vehicle/vehicle_cif.c +++ b/drivers/video/rockchip/vehicle/vehicle_cif.c @@ -3045,12 +3045,15 @@ static int vehicle_cif_csi_channel_init(struct vehicle_cif *cif, if (cfg->input_format == CIF_INPUT_FORMAT_PAL || cfg->input_format == CIF_INPUT_FORMAT_NTSC) { VEHICLE_INFO("CVBS IN PAL or NTSC config."); - channel->virtual_width *= 2; cif->interlaced_enable = true; - cif->interlaced_offset = channel->width; - cif->interlaced_counts = 0; - cif->interlaced_buffer = 0; - channel->height /= 2; + if (!cif->use_hw_interlace) { + channel->virtual_width *= 2; + cif->interlaced_offset = channel->width; + cif->interlaced_counts = 0; + cif->interlaced_buffer = 0; + channel->height /= 2; + } + VEHICLE_INFO("do denterlaced.\n"); } @@ -3572,9 +3575,13 @@ static int vehicle_cif_csi2_s_stream_v1(struct vehicle_cif *cif, if (!infmt) { VEHICLE_INFO("Input fmt is invalid, use default!\n"); val |= CSI_YUV_INPUT_ORDER_UYVY; + } else if (cif->interlaced_enable) { + val |= (infmt->csi_yuv_order >> 4) | + ((infmt->csi_fmt_val + 1) << 4); } else { val |= (infmt->csi_yuv_order >> 4) | (infmt->csi_fmt_val << 4); } + if (cfg->output_format == CIF_OUTPUT_FORMAT_420) { if (find_output_fmt(V4L2_PIX_FMT_NV12)) val |= CSI_WRDDR_TYPE_YUV420SP_RK3588 << 3 | @@ -4304,7 +4311,7 @@ static int vehicle_cif_next_buffer(struct vehicle_cif *cif, u32 frame_ready, int spin_lock(&cif->vbq_lock); - if (!cif->interlaced_enable) { + if (!cif->interlaced_enable || cif->use_hw_interlace) { temp_y_addr = vehicle_flinger_request_cif_buffer(); if (temp_y_addr == 0) { VEHICLE_INFO("%s,warnning request buffer failed\n", __func__); @@ -4327,7 +4334,7 @@ static int vehicle_cif_next_buffer(struct vehicle_cif *cif, u32 frame_ready, int y_addr = temp_y_addr; uv_addr = temp_uv_addr; commit_buf = 0; - } else { + } else if (cif->interlaced_enable && !cif->use_hw_interlace) { if ((frame_id != 0 && (frame_id & 0xffff) % 2 == 0) || (frame_id == 0 && (cif->interlaced_counts % 2 == 0))) { temp_y_addr = vehicle_flinger_request_cif_buffer(); @@ -5625,6 +5632,12 @@ int vehicle_cif_init(struct vehicle_cif *cif) } mutex_init(&dphy_hw->mutex); } + + if (cif->inf_id == RKCIF_MIPI_LVDS && cif->chip_id <= CHIP_RK3562_VEHICLE_CIF) + cif->use_hw_interlace = false; + else + cif->use_hw_interlace = true; + /* 9. init waitqueue */ atomic_set(&cif->reset_status, 0); init_waitqueue_head(&cif->wq_stopped); diff --git a/drivers/video/rockchip/vehicle/vehicle_cif.h b/drivers/video/rockchip/vehicle/vehicle_cif.h index f31de6a63366..48481034c92a 100644 --- a/drivers/video/rockchip/vehicle/vehicle_cif.h +++ b/drivers/video/rockchip/vehicle/vehicle_cif.h @@ -149,6 +149,7 @@ struct vehicle_cif { struct mutex stream_lock; enum rkcif_state state; struct vehicle_csi2_err_state_work err_state; + bool use_hw_interlace; }; int vehicle_cif_init_mclk(struct vehicle_cif *cif);