[1/3] media: rcar-csi2: Prepare for Gen4 support

Message ID 20230211145310.3819989-2-niklas.soderlund+renesas@ragnatech.se (mailing list archive)
State Changes Requested
Delegated to: Hans Verkuil
Headers
Series media: rcar-csi2: Add support for V4H |

Commit Message

Niklas Söderlund Feb. 11, 2023, 2:53 p.m. UTC
  Prepare the driver for supporting R-Car Gen4. The starting of the
receiver and how to enter standby differs between Gen3 and Gen4,
create function pointers in the device info structure to control the
different behavior.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 .../platform/renesas/rcar-vin/rcar-csi2.c     | 35 +++++++++++++++++--
 1 file changed, 32 insertions(+), 3 deletions(-)
  

Comments

Geert Uytterhoeven Feb. 13, 2023, 3:41 p.m. UTC | #1
Hi Niklas,

On Sat, Feb 11, 2023 at 4:05 PM Niklas Söderlund
<niklas.soderlund+renesas@ragnatech.se> wrote:
> Prepare the driver for supporting R-Car Gen4. The starting of the
> receiver and how to enter standby differs between Gen3 and Gen4,
> create function pointers in the device info structure to control the
> different behavior.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>

Thanks for your patch!

> --- a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c
> +++ b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c

> @@ -1416,11 +1441,15 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = {
>  static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = {
>         .init_phtw = rcsi2_init_phtw_v3m_e3,
>         .phy_post_init = rcsi2_phy_post_init_v3m_e3,
> +       .start_receiver = rcsi2_start_receiver_gen3,
> +       .enter_standby = rcsi2_enter_standby_gen3,
>         .num_channels = 2,
>  };
>
>  static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = {
>         .init_phtw = rcsi2_init_phtw_v3u,
> +       .start_receiver = rcsi2_start_receiver_gen3,
> +       .enter_standby = rcsi2_enter_standby_gen3,

This part means R-Car V3U is still treated like other R-Car Gen3 SoCs,
not like R-Car Gen4.  Just double-checking if that is intentional?

>         .hsfreqrange = hsfreqrange_v3u,
>         .csi0clkfreqrange = 0x20,
>         .clear_ulps = true,

Gr{oetje,eeting}s,

                        Geert
  
Niklas Söderlund Feb. 13, 2023, 4:04 p.m. UTC | #2
Hi Geert,

Thanks for your feedback.

On 2023-02-13 16:41:22 +0100, Geert Uytterhoeven wrote:
> Hi Niklas,
> 
> On Sat, Feb 11, 2023 at 4:05 PM Niklas Söderlund
> <niklas.soderlund+renesas@ragnatech.se> wrote:
> > Prepare the driver for supporting R-Car Gen4. The starting of the
> > receiver and how to enter standby differs between Gen3 and Gen4,
> > create function pointers in the device info structure to control the
> > different behavior.
> >
> > Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> 
> Thanks for your patch!
> 
> > --- a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c
> > +++ b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c
> 
> > @@ -1416,11 +1441,15 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = {
> >  static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = {
> >         .init_phtw = rcsi2_init_phtw_v3m_e3,
> >         .phy_post_init = rcsi2_phy_post_init_v3m_e3,
> > +       .start_receiver = rcsi2_start_receiver_gen3,
> > +       .enter_standby = rcsi2_enter_standby_gen3,
> >         .num_channels = 2,
> >  };
> >
> >  static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = {
> >         .init_phtw = rcsi2_init_phtw_v3u,
> > +       .start_receiver = rcsi2_start_receiver_gen3,
> > +       .enter_standby = rcsi2_enter_standby_gen3,
> 
> This part means R-Car V3U is still treated like other R-Car Gen3 SoCs,
> not like R-Car Gen4.  Just double-checking if that is intentional?

That is intentional.

The big difference between most Gen3 SoC and V3U is that it adds the 
ISPCS (Channel Selector) between the CSI-2 IP downstream (not on the 
CSI-2 side) and the VIN IP. In short this moves some logic for routing 
which video stream is routed to which dma-engine from the VIN register 
space to the new ISPCS register space.

On the V3U the CSI-2 module is the same as on the other Gen3 SoC and it 
only supports CSI-2 D-PHY. No major new CSI-2 related change was added 
for V3U.

On the V4H the ISPCS is kept and all changes to the VIN module are the 
same as for the V3U. The new thing is more or less a new CSI-2 module, 
the register space is completely different from Gen3. It ties in to the 
same place in the video pipeline so most of the DT and V4L plumbing can 
be shared between Gen3 and Gen4. But how to start it and how to enter 
standby differs, more on standby in the reply to patch 3/3.

> 
> >         .hsfreqrange = hsfreqrange_v3u,
> >         .csi0clkfreqrange = 0x20,
> >         .clear_ulps = true,
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> -- 
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds
  

Patch

diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c
index 174aa6176f54..180926a2722d 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c
@@ -483,6 +483,8 @@  enum rcar_csi2_pads {
 struct rcar_csi2_info {
 	int (*init_phtw)(struct rcar_csi2 *priv, unsigned int mbps);
 	int (*phy_post_init)(struct rcar_csi2 *priv);
+	int (*start_receiver)(struct rcar_csi2 *priv);
+	void (*enter_standby)(struct rcar_csi2 *priv);
 	const struct rcsi2_mbps_reg *hsfreqrange;
 	unsigned int csi0clkfreqrange;
 	unsigned int num_channels;
@@ -533,10 +535,17 @@  static void rcsi2_write(struct rcar_csi2 *priv, unsigned int reg, u32 data)
 	iowrite32(data, priv->base + reg);
 }
 
-static void rcsi2_enter_standby(struct rcar_csi2 *priv)
+static void rcsi2_enter_standby_gen3(struct rcar_csi2 *priv)
 {
 	rcsi2_write(priv, PHYCNT_REG, 0);
 	rcsi2_write(priv, PHTC_REG, PHTC_TESTCLR);
+}
+
+static void rcsi2_enter_standby(struct rcar_csi2 *priv)
+{
+	if (priv->info->enter_standby)
+		priv->info->enter_standby(priv);
+
 	reset_control_assert(priv->rstc);
 	usleep_range(100, 150);
 	pm_runtime_put(priv->dev);
@@ -674,7 +683,7 @@  static int rcsi2_get_active_lanes(struct rcar_csi2 *priv,
 	return 0;
 }
 
-static int rcsi2_start_receiver(struct rcar_csi2 *priv)
+static int rcsi2_start_receiver_gen3(struct rcar_csi2 *priv)
 {
 	const struct rcar_csi2_format *format;
 	u32 phycnt, vcdt = 0, vcdt2 = 0, fld = 0;
@@ -821,7 +830,7 @@  static int rcsi2_start(struct rcar_csi2 *priv)
 	if (ret < 0)
 		return ret;
 
-	ret = rcsi2_start_receiver(priv);
+	ret = priv->info->start_receiver(priv);
 	if (ret) {
 		rcsi2_enter_standby(priv);
 		return ret;
@@ -1363,6 +1372,8 @@  static int rcsi2_probe_resources(struct rcar_csi2 *priv,
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a7795 = {
 	.init_phtw = rcsi2_init_phtw_h3_v3h_m3n,
+	.start_receiver = rcsi2_start_receiver_gen3,
+	.enter_standby = rcsi2_enter_standby_gen3,
 	.hsfreqrange = hsfreqrange_h3_v3h_m3n,
 	.csi0clkfreqrange = 0x20,
 	.num_channels = 4,
@@ -1370,12 +1381,16 @@  static const struct rcar_csi2_info rcar_csi2_info_r8a7795 = {
 };
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a7795es1 = {
+	.start_receiver = rcsi2_start_receiver_gen3,
+	.enter_standby = rcsi2_enter_standby_gen3,
 	.hsfreqrange = hsfreqrange_m3w_h3es1,
 	.num_channels = 4,
 };
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a7795es2 = {
 	.init_phtw = rcsi2_init_phtw_h3es2,
+	.start_receiver = rcsi2_start_receiver_gen3,
+	.enter_standby = rcsi2_enter_standby_gen3,
 	.hsfreqrange = hsfreqrange_h3_v3h_m3n,
 	.csi0clkfreqrange = 0x20,
 	.num_channels = 4,
@@ -1383,17 +1398,23 @@  static const struct rcar_csi2_info rcar_csi2_info_r8a7795es2 = {
 };
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = {
+	.start_receiver = rcsi2_start_receiver_gen3,
+	.enter_standby = rcsi2_enter_standby_gen3,
 	.hsfreqrange = hsfreqrange_m3w_h3es1,
 	.num_channels = 4,
 };
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a77961 = {
+	.start_receiver = rcsi2_start_receiver_gen3,
+	.enter_standby = rcsi2_enter_standby_gen3,
 	.hsfreqrange = hsfreqrange_m3w_h3es1,
 	.num_channels = 4,
 };
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = {
 	.init_phtw = rcsi2_init_phtw_h3_v3h_m3n,
+	.start_receiver = rcsi2_start_receiver_gen3,
+	.enter_standby = rcsi2_enter_standby_gen3,
 	.hsfreqrange = hsfreqrange_h3_v3h_m3n,
 	.csi0clkfreqrange = 0x20,
 	.num_channels = 4,
@@ -1403,11 +1424,15 @@  static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = {
 static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = {
 	.init_phtw = rcsi2_init_phtw_v3m_e3,
 	.phy_post_init = rcsi2_phy_post_init_v3m_e3,
+	.start_receiver = rcsi2_start_receiver_gen3,
+	.enter_standby = rcsi2_enter_standby_gen3,
 	.num_channels = 4,
 };
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = {
 	.init_phtw = rcsi2_init_phtw_h3_v3h_m3n,
+	.start_receiver = rcsi2_start_receiver_gen3,
+	.enter_standby = rcsi2_enter_standby_gen3,
 	.hsfreqrange = hsfreqrange_h3_v3h_m3n,
 	.csi0clkfreqrange = 0x20,
 	.clear_ulps = true,
@@ -1416,11 +1441,15 @@  static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = {
 static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = {
 	.init_phtw = rcsi2_init_phtw_v3m_e3,
 	.phy_post_init = rcsi2_phy_post_init_v3m_e3,
+	.start_receiver = rcsi2_start_receiver_gen3,
+	.enter_standby = rcsi2_enter_standby_gen3,
 	.num_channels = 2,
 };
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = {
 	.init_phtw = rcsi2_init_phtw_v3u,
+	.start_receiver = rcsi2_start_receiver_gen3,
+	.enter_standby = rcsi2_enter_standby_gen3,
 	.hsfreqrange = hsfreqrange_v3u,
 	.csi0clkfreqrange = 0x20,
 	.clear_ulps = true,