From 832a2e67a9a3e34dcfcbdec76e1bdfa841cb4bac Mon Sep 17 00:00:00 2001 From: Allon Huang Date: Thu, 2 Apr 2020 13:45:00 +0800 Subject: [PATCH] drivers: media: platform: rockchip: cif: single dvp channel can sample data for rv1126/rv1109 fix reg address conflict between rv1126/rv1109 and other chips Signed-off-by: Allon Huang Change-Id: I12c0291a24068ea385369d8c4aa371385992f8cd --- drivers/media/platform/rockchip/cif/capture.c | 21 ++++-- drivers/media/platform/rockchip/cif/dev.c | 74 +++++++++++++++++-- drivers/media/platform/rockchip/cif/dev.h | 1 + drivers/media/platform/rockchip/cif/regs.h | 7 ++ drivers/media/platform/rockchip/cif/version.h | 4 +- 5 files changed, 92 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 801ebbd66613..8d565213a8ed 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -1300,7 +1300,8 @@ static int rkcif_stream_start(struct rkcif_stream *stream) rkcif_write_register(dev, CIF_REG_DVP_INTSTAT, INTSTAT_CLS); rkcif_write_register(dev, CIF_REG_DVP_SCL_CTRL, rkcif_scl_ctl(stream)); - if (dev->chip_id == CHIP_RK1808_CIF && + if ((dev->chip_id == CHIP_RK1808_CIF || + dev->chip_id == CHIP_RV1126_CIF) && rkcif_determine_input_mode(stream) == INPUT_MODE_BT1120) rkcif_assign_new_buffer_pingpong(stream, 1, 0); else @@ -1318,7 +1319,8 @@ static int rkcif_stream_start(struct rkcif_stream *stream) else workmode = MODE_LINELOOP; - if (dev->chip_id == CHIP_RK1808_CIF && + if ((dev->chip_id == CHIP_RK1808_CIF || + dev->chip_id == CHIP_RV1126_CIF) && rkcif_determine_input_mode(stream) == INPUT_MODE_BT1120) { dev->workmode = RKCIF_WORKMODE_PINGPONG; rkcif_write_register(dev, CIF_REG_DVP_CTRL, @@ -1439,7 +1441,8 @@ static int rkcif_start_streaming(struct vb2_queue *queue, unsigned int count) goto runtime_put; } - if (dev->chip_id == CHIP_RK1808_CIF) { + if (dev->chip_id == CHIP_RK1808_CIF || + dev->chip_id == CHIP_RV1126_CIF) { if (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2) ret = rkcif_csi_stream_start(stream); else @@ -1654,7 +1657,8 @@ static int rkcif_fh_open(struct file *filp) * Because CRU would reset iommu too, so there's not chance * to reset cif once we hold buffers after buf queued */ - if (cifdev->chip_id == CHIP_RK1808_CIF) { + if (cifdev->chip_id == CHIP_RK1808_CIF || + cifdev->chip_id == CHIP_RV1126_CIF) { mutex_lock(&cifdev->stream_lock); if (!atomic_read(&cifdev->fh_cnt)) rkcif_soft_reset(cifdev, true); @@ -2053,7 +2057,8 @@ void rkcif_irq_oneframe(struct rkcif_device *cif_dev) * - PST_INF_FRAME_END: cif FIFO is ready, this is prior to FRAME_END * - FRAME_END: cif has saved frame to memory, a frame ready */ - if (cif_dev->chip_id == CHIP_RK1808_CIF) + if (cif_dev->chip_id == CHIP_RK1808_CIF || + cif_dev->chip_id == CHIP_RV1126_CIF) stream = &cif_dev->stream[RKCIF_STREAM_DVP]; else stream = &cif_dev->stream[RKCIF_STREAM_CIF]; @@ -2169,7 +2174,8 @@ void rkcif_irq_pingpong(struct rkcif_device *cif_dev) unsigned int intstat, i = 0xff; if (cif_dev->active_sensor->mbus.type == V4L2_MBUS_CSI2 && - cif_dev->chip_id == CHIP_RK1808_CIF) { + (cif_dev->chip_id == CHIP_RK1808_CIF || + cif_dev->chip_id == CHIP_RV1126_CIF)) { int mipi_id; struct vb2_v4l2_buffer *vb_done = NULL; u32 lastline = 0; @@ -2268,7 +2274,8 @@ void rkcif_irq_pingpong(struct rkcif_device *cif_dev) lastpix = CIF_FETCH_Y_LAST_LINE(lastpix); ctl = rkcif_read_register(cif_dev, CIF_REG_DVP_CTRL); - if (cif_dev->chip_id == CHIP_RK1808_CIF) + if (cif_dev->chip_id == CHIP_RK1808_CIF || + cif_dev->chip_id == CHIP_RV1126_CIF) stream = &cif_dev->stream[RKCIF_STREAM_DVP]; else stream = &cif_dev->stream[RKCIF_STREAM_CIF]; diff --git a/drivers/media/platform/rockchip/cif/dev.c b/drivers/media/platform/rockchip/cif/dev.c index 59c7ca51daf2..cdfe2c7f2723 100644 --- a/drivers/media/platform/rockchip/cif/dev.c +++ b/drivers/media/platform/rockchip/cif/dev.c @@ -201,7 +201,8 @@ static int rkcif_create_links(struct rkcif_device *dev) u32 flags; unsigned int s, pad, id, stream_num = 0; - if (dev->chip_id == CHIP_RK1808_CIF) + if (dev->chip_id == CHIP_RK1808_CIF || + dev->chip_id == CHIP_RV1126_CIF) stream_num = RKCIF_MULTI_STREAMS_NUM; else stream_num = RKCIF_SINGLE_STREAM; @@ -224,7 +225,8 @@ static int rkcif_create_links(struct rkcif_device *dev) if ((sensor->mbus.type == V4L2_MBUS_BT656 || sensor->mbus.type == V4L2_MBUS_PARALLEL) && - dev->chip_id == CHIP_RK1808_CIF) { + (dev->chip_id == CHIP_RK1808_CIF || + dev->chip_id == CHIP_RV1126_CIF)) { source_entity = &sensor->sd->entity; sink_entity = &dev->stream[RKCIF_STREAM_DVP].vnode.vdev.entity; @@ -243,7 +245,7 @@ static int rkcif_create_links(struct rkcif_device *dev) source_entity = &sensor->sd->entity; sink_entity = &dev->stream[id].vnode.vdev.entity; - (dev->chip_id != CHIP_RK1808_CIF) | (id == pad - 1) ? + (dev->chip_id != CHIP_RK1808_CIF && dev->chip_id != CHIP_RV1126_CIF) | (id == pad - 1) ? (flags = MEDIA_LNK_FL_ENABLED) : (flags = 0); ret = media_create_pad_link(source_entity, @@ -381,7 +383,8 @@ static int rkcif_register_platform_subdevs(struct rkcif_device *cif_dev) { int stream_num = 0, ret; - if (cif_dev->chip_id == CHIP_RK1808_CIF) { + if (cif_dev->chip_id == CHIP_RK1808_CIF || + cif_dev->chip_id == CHIP_RV1126_CIF) { stream_num = RKCIF_MULTI_STREAMS_NUM; ret = rkcif_register_stream_vdevs(cif_dev, stream_num, true); @@ -583,6 +586,47 @@ static const char * const rk3328_cif_rsts[] = { "rst_cif_h", }; +static const char * const rv1126_cif_clks[] = { + "aclk_cif", + "hclk_cif", + "aclk_cif_lite", + "hclk_cif_lite", +}; + +static const char * const rv1126_cif_rsts[] = { + "rst_cif_a", + "rst_cif_h", + "rst_cif_d", + "rst_cif_p", + "rst_cif_i", + "rst_cif_rx_p", + "rst_cif_lite_a", + "rst_cif_lite_h", + "rst_cif_lite_d", + "rst_cif_lite_rx_p", +}; + +static const struct cif_reg rv1126_cif_regs[] = { + [CIF_REG_DVP_CTRL] = CIF_REG(CIF_CTRL), + [CIF_REG_DVP_INTEN] = CIF_REG(CIF_INTEN), + [CIF_REG_DVP_INTSTAT] = CIF_REG(CIF_INTSTAT), + [CIF_REG_DVP_FOR] = CIF_REG(CIF_FOR), + [CIF_REG_DVP_MULTI_ID] = CIF_REG(CIF_MULTI_ID), + [CIF_REG_DVP_FRM0_ADDR_Y] = CIF_REG(CIF_FRM0_ADDR_Y), + [CIF_REG_DVP_FRM0_ADDR_UV] = CIF_REG(CIF_FRM0_ADDR_UV), + [CIF_REG_DVP_FRM1_ADDR_Y] = CIF_REG(CIF_FRM1_ADDR_Y), + [CIF_REG_DVP_FRM1_ADDR_UV] = CIF_REG(CIF_FRM1_ADDR_UV), + [CIF_REG_DVP_VIR_LINE_WIDTH] = CIF_REG(CIF_VIR_LINE_WIDTH), + [CIF_REG_DVP_SET_SIZE] = CIF_REG(CIF_SET_SIZE), + [CIF_REG_DVP_LINE_INT_NUM] = CIF_REG(CIF_LINE_INT_NUM), + [CIF_REG_DVP_LINE_CNT] = CIF_REG(CIF_LINE_CNT), + [CIF_REG_DVP_CROP] = CIF_REG(RV1126_CIF_CROP), + [CIF_REG_DVP_FRAME_STATUS] = CIF_REG(RV1126_CIF_FRAME_STATUS), + [CIF_REG_DVP_CUR_DST] = CIF_REG(RV1126_CIF_CUR_DST), + [CIF_REG_DVP_LAST_LINE] = CIF_REG(RV1126_CIF_LAST_LINE), + [CIF_REG_DVP_LAST_PIX] = CIF_REG(RV1126_CIF_LAST_PIX), +}; + static const struct cif_match_data px30_cif_match_data = { .chip_id = CHIP_PX30_CIF, .clks = px30_cif_clks, @@ -628,6 +672,15 @@ static const struct cif_match_data rk3328_cif_match_data = { .cif_regs = rk3328_cif_regs, }; +static const struct cif_match_data rv1126_cif_match_data = { + .chip_id = CHIP_RV1126_CIF, + .clks = rv1126_cif_clks, + .clks_num = ARRAY_SIZE(rv1126_cif_clks), + .rsts = rv1126_cif_rsts, + .rsts_num = ARRAY_SIZE(rv1126_cif_rsts), + .cif_regs = rv1126_cif_regs, +}; + static const struct of_device_id rkcif_plat_of_match[] = { { .compatible = "rockchip,px30-cif", @@ -649,6 +702,10 @@ static const struct of_device_id rkcif_plat_of_match[] = { .compatible = "rockchip,rk3328-cif", .data = &rk3328_cif_match_data, }, + { + .compatible = "rockchip,rv1126-cif", + .data = &rv1126_cif_match_data, + }, {}, }; @@ -786,7 +843,8 @@ static int rkcif_plat_probe(struct platform_device *pdev) cif_dev->irq = irq; data = match->data; cif_dev->chip_id = data->chip_id; - if (data->chip_id == CHIP_RK1808_CIF) { + if (data->chip_id == CHIP_RK1808_CIF || + data->chip_id == CHIP_RV1126_CIF) { res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cif_regs"); @@ -849,7 +907,8 @@ static int rkcif_plat_probe(struct platform_device *pdev) cif_dev->pipe.close = rkcif_pipeline_close; cif_dev->pipe.set_stream = rkcif_pipeline_set_stream; - if (data->chip_id == CHIP_RK1808_CIF) { + if (data->chip_id == CHIP_RK1808_CIF || + data->chip_id == CHIP_RV1126_CIF) { rkcif_stream_init(cif_dev, RKCIF_STREAM_MIPI_ID0); rkcif_stream_init(cif_dev, RKCIF_STREAM_MIPI_ID1); rkcif_stream_init(cif_dev, RKCIF_STREAM_MIPI_ID2); @@ -929,7 +988,8 @@ static int rkcif_plat_remove(struct platform_device *pdev) media_device_unregister(&cif_dev->media_dev); v4l2_device_unregister(&cif_dev->v4l2_dev); - if (cif_dev->chip_id == CHIP_RK1808_CIF) + if (cif_dev->chip_id == CHIP_RK1808_CIF || + cif_dev->chip_id == CHIP_RV1126_CIF) stream_num = RKCIF_MULTI_STREAMS_NUM; else stream_num = RKCIF_SINGLE_STREAM; diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index b939e357e584..b8d524c88eb3 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -80,6 +80,7 @@ enum rkcif_chip_id { CHIP_RK3128_CIF, CHIP_RK3288_CIF, CHIP_RK3328_CIF, + CHIP_RV1126_CIF, }; enum host_type_t { diff --git a/drivers/media/platform/rockchip/cif/regs.h b/drivers/media/platform/rockchip/cif/regs.h index b44278657d58..1fc54a383a22 100644 --- a/drivers/media/platform/rockchip/cif/regs.h +++ b/drivers/media/platform/rockchip/cif/regs.h @@ -73,6 +73,7 @@ enum cif_reg_index { #define CIF_WB_LOW_FILTER 0x3c #define CIF_WBC_CNT 0x40 #define CIF_CROP 0x44 +#define RV1126_CIF_CROP 0x34 #define CIF_SCL_CTRL 0x48 #define CIF_PATH_SEL 0x48 #define CIF_SCL_DST 0x4c @@ -81,9 +82,15 @@ enum cif_reg_index { #define CIF_FIFO_ENTRY 0x54 #define CIF_LINE_LOOP_CTR 0x58 #define CIF_FRAME_STATUS 0x60 +#define RV1126_CIF_FRAME_STATUS 0x3c #define CIF_CUR_DST 0x64 +#define RV1126_CIF_CUR_DST 0x40 #define CIF_LAST_LINE 0x68 +#define RV1126_CIF_LAST_LINE 0x44 #define CIF_LAST_PIX 0x6c +#define RV1126_CIF_LAST_PIX 0x48 +#define CIF_MULTI_ID 0x10 + #define CIF_FETCH_Y_LAST_LINE(val) ((val) & 0x1fff) /* Check if swap y and c in bt1120 mode */ #define CIF_FETCH_IS_Y_FIRST(val) ((val) & 0xf) diff --git a/drivers/media/platform/rockchip/cif/version.h b/drivers/media/platform/rockchip/cif/version.h index 1dfed49ec7a4..a947adf71aec 100644 --- a/drivers/media/platform/rockchip/cif/version.h +++ b/drivers/media/platform/rockchip/cif/version.h @@ -23,8 +23,10 @@ *8. fix dvp camera fails to link with cif on rk1808 *9. add camera support hotplug for n4 *10. reconstruct register's reading and writing + *v0.1.3 + *1. support kernel-4.19 and support vicap single dvp for rv1126 */ -#define RKCIF_DRIVER_VERSION KERNEL_VERSION(0, 1, 0x2) +#define RKCIF_DRIVER_VERSION KERNEL_VERSION(0, 1, 0x3) #endif