Gen4 will support both D-PHY and C-PHY, while Gen3 only supports D-PHY. Add two flags to the device information structure to be able to record what each SoC supports. Extend the device node parsing to accept both CSI_2 D-PHY and C-PHY buses, while at the same time taking the SoC support into account. Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@xxxxxxxxxxxx> --- .../platform/renesas/rcar-vin/rcar-csi2.c | 71 +++++++++++++++---- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c index 180926a2722d..5fa4a29064fd 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c @@ -490,6 +490,8 @@ struct rcar_csi2_info { unsigned int num_channels; bool clear_ulps; bool use_isp; + bool support_dphy; + bool support_cphy; }; struct rcar_csi2 { @@ -511,6 +513,7 @@ struct rcar_csi2 { struct v4l2_mbus_framefmt mf; int stream_count; + bool cphy; unsigned short lanes; unsigned char lane_swap[4]; }; @@ -665,9 +668,17 @@ static int rcsi2_get_active_lanes(struct rcar_csi2 *priv, return ret; } - if (mbus_config.type != V4L2_MBUS_CSI2_DPHY) { - dev_err(priv->dev, "Unsupported media bus type %u\n", - mbus_config.type); + switch (mbus_config.type) { + case V4L2_MBUS_CSI2_CPHY: + if (!priv->cphy) + return -EINVAL; + break; + case V4L2_MBUS_CSI2_DPHY: + if (priv->cphy) + return -EINVAL; + break; + default: + dev_err(priv->dev, "Unsupported media bus type %u\n", mbus_config.type); return -EINVAL; } @@ -1025,15 +1036,41 @@ static int rcsi2_parse_v4l2(struct rcar_csi2 *priv, if (vep->base.port || vep->base.id) return -ENOTCONN; - if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) { - dev_err(priv->dev, "Unsupported bus: %u\n", vep->bus_type); - return -EINVAL; - } - priv->lanes = vep->bus.mipi_csi2.num_data_lanes; - if (priv->lanes != 1 && priv->lanes != 2 && priv->lanes != 4) { - dev_err(priv->dev, "Unsupported number of data-lanes: %u\n", - priv->lanes); + + switch (vep->bus_type) { + case V4L2_MBUS_CSI2_DPHY: + if (!priv->info->support_dphy) { + dev_err(priv->dev, "D-PHY not supported\n"); + return -EINVAL; + } + + if (priv->lanes != 1 && priv->lanes != 2 && priv->lanes != 4) { + dev_err(priv->dev, + "Unsupported number of data-lanes for D-PHY: %u\n", + priv->lanes); + return -EINVAL; + } + + priv->cphy = false; + break; + case V4L2_MBUS_CSI2_CPHY: + if (!priv->info->support_cphy) { + dev_err(priv->dev, "C-PHY not supported\n"); + return -EINVAL; + } + + if (priv->lanes != 3) { + dev_err(priv->dev, + "Unsupported number of data-lanes for C-PHY: %u\n", + priv->lanes); + return -EINVAL; + } + + priv->cphy = true; + break; + default: + dev_err(priv->dev, "Unsupported bus: %u\n", vep->bus_type); return -EINVAL; } @@ -1057,7 +1094,7 @@ static int rcsi2_parse_dt(struct rcar_csi2 *priv) struct fwnode_handle *fwnode; struct fwnode_handle *ep; struct v4l2_fwnode_endpoint v4l2_ep = { - .bus_type = V4L2_MBUS_CSI2_DPHY + .bus_type = V4L2_MBUS_UNKNOWN, }; int ret; @@ -1378,6 +1415,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7795 = { .csi0clkfreqrange = 0x20, .num_channels = 4, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a7795es1 = { @@ -1385,6 +1423,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7795es1 = { .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_m3w_h3es1, .num_channels = 4, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a7795es2 = { @@ -1395,6 +1434,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7795es2 = { .csi0clkfreqrange = 0x20, .num_channels = 4, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = { @@ -1402,6 +1442,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = { .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_m3w_h3es1, .num_channels = 4, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77961 = { @@ -1409,6 +1450,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77961 = { .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_m3w_h3es1, .num_channels = 4, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = { @@ -1419,6 +1461,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = { .csi0clkfreqrange = 0x20, .num_channels = 4, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = { @@ -1427,6 +1470,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = { .start_receiver = rcsi2_start_receiver_gen3, .enter_standby = rcsi2_enter_standby_gen3, .num_channels = 4, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = { @@ -1436,6 +1480,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = { .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = { @@ -1444,6 +1489,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = { .start_receiver = rcsi2_start_receiver_gen3, .enter_standby = rcsi2_enter_standby_gen3, .num_channels = 2, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = { @@ -1454,6 +1500,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = { .csi0clkfreqrange = 0x20, .clear_ulps = true, .use_isp = true, + .support_dphy = true, }; static const struct of_device_id rcar_csi2_of_table[] = { -- 2.39.1