From: Michael Riesch <michael.riesch@collabora.com>
The RK3588 Video Capture (VICAP) unit features a Digital Video Port
(DVP) and six MIPI CSI-2 capture interfaces. Add initial support
for this variant to the rkcif driver and enable the MIPI CSI-2
capture interfaces.
Signed-off-by: Michael Riesch <michael.riesch@collabora.com>
---
.../platform/rockchip/rkcif/rkcif-capture-mipi.c | 136 +++++++++++++++++++++
.../platform/rockchip/rkcif/rkcif-capture-mipi.h | 1 +
.../media/platform/rockchip/rkcif/rkcif-common.h | 2 +-
drivers/media/platform/rockchip/rkcif/rkcif-dev.c | 18 +++
4 files changed, 156 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
index 9e67160a16e4..aa70d3e9db04 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
@@ -30,10 +30,18 @@
#define RK3568_MIPI_CTRL0_CROP_EN BIT(5)
#define RK3568_MIPI_CTRL0_WRDDR(type) ((type) << 1)
+#define RK3588_MIPI_CTRL0_DMA_EN BIT(28)
+#define RK3588_MIPI_CTRL0_HIGH_ALIGN BIT(27)
+#define RK3588_MIPI_CTRL0_WRDDR(type) ((type) << 5)
+#define RK3588_MIPI_CTRL0_CROP_EN BIT(4)
+#define RK3588_MIPI_CTRL0_PARSE(type) ((type) << 1)
+
#define RKCIF_MIPI_CTRL0_DT_ID(id) ((id) << 10)
#define RKCIF_MIPI_CTRL0_VC_ID(id) ((id) << 8)
#define RKCIF_MIPI_CTRL0_CAP_EN BIT(0)
+#define RKCIF_MIPI_CTRL_CAP_EN BIT(0)
+
#define RKCIF_MIPI_INT_FRAME0_END(id) BIT(8 + (id) * 2 + 0)
#define RKCIF_MIPI_INT_FRAME1_END(id) BIT(8 + (id) * 2 + 1)
@@ -481,6 +489,132 @@ const struct rkcif_mipi_match_data rkcif_rk3568_vicap_mipi_match_data = {
},
};
+static u32
+rkcif_rk3588_mipi_ctrl0(struct rkcif_stream *stream,
+ const struct rkcif_output_fmt *active_out_fmt)
+{
+ u32 ctrl0 = 0;
+
+ ctrl0 |= RK3588_MIPI_CTRL0_DMA_EN;
+ ctrl0 |= RKCIF_MIPI_CTRL0_DT_ID(active_out_fmt->mipi.dt);
+ ctrl0 |= RK3588_MIPI_CTRL0_CROP_EN;
+ ctrl0 |= RKCIF_MIPI_CTRL0_CAP_EN;
+
+ switch (active_out_fmt->mipi.type) {
+ case RKCIF_MIPI_TYPE_RAW8:
+ break;
+ case RKCIF_MIPI_TYPE_RAW10:
+ ctrl0 |= RK3588_MIPI_CTRL0_PARSE(0x1);
+ if (!active_out_fmt->mipi.compact)
+ ctrl0 |= RK3588_MIPI_CTRL0_WRDDR(0x1);
+ break;
+ case RKCIF_MIPI_TYPE_RAW12:
+ ctrl0 |= RK3588_MIPI_CTRL0_PARSE(0x2);
+ if (!active_out_fmt->mipi.compact)
+ ctrl0 |= RK3588_MIPI_CTRL0_WRDDR(0x1);
+ break;
+ case RKCIF_MIPI_TYPE_RGB888:
+ break;
+ case RKCIF_MIPI_TYPE_YUV422SP:
+ ctrl0 |= RK3588_MIPI_CTRL0_WRDDR(0x4);
+ break;
+ case RKCIF_MIPI_TYPE_YUV420SP:
+ ctrl0 |= RK3588_MIPI_CTRL0_WRDDR(0x5);
+ break;
+ case RKCIF_MIPI_TYPE_YUV400:
+ ctrl0 |= RK3588_MIPI_CTRL0_WRDDR(0x3);
+ break;
+ default:
+ break;
+ }
+
+ return ctrl0;
+}
+
+const struct rkcif_mipi_match_data rkcif_rk3588_vicap_mipi_match_data = {
+ .mipi_num = 6,
+ .mipi_ctrl0 = rkcif_rk3588_mipi_ctrl0,
+ .regs = {
+ [RKCIF_MIPI_CTRL] = 0x20,
+ [RKCIF_MIPI_INTEN] = 0x74,
+ [RKCIF_MIPI_INTSTAT] = 0x78,
+ },
+ .regs_id = {
+ [RKCIF_ID0] = {
+ [RKCIF_MIPI_CTRL0] = 0x00,
+ [RKCIF_MIPI_CTRL1] = 0x04,
+ [RKCIF_MIPI_FRAME0_ADDR_Y] = 0x24,
+ [RKCIF_MIPI_FRAME0_ADDR_UV] = 0x2c,
+ [RKCIF_MIPI_FRAME0_VLW_Y] = 0x34,
+ [RKCIF_MIPI_FRAME0_VLW_UV] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_FRAME1_ADDR_Y] = 0x28,
+ [RKCIF_MIPI_FRAME1_ADDR_UV] = 0x30,
+ [RKCIF_MIPI_FRAME1_VLW_Y] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_FRAME1_VLW_UV] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_CROP_START] = 0x8c,
+ },
+ [RKCIF_ID1] = {
+ [RKCIF_MIPI_CTRL0] = 0x08,
+ [RKCIF_MIPI_CTRL1] = 0x0c,
+ [RKCIF_MIPI_FRAME0_ADDR_Y] = 0x38,
+ [RKCIF_MIPI_FRAME0_ADDR_UV] = 0x40,
+ [RKCIF_MIPI_FRAME0_VLW_Y] = 0x48,
+ [RKCIF_MIPI_FRAME0_VLW_UV] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_FRAME1_ADDR_Y] = 0x3c,
+ [RKCIF_MIPI_FRAME1_ADDR_UV] = 0x44,
+ [RKCIF_MIPI_FRAME1_VLW_Y] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_FRAME1_VLW_UV] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_CROP_START] = 0x90,
+ },
+ [RKCIF_ID2] = {
+ [RKCIF_MIPI_CTRL0] = 0x10,
+ [RKCIF_MIPI_CTRL1] = 0x14,
+ [RKCIF_MIPI_FRAME0_ADDR_Y] = 0x4c,
+ [RKCIF_MIPI_FRAME0_ADDR_UV] = 0x54,
+ [RKCIF_MIPI_FRAME0_VLW_Y] = 0x5c,
+ [RKCIF_MIPI_FRAME0_VLW_UV] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_FRAME1_ADDR_Y] = 0x50,
+ [RKCIF_MIPI_FRAME1_ADDR_UV] = 0x58,
+ [RKCIF_MIPI_FRAME1_VLW_Y] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_FRAME1_VLW_UV] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_CROP_START] = 0x94,
+ },
+ [RKCIF_ID3] = {
+ [RKCIF_MIPI_CTRL0] = 0x18,
+ [RKCIF_MIPI_CTRL1] = 0x1c,
+ [RKCIF_MIPI_FRAME0_ADDR_Y] = 0x60,
+ [RKCIF_MIPI_FRAME0_ADDR_UV] = 0x68,
+ [RKCIF_MIPI_FRAME0_VLW_Y] = 0x70,
+ [RKCIF_MIPI_FRAME0_VLW_UV] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_FRAME1_ADDR_Y] = 0x64,
+ [RKCIF_MIPI_FRAME1_ADDR_UV] = 0x6c,
+ [RKCIF_MIPI_FRAME1_VLW_Y] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_FRAME1_VLW_UV] = RKCIF_REGISTER_NOTSUPPORTED,
+ [RKCIF_MIPI_CROP_START] = 0x98,
+ },
+ },
+ .blocks = {
+ {
+ .offset = 0x100,
+ },
+ {
+ .offset = 0x200,
+ },
+ {
+ .offset = 0x300,
+ },
+ {
+ .offset = 0x400,
+ },
+ {
+ .offset = 0x500,
+ },
+ {
+ .offset = 0x600,
+ },
+ },
+};
+
static inline unsigned int rkcif_mipi_get_reg(struct rkcif_interface *interface,
unsigned int index)
{
@@ -631,6 +765,8 @@ static int rkcif_mipi_start_streaming(struct rkcif_stream *stream)
rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL1, ctrl1);
rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, ctrl0);
+ rkcif_mipi_write(interface, RKCIF_MIPI_CTRL, RKCIF_MIPI_CTRL_CAP_EN);
+
ret = 0;
out:
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h
index 7f16eadc474c..7edaca44f653 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h
@@ -13,6 +13,7 @@
#include "rkcif-common.h"
extern const struct rkcif_mipi_match_data rkcif_rk3568_vicap_mipi_match_data;
+extern const struct rkcif_mipi_match_data rkcif_rk3588_vicap_mipi_match_data;
int rkcif_mipi_register(struct rkcif_device *rkcif);
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
index dd92cfbc879f..4d9211ba9bda 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-common.h
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
@@ -27,7 +27,7 @@
#include "rkcif-regs.h"
#define RKCIF_DRIVER_NAME "rockchip-cif"
-#define RKCIF_CLK_MAX 4
+#define RKCIF_CLK_MAX 5
enum rkcif_format_type {
RKCIF_FMT_TYPE_INVALID,
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
index b4cf1146f131..c8542398b7f0 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
@@ -53,6 +53,20 @@ static const struct rkcif_match_data rk3568_vicap_match_data = {
.mipi = &rkcif_rk3568_vicap_mipi_match_data,
};
+static const char *const rk3588_vicap_clks[] = {
+ "aclk",
+ "hclk",
+ "dclk",
+ "iclk0",
+ "iclk1",
+};
+
+static const struct rkcif_match_data rk3588_vicap_match_data = {
+ .clks = rk3588_vicap_clks,
+ .clks_num = ARRAY_SIZE(rk3588_vicap_clks),
+ .mipi = &rkcif_rk3588_vicap_mipi_match_data,
+};
+
static const struct of_device_id rkcif_plat_of_match[] = {
{
.compatible = "rockchip,px30-vip",
@@ -62,6 +76,10 @@ static const struct of_device_id rkcif_plat_of_match[] = {
.compatible = "rockchip,rk3568-vicap",
.data = &rk3568_vicap_match_data,
},
+ {
+ .compatible = "rockchip,rk3588-vicap",
+ .data = &rk3588_vicap_match_data,
+ },
{}
};
MODULE_DEVICE_TABLE(of, rkcif_plat_of_match);
--
2.39.5
Hi Michael,
Thank you for this nice patch!
On Tue, Mar 17, 2026 at 10:32:21AM +0100, Michael Riesch via B4 Relay wrote:
> From: Michael Riesch <michael.riesch@collabora.com>
>
> The RK3588 Video Capture (VICAP) unit features a Digital Video Port
> (DVP) and six MIPI CSI-2 capture interfaces. Add initial support
> for this variant to the rkcif driver and enable the MIPI CSI-2
> capture interfaces.
>
> Signed-off-by: Michael Riesch <michael.riesch@collabora.com>
[...]
> static inline unsigned int rkcif_mipi_get_reg(struct rkcif_interface *interface,
> unsigned int index)
> {
> @@ -631,6 +765,8 @@ static int rkcif_mipi_start_streaming(struct rkcif_stream *stream)
> rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL1, ctrl1);
> rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, ctrl0);
>
> + rkcif_mipi_write(interface, RKCIF_MIPI_CTRL, RKCIF_MIPI_CTRL_CAP_EN);
> +
while this is the correct solution for rk3588, for the rk3568 vicap this
will write 0x1 to the VICAP_MIPI_CTRL : 0x00A0 which will enable the water line.
--
Kind Regards
Mehdi Djait
Hi Mehdi,
On 3/17/26 14:08, Mehdi Djait wrote:
> Hi Michael,
>
> Thank you for this nice patch!
>
> On Tue, Mar 17, 2026 at 10:32:21AM +0100, Michael Riesch via B4 Relay wrote:
>> From: Michael Riesch <michael.riesch@collabora.com>
>>
>> The RK3588 Video Capture (VICAP) unit features a Digital Video Port
>> (DVP) and six MIPI CSI-2 capture interfaces. Add initial support
>> for this variant to the rkcif driver and enable the MIPI CSI-2
>> capture interfaces.
>>
>> Signed-off-by: Michael Riesch <michael.riesch@collabora.com>
>
> [...]
>
>> static inline unsigned int rkcif_mipi_get_reg(struct rkcif_interface *interface,
>> unsigned int index)
>> {
>> @@ -631,6 +765,8 @@ static int rkcif_mipi_start_streaming(struct rkcif_stream *stream)
>> rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL1, ctrl1);
>> rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, ctrl0);
>>
>> + rkcif_mipi_write(interface, RKCIF_MIPI_CTRL, RKCIF_MIPI_CTRL_CAP_EN);
>> +
>
> while this is the correct solution for rk3588, for the rk3568 vicap this
> will write 0x1 to the VICAP_MIPI_CTRL : 0x00A0 which will enable the water line.
nice catch ;-) However, the TRM (at least my version) claims that this
bit has a reset value of 0x1, so the bit in question should be already
set in the first place. Thus I decided to *not* make variant specific
code paths.
Do you see problems in your setup?
>
> --
> Kind Regards
> Mehdi Djait
Best regards,
Michael
Hi Michael,
On Tue, Mar 17, 2026 at 02:21:20PM +0100, Michael Riesch wrote:
> Hi Mehdi,
>
> On 3/17/26 14:08, Mehdi Djait wrote:
> > Hi Michael,
> >
> > Thank you for this nice patch!
> >
> > On Tue, Mar 17, 2026 at 10:32:21AM +0100, Michael Riesch via B4 Relay wrote:
> >> From: Michael Riesch <michael.riesch@collabora.com>
> >>
> >> The RK3588 Video Capture (VICAP) unit features a Digital Video Port
> >> (DVP) and six MIPI CSI-2 capture interfaces. Add initial support
> >> for this variant to the rkcif driver and enable the MIPI CSI-2
> >> capture interfaces.
> >>
> >> Signed-off-by: Michael Riesch <michael.riesch@collabora.com>
> >
> > [...]
> >
> >> static inline unsigned int rkcif_mipi_get_reg(struct rkcif_interface *interface,
> >> unsigned int index)
> >> {
> >> @@ -631,6 +765,8 @@ static int rkcif_mipi_start_streaming(struct rkcif_stream *stream)
> >> rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL1, ctrl1);
> >> rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, ctrl0);
> >>
> >> + rkcif_mipi_write(interface, RKCIF_MIPI_CTRL, RKCIF_MIPI_CTRL_CAP_EN);
> >> +
> >
> > while this is the correct solution for rk3588, for the rk3568 vicap this
> > will write 0x1 to the VICAP_MIPI_CTRL : 0x00A0 which will enable the water line.
>
> nice catch ;-) However, the TRM (at least my version) claims that this
> bit has a reset value of 0x1, so the bit in question should be already
> set in the first place. Thus I decided to *not* make variant specific
> code paths.
Yes, the reset value is indeed 0x1
>
> Do you see problems in your setup?
>
No problems, it works as expected, I was just confused to see the
mipi capture enable added with this rk3588 patch and not before.
I just find it a bit confusing but if a nicer solution is too much
hassle we can leave it like this.
--
Kind Regards
Mehdi Djait
Hi Mehdi,
On 3/17/26 14:28, Mehdi Djait wrote:
> Hi Michael,
>
> On Tue, Mar 17, 2026 at 02:21:20PM +0100, Michael Riesch wrote:
>> Hi Mehdi,
>>
>> On 3/17/26 14:08, Mehdi Djait wrote:
>>> Hi Michael,
>>>
>>> Thank you for this nice patch!
>>>
>>> On Tue, Mar 17, 2026 at 10:32:21AM +0100, Michael Riesch via B4 Relay wrote:
>>>> From: Michael Riesch <michael.riesch@collabora.com>
>>>>
>>>> The RK3588 Video Capture (VICAP) unit features a Digital Video Port
>>>> (DVP) and six MIPI CSI-2 capture interfaces. Add initial support
>>>> for this variant to the rkcif driver and enable the MIPI CSI-2
>>>> capture interfaces.
>>>>
>>>> Signed-off-by: Michael Riesch <michael.riesch@collabora.com>
>>>
>>> [...]
>>>
>>>> static inline unsigned int rkcif_mipi_get_reg(struct rkcif_interface *interface,
>>>> unsigned int index)
>>>> {
>>>> @@ -631,6 +765,8 @@ static int rkcif_mipi_start_streaming(struct rkcif_stream *stream)
>>>> rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL1, ctrl1);
>>>> rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, ctrl0);
>>>>
>>>> + rkcif_mipi_write(interface, RKCIF_MIPI_CTRL, RKCIF_MIPI_CTRL_CAP_EN);
>>>> +
>>>
>>> while this is the correct solution for rk3588, for the rk3568 vicap this
>>> will write 0x1 to the VICAP_MIPI_CTRL : 0x00A0 which will enable the water line.
>>
>> nice catch ;-) However, the TRM (at least my version) claims that this
>> bit has a reset value of 0x1, so the bit in question should be already
>> set in the first place. Thus I decided to *not* make variant specific
>> code paths.
>
> Yes, the reset value is indeed 0x1
>
>>
>> Do you see problems in your setup?
>>
>
> No problems, it works as expected, I was just confused to see the
> mipi capture enable added with this rk3588 patch and not before.
>
> I just find it a bit confusing but if a nicer solution is too much
> hassle we can leave it like this.
I agree that this is (while correct) not the nicest way. I am still
bringing up the remaining features of the RK3588 VICAP (MUX + TOISP +
SCALER) and it looks like I need to do some refactoring anyway to
support them. When I do that, I shall rewrite this part. For the time
being it would be great to have this merged in order to provide initial
mainline support for this unit.
Best regards,
Michael
Hi Michael,
On Wed, Mar 25, 2026 at 09:04:57AM +0100, Michael Riesch wrote:
> Hi Mehdi,
>
> On 3/17/26 14:28, Mehdi Djait wrote:
> > Hi Michael,
> >
> > On Tue, Mar 17, 2026 at 02:21:20PM +0100, Michael Riesch wrote:
> >> Hi Mehdi,
> >>
> >> On 3/17/26 14:08, Mehdi Djait wrote:
> >>> Hi Michael,
> >>>
> >>> Thank you for this nice patch!
> >>>
> >>> On Tue, Mar 17, 2026 at 10:32:21AM +0100, Michael Riesch via B4 Relay wrote:
> >>>> From: Michael Riesch <michael.riesch@collabora.com>
> >>>>
> >>>> The RK3588 Video Capture (VICAP) unit features a Digital Video Port
> >>>> (DVP) and six MIPI CSI-2 capture interfaces. Add initial support
> >>>> for this variant to the rkcif driver and enable the MIPI CSI-2
> >>>> capture interfaces.
> >>>>
> >>>> Signed-off-by: Michael Riesch <michael.riesch@collabora.com>
> >>>
> >>> [...]
> >>>
> >>>> static inline unsigned int rkcif_mipi_get_reg(struct rkcif_interface *interface,
> >>>> unsigned int index)
> >>>> {
> >>>> @@ -631,6 +765,8 @@ static int rkcif_mipi_start_streaming(struct rkcif_stream *stream)
> >>>> rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL1, ctrl1);
> >>>> rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, ctrl0);
> >>>>
> >>>> + rkcif_mipi_write(interface, RKCIF_MIPI_CTRL, RKCIF_MIPI_CTRL_CAP_EN);
> >>>> +
> >>>
> >>> while this is the correct solution for rk3588, for the rk3568 vicap this
> >>> will write 0x1 to the VICAP_MIPI_CTRL : 0x00A0 which will enable the water line.
> >>
> >> nice catch ;-) However, the TRM (at least my version) claims that this
> >> bit has a reset value of 0x1, so the bit in question should be already
> >> set in the first place. Thus I decided to *not* make variant specific
> >> code paths.
> >
> > Yes, the reset value is indeed 0x1
> >
> >>
> >> Do you see problems in your setup?
> >>
> >
> > No problems, it works as expected, I was just confused to see the
> > mipi capture enable added with this rk3588 patch and not before.
> >
> > I just find it a bit confusing but if a nicer solution is too much
> > hassle we can leave it like this.
>
> I agree that this is (while correct) not the nicest way. I am still
> bringing up the remaining features of the RK3588 VICAP (MUX + TOISP +
> SCALER) and it looks like I need to do some refactoring anyway to
> support them. When I do that, I shall rewrite this part. For the time
> being it would be great to have this merged in order to provide initial
> mainline support for this unit.
That sounds good.
How about adding a TODO comment ?
--
Kind Regards
Mehdi Djait
© 2016 - 2026 Red Hat, Inc.