[PATCH 13/14] media: rockchip: cif: add support for rk3568 vicap

From: Michael Riesch
Date: Tue Feb 20 2024 - 04:45:16 EST


Add support for the Rockchip RK3568 video capture (VICAP) block.

Signed-off-by: Michael Riesch <michael.riesch@xxxxxxxxxxxxxx>
---
drivers/media/platform/rockchip/cif/cif-capture.c | 6 +
drivers/media/platform/rockchip/cif/cif-dev.c | 247 ++++++++++++++++++++++
drivers/media/platform/rockchip/cif/cif-regs.h | 9 +
3 files changed, 262 insertions(+)

diff --git a/drivers/media/platform/rockchip/cif/cif-capture.c b/drivers/media/platform/rockchip/cif/cif-capture.c
index dd5c45f28cdd..d0e8f3b49d38 100644
--- a/drivers/media/platform/rockchip/cif/cif-capture.c
+++ b/drivers/media/platform/rockchip/cif/cif-capture.c
@@ -340,6 +340,7 @@ static int cif_stream_start(struct cif_stream *stream)
u32 val, fmt_type, xfer_mode = 0;
struct cif_device *cif_dev = stream->cifdev;
struct cif_remote *remote_info = &cif_dev->remote;
+ struct v4l2_mbus_config_parallel *parallel;
int ret;
u32 input_mode;

@@ -351,6 +352,11 @@ static int cif_stream_start(struct cif_stream *stream)
CIF_FORMAT_INPUT_MODE_NTSC :
CIF_FORMAT_INPUT_MODE_PAL;

+ parallel = &cif_dev->vep.bus.parallel;
+ if ((parallel->bus_width == 16) &&
+ (parallel->flags & V4L2_MBUS_PCLK_SAMPLE_DUALEDGE))
+ xfer_mode |= CIF_FORMAT_BT1120_CLOCK_DOUBLE_EDGES;
+
val = input_mode | stream->cif_fmt_out->fmt_val |
stream->cif_fmt_in->dvp_fmt_val | xfer_mode;
cif_write(cif_dev, CIF_FOR, val);
diff --git a/drivers/media/platform/rockchip/cif/cif-dev.c b/drivers/media/platform/rockchip/cif/cif-dev.c
index 929ea39dd832..3b895b496c45 100644
--- a/drivers/media/platform/rockchip/cif/cif-dev.c
+++ b/drivers/media/platform/rockchip/cif/cif-dev.c
@@ -302,11 +302,258 @@ static const struct cif_match_data px30_cif_match_data = {
},
};

+static const struct cif_input_fmt rk3568_in_fmts[] = {
+ {
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YUYV,
+ .fmt_type = CIF_FMT_TYPE_YUV,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YUYV,
+ .fmt_type = CIF_FMT_TYPE_YUV,
+ .field = V4L2_FIELD_INTERLACED,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YVYU,
+ .fmt_type = CIF_FMT_TYPE_YUV,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YVYU,
+ .fmt_type = CIF_FMT_TYPE_YUV,
+ .field = V4L2_FIELD_INTERLACED,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_UYVY,
+ .fmt_type = CIF_FMT_TYPE_YUV,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_UYVY,
+ .fmt_type = CIF_FMT_TYPE_YUV,
+ .field = V4L2_FIELD_INTERLACED,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_VYUY,
+ .fmt_type = CIF_FMT_TYPE_YUV,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_VYUY,
+ .fmt_type = CIF_FMT_TYPE_YUV,
+ .field = V4L2_FIELD_INTERLACED,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+ CIF_FORMAT_INPUT_MODE_BT1120 |
+ CIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+ CIF_FORMAT_INPUT_MODE_BT1120,
+ .field = V4L2_FIELD_INTERLACED,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_YVYU8_1X16,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+ CIF_FORMAT_INPUT_MODE_BT1120 |
+ CIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_YVYU8_1X16,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+ CIF_FORMAT_INPUT_MODE_BT1120,
+ .field = V4L2_FIELD_INTERLACED,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+ CIF_FORMAT_INPUT_MODE_BT1120 |
+ CIF_FORMAT_BT1120_YC_SWAP |
+ CIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+ CIF_FORMAT_BT1120_YC_SWAP |
+ CIF_FORMAT_INPUT_MODE_BT1120,
+ .field = V4L2_FIELD_INTERLACED,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_VYUY8_1X16,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+ CIF_FORMAT_INPUT_MODE_BT1120 |
+ CIF_FORMAT_BT1120_YC_SWAP |
+ CIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_VYUY8_1X16,
+ .dvp_fmt_val = CIF_FORMAT_YUV_INPUT_422 |
+ CIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+ CIF_FORMAT_BT1120_YC_SWAP |
+ CIF_FORMAT_INPUT_MODE_BT1120,
+ .field = V4L2_FIELD_INTERLACED,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_8,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_8,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_8,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_8,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_10,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_10,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_10,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_10,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_12,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_12,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_12,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_12,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_RGB888_1X24,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_Y8_1X8,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_8,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_Y10_1X10,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_10,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_Y12_1X12,
+ .dvp_fmt_val = CIF_FORMAT_INPUT_MODE_RAW |
+ CIF_FORMAT_RAW_DATA_WIDTH_12,
+ .fmt_type = CIF_FMT_TYPE_RAW,
+ .field = V4L2_FIELD_NONE,
+ },
+};
+
+static struct clk_bulk_data rk3568_cif_clks[] = {
+ { .id = "aclk", },
+ { .id = "hclk", },
+ { .id = "dclk", },
+ { .id = "iclk", },
+};
+
+static void rk3568_grf_dvp_setup(struct cif_device *cif_dev)
+{
+ u32 con1 = RK3568_GRF_WRITE_ENABLE(RK3568_GRF_VI_CON1_CIF_DATAPATH);
+
+ if (cif_dev->vep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_DUALEDGE)
+ con1 |= RK3568_GRF_VI_CON1_CIF_DATAPATH;
+
+ regmap_write(cif_dev->grf, RK3568_GRF_VI_CON1, con1);
+}
+
+static const struct cif_match_data rk3568_cif_match_data = {
+ .clks = rk3568_cif_clks,
+ .clks_num = ARRAY_SIZE(rk3568_cif_clks),
+ .grf_dvp_setup = rk3568_grf_dvp_setup,
+ .in_fmts = rk3568_in_fmts,
+ .in_fmts_num = ARRAY_SIZE(rk3568_in_fmts),
+ .has_scaler = false,
+ .regs = {
+ [CIF_CTRL] = 0x00,
+ [CIF_INTEN] = 0x04,
+ [CIF_INTSTAT] = 0x08,
+ [CIF_FOR] = 0x0c,
+ [CIF_LINE_NUM_ADDR] = 0x2c,
+ [CIF_FRM0_ADDR_Y] = 0x14,
+ [CIF_FRM0_ADDR_UV] = 0x18,
+ [CIF_FRM1_ADDR_Y] = 0x1c,
+ [CIF_FRM1_ADDR_UV] = 0x20,
+ [CIF_VIR_LINE_WIDTH] = 0x24,
+ [CIF_SET_SIZE] = 0x28,
+ [CIF_FRAME_STATUS] = 0x3c,
+ [CIF_LAST_LINE] = 0x44,
+ [CIF_LAST_PIX] = 0x48,
+ },
+};
+
static const struct of_device_id cif_plat_of_match[] = {
{
.compatible = "rockchip,px30-vip",
.data = &px30_cif_match_data,
},
+ {
+ .compatible = "rockchip,rk3568-vicap",
+ .data = &rk3568_cif_match_data,
+ },
{},
};

diff --git a/drivers/media/platform/rockchip/cif/cif-regs.h b/drivers/media/platform/rockchip/cif/cif-regs.h
index 2ce756fde204..261bc71240f2 100644
--- a/drivers/media/platform/rockchip/cif/cif-regs.h
+++ b/drivers/media/platform/rockchip/cif/cif-regs.h
@@ -117,4 +117,13 @@ enum cif_register {
#define CIF_CROP_Y_SHIFT 16
#define CIF_CROP_X_SHIFT 0

+/* GRF register offsets */
+#define RK3568_GRF_VI_CON0 0x340
+#define RK3568_GRF_VI_CON1 0x344
+#define RK3568_GRF_VI_STATUS0 0x348
+
+#define RK3568_GRF_VI_CON1_CIF_DATAPATH BIT(9)
+
+#define RK3568_GRF_WRITE_ENABLE(x) ((x) << 16)
+
#endif

--
2.30.2