From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: "Niklas Söderlund" <niklas.soderlund+renesas@ragnatech.se>
Cc: Hans Verkuil <hverkuil@xs4all.nl>,
linux-media@vger.kernel.org,
Sakari Ailus <sakari.ailus@linux.intel.com>,
linux-renesas-soc@vger.kernel.org,
tomoharu.fukawa.eb@renesas.com,
Kieran Bingham <kieran.bingham@ideasonboard.com>,
Geert Uytterhoeven <geert@linux-m68k.org>
Subject: Re: [PATCH v13 2/2] rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver
Date: Wed, 04 Apr 2018 18:15:16 +0300 [thread overview]
Message-ID: <5149348.Rp98f1K5qJ@avalon> (raw)
In-Reply-To: <20180212230132.5402-3-niklas.soderlund+renesas@ragnatech.se>
Hi Niklas,
Thank you for the patch.
On Tuesday, 13 February 2018 01:01:32 EEST Niklas Söderlund wrote:
> A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver
> supports the R-Car Gen3 SoCs where separate CSI-2 hardware blocks are
> connected between the video sources and the video grabbers (VIN).
>
> Driver is based on a prototype by Koji Matsuoka in the Renesas BSP.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> Reviewed-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
> drivers/media/platform/rcar-vin/Kconfig | 12 +
> drivers/media/platform/rcar-vin/Makefile | 1 +
> drivers/media/platform/rcar-vin/rcar-csi2.c | 884 +++++++++++++++++++++++++
> 3 files changed, 897 insertions(+)
> create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c
[snip]
> diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c
> b/drivers/media/platform/rcar-vin/rcar-csi2.c new file mode 100644
> index 0000000000000000..c0c2a763151bc928
> --- /dev/null
> +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
[snip]
> +static const struct phypll_hsfreqrange hsfreqrange_m3w_h3es1[] = {
> + { .mbps = 80, .reg = 0x00 },
> + { .mbps = 90, .reg = 0x10 },
> + { .mbps = 100, .reg = 0x20 },
> + { .mbps = 110, .reg = 0x30 },
> + { .mbps = 120, .reg = 0x01 },
> + { .mbps = 130, .reg = 0x11 },
> + { .mbps = 140, .reg = 0x21 },
> + { .mbps = 150, .reg = 0x31 },
> + { .mbps = 160, .reg = 0x02 },
> + { .mbps = 170, .reg = 0x12 },
> + { .mbps = 180, .reg = 0x22 },
> + { .mbps = 190, .reg = 0x32 },
> + { .mbps = 205, .reg = 0x03 },
> + { .mbps = 220, .reg = 0x13 },
> + { .mbps = 235, .reg = 0x23 },
> + { .mbps = 250, .reg = 0x33 },
> + { .mbps = 275, .reg = 0x04 },
> + { .mbps = 300, .reg = 0x14 },
> + { .mbps = 325, .reg = 0x05 },
> + { .mbps = 350, .reg = 0x15 },
> + { .mbps = 400, .reg = 0x25 },
> + { .mbps = 450, .reg = 0x06 },
> + { .mbps = 500, .reg = 0x16 },
> + { .mbps = 550, .reg = 0x07 },
> + { .mbps = 600, .reg = 0x17 },
> + { .mbps = 650, .reg = 0x08 },
> + { .mbps = 700, .reg = 0x18 },
> + { .mbps = 750, .reg = 0x09 },
> + { .mbps = 800, .reg = 0x19 },
> + { .mbps = 850, .reg = 0x29 },
> + { .mbps = 900, .reg = 0x39 },
> + { .mbps = 950, .reg = 0x0A },
> + { .mbps = 1000, .reg = 0x1A },
> + { .mbps = 1050, .reg = 0x2A },
> + { .mbps = 1100, .reg = 0x3A },
> + { .mbps = 1150, .reg = 0x0B },
> + { .mbps = 1200, .reg = 0x1B },
> + { .mbps = 1250, .reg = 0x2B },
> + { .mbps = 1300, .reg = 0x3B },
> + { .mbps = 1350, .reg = 0x0C },
> + { .mbps = 1400, .reg = 0x1C },
> + { .mbps = 1450, .reg = 0x2C },
> + { .mbps = 1500, .reg = 0x3C },
All the other hex values in the file are lowercase, I'd do the same here.
> + /* guard */
> + { .mbps = 0, .reg = 0x00 },
> +};
[snip]
> +static int rcar_csi2_start(struct rcar_csi2 *priv)
> +{
> + const struct rcar_csi2_format *format;
> + u32 phycnt, phypll, vcdt = 0, vcdt2 = 0;
> + unsigned int i;
> + int ret;
> +
> + dev_dbg(priv->dev, "Input size (%ux%u%c)\n",
> + priv->mf.width, priv->mf.height,
> + priv->mf.field == V4L2_FIELD_NONE ? 'p' : 'i');
> +
> + /* Code is validated in set_fmt */
> + format = rcar_csi2_code_to_fmt(priv->mf.code);
You could store the format pointer iin the rcar_csi2 structure to avoid
looking it up here.
> + /*
> + * Enable all Virtual Channels
> + *
> + * NOTE: It's not possible to get individual datatype for each
> + * source virtual channel. Once this is possible in V4L2
> + * it should be used here.
> + */
> + for (i = 0; i < 4; i++) {
> + u32 vcdt_part;
> +
> + vcdt_part = VCDT_SEL_VC(i) | VCDT_VCDTN_EN | VCDT_SEL_DTN_ON |
> + VCDT_SEL_DT(format->datatype);
> +
> + /* Store in correct reg and offset */
> + if (i < 2)
> + vcdt |= vcdt_part << ((i % 2) * 16);
> + else
> + vcdt2 |= vcdt_part << ((i % 2) * 16);
> + }
> +
> + switch (priv->lanes) {
> + case 1:
> + phycnt = PHYCNT_ENABLECLK | PHYCNT_ENABLE_0;
> + break;
> + case 2:
> + phycnt = PHYCNT_ENABLECLK | PHYCNT_ENABLE_1 | PHYCNT_ENABLE_0;
> + break;
> + case 4:
> + phycnt = PHYCNT_ENABLECLK | PHYCNT_ENABLE_3 | PHYCNT_ENABLE_2 |
> + PHYCNT_ENABLE_1 | PHYCNT_ENABLE_0;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + ret = rcar_csi2_calc_phypll(priv, format->bpp, &phypll);
> + if (ret)
> + return ret;
> +
> + /* Clear Ultra Low Power interrupt */
> + if (priv->info->clear_ulps)
> + rcar_csi2_write(priv, INTSTATE_REG,
> + INTSTATE_INT_ULPS_START |
> + INTSTATE_INT_ULPS_END);
> +
> + /* Init */
> + rcar_csi2_write(priv, TREF_REG, TREF_TREF);
> + rcar_csi2_reset(priv);
> + rcar_csi2_write(priv, PHTC_REG, 0);
> +
> + /* Configure */
> + rcar_csi2_write(priv, FLD_REG, FLD_FLD_NUM(2) | FLD_FLD_EN4 |
> + FLD_FLD_EN3 | FLD_FLD_EN2 | FLD_FLD_EN);
> + rcar_csi2_write(priv, VCDT_REG, vcdt);
> + rcar_csi2_write(priv, VCDT2_REG, vcdt2);
> + /* Lanes are zero indexed */
> + rcar_csi2_write(priv, LSWAP_REG,
> + LSWAP_L0SEL(priv->lane_swap[0] - 1) |
> + LSWAP_L1SEL(priv->lane_swap[1] - 1) |
> + LSWAP_L2SEL(priv->lane_swap[2] - 1) |
> + LSWAP_L3SEL(priv->lane_swap[3] - 1));
> +
> + if (priv->info->init_phtw) {
> + /*
> + * This is for H3 ES2.0
> + *
> + * NOTE: Additional logic is needed here when
> + * support for V3H and/or M3-N is added
> + */
> + rcar_csi2_write(priv, PHTW_REG, 0x01cc01e2);
> + rcar_csi2_write(priv, PHTW_REG, 0x010101e3);
> + rcar_csi2_write(priv, PHTW_REG, 0x010101e4);
> + rcar_csi2_write(priv, PHTW_REG, 0x01100104);
> + rcar_csi2_write(priv, PHTW_REG, 0x01030100);
> + rcar_csi2_write(priv, PHTW_REG, 0x01800100);
> + }
> +
> + /* Start */
> + rcar_csi2_write(priv, PHYPLL_REG, phypll);
> +
> + /* Set frequency range if we have it */
> + if (priv->info->csi0clkfreqrange)
> + rcar_csi2_write(priv, CSI0CLKFCPR_REG,
> + CSI0CLKFREQRANGE(priv->info->csi0clkfreqrange));
> +
> + rcar_csi2_write(priv, PHYCNT_REG, phycnt);
> + rcar_csi2_write(priv, LINKCNT_REG, LINKCNT_MONITOR_EN |
> + LINKCNT_REG_MONI_PACT_EN | LINKCNT_ICLK_NONSTOP);
> + rcar_csi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ);
> + rcar_csi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ |
> + PHYCNT_RSTZ);
> +
> + return rcar_csi2_wait_phy_start(priv);
> +}
[snip]
> +static int rcar_csi2_parse_v4l2(struct rcar_csi2 *priv,
> + struct v4l2_fwnode_endpoint *vep)
> +{
> + unsigned int i;
> +
> + /* Only port 0 endpoint 0 is valid */
> + if (vep->base.port || vep->base.id)
> + return -ENOTCONN;
> +
> + if (vep->bus_type != V4L2_MBUS_CSI2) {
> + dev_err(priv->dev, "Unsupported bus: 0x%x\n", vep->bus_type);
I think you can print this in decimal with %u.
> + 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);
> + return -EINVAL;
> + }
> +
> + for (i = 0; i < ARRAY_SIZE(priv->lane_swap); i++) {
> + priv->lane_swap[i] = i < priv->lanes ?
> + vep->bus.mipi_csi2.data_lanes[i] : i;
> +
> + /* Check for valid lane number */
> + if (priv->lane_swap[i] < 1 || priv->lane_swap[i] > 4) {
> + dev_err(priv->dev, "data-lanes must be in 1-4 range\n");
> + return -EINVAL;
> + }
> + }
> +
> + return 0;
> +}
[snip]
> +static int rcar_csi2_probe_resources(struct rcar_csi2 *priv,
> + struct platform_device *pdev)
> +{
> + struct resource *res;
> + int irq;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + priv->base = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(priv->base))
> + return PTR_ERR(priv->base);
> +
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0)
> + return irq;
You don't seem to use the IRQ. Is this meant to catch invalid DT that don't
specify an IRQ, to make sure we'll always have one available when we'll need
to later ?
> + return 0;
> +}
[snip]
> +static int rcar_csi2_probe(struct platform_device *pdev)
> +{
> + const struct soc_device_attribute *attr;
> + struct rcar_csi2 *priv;
> + unsigned int i;
> + int ret;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + priv->info = of_device_get_match_data(&pdev->dev);
> +
> + /* r8a7795 ES1.x behaves different then ES2.0+ but no own compat */
> + attr = soc_device_match(r8a7795es1);
> + if (attr)
> + priv->info = attr->data;
> +
> + priv->dev = &pdev->dev;
> +
> + mutex_init(&priv->lock);
> + priv->stream_count = 0;
> +
> + ret = rcar_csi2_probe_resources(priv, pdev);
> + if (ret) {
> + dev_err(priv->dev, "Failed to get resources\n");
> + return ret;
> + }
> +
> + platform_set_drvdata(pdev, priv);
> +
> + ret = rcar_csi2_parse_dt(priv);
> + if (ret)
> + return ret;
> +
> + priv->subdev.owner = THIS_MODULE;
> + priv->subdev.dev = &pdev->dev;
> + v4l2_subdev_init(&priv->subdev, &rcar_csi2_subdev_ops);
> + v4l2_set_subdevdata(&priv->subdev, &pdev->dev);
> + snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s %s",
> + KBUILD_MODNAME, dev_name(&pdev->dev));
> + priv->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
> +
> + priv->subdev.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
> + priv->subdev.entity.ops = &rcar_csi2_entity_ops;
> +
> + priv->pads[RCAR_CSI2_SINK].flags = MEDIA_PAD_FL_SINK;
> + for (i = RCAR_CSI2_SOURCE_VC0; i < NR_OF_RCAR_CSI2_PAD; i++)
> + priv->pads[i].flags = MEDIA_PAD_FL_SOURCE;
> +
> + ret = media_entity_pads_init(&priv->subdev.entity, NR_OF_RCAR_CSI2_PAD,
> + priv->pads);
> + if (ret)
> + goto error;
> +
> + pm_runtime_enable(&pdev->dev);
> +
> + ret = v4l2_async_register_subdev(&priv->subdev);
> + if (ret < 0)
> + goto error;
> +
> + dev_info(priv->dev, "%d lanes found\n", priv->lanes);
priv->lanes is unsigned you should use %u.
> +
> + return 0;
> +
> +error:
> + v4l2_async_notifier_unregister(&priv->notifier);
> + v4l2_async_notifier_cleanup(&priv->notifier);
> +
> + return ret;
> +}
[snip]
With these small issues fixed and Kieran's and Maxime's comments addressed as
you see fit,
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
--
Regards,
Laurent Pinchart
next prev parent reply other threads:[~2018-04-04 15:15 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-12 23:01 [PATCH v13 0/2] rcar-csi2: add Renesas R-Car MIPI CSI-2 Niklas Söderlund
2018-02-12 23:01 ` [PATCH v13 1/2] rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation Niklas Söderlund
2018-04-04 14:49 ` Laurent Pinchart
2018-02-12 23:01 ` [PATCH v13 2/2] rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver Niklas Söderlund
2018-03-13 22:23 ` Kieran Bingham
2018-04-04 15:25 ` Laurent Pinchart
2018-04-15 18:50 ` Niklas Söderlund
2018-04-15 18:48 ` Niklas Söderlund
2018-03-29 11:30 ` Maxime Ripard
2018-04-04 15:26 ` Laurent Pinchart
2018-04-05 7:33 ` Geert Uytterhoeven
2018-04-05 8:26 ` Laurent Pinchart
2018-04-15 20:35 ` Niklas Söderlund
2018-04-04 20:13 ` Sakari Ailus
2018-04-15 20:47 ` Niklas Söderlund
2018-04-16 9:30 ` Sakari Ailus
2018-04-15 20:33 ` Niklas Söderlund
2018-04-04 15:15 ` Laurent Pinchart [this message]
2018-04-15 21:26 ` Niklas Söderlund
2018-04-23 23:23 ` Laurent Pinchart
2018-04-05 9:10 ` jacopo mondi
2018-04-05 13:06 ` jacopo mondi
2018-04-15 23:16 ` Niklas Söderlund
2018-04-16 12:46 ` jacopo mondi
2018-04-17 0:05 ` Niklas Söderlund
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5149348.Rp98f1K5qJ@avalon \
--to=laurent.pinchart@ideasonboard.com \
--cc=geert@linux-m68k.org \
--cc=hverkuil@xs4all.nl \
--cc=kieran.bingham@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=niklas.soderlund+renesas@ragnatech.se \
--cc=sakari.ailus@linux.intel.com \
--cc=tomoharu.fukawa.eb@renesas.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox