Re: [PATCH v10 2/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver
Hi Niklas, On Saturday, 11 November 2017 02:11:13 EET Niklas Söderlund wrote: > On 2017-11-11 00:32:27 +0200, Sakari Ailus wrote: > > On Fri, Nov 10, 2017 at 02:31:37PM +0100, Niklas Söderlund wrote: > >> A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver > >> supports the rcar-vin driver on 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> >> --- > >> > >> drivers/media/platform/rcar-vin/Kconfig | 12 + > >> drivers/media/platform/rcar-vin/Makefile| 1 + > >> drivers/media/platform/rcar-vin/rcar-csi2.c | 934 ++ > >> 3 files changed, 947 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 ..27d09da191a09b39 > >> --- /dev/null > >> +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c [snip] > >> +static int rcar_csi2_calc_phypll(struct rcar_csi2 *priv, > >> + struct v4l2_subdev *source, > >> + struct v4l2_mbus_framefmt *mf, > >> + u32 *phypll) > >> +{ > >> + const struct phypll_hsfreqrange *hsfreq; > >> + const struct rcar_csi2_format *format; > >> + struct v4l2_ctrl *ctrl; > >> + u64 mbps; > >> + > >> + ctrl = v4l2_ctrl_find(source->ctrl_handler, V4L2_CID_PIXEL_RATE); > > > > How about LINK_FREQ instead? It'd be more straightforward to calculate > > this. Up to you. > > I need to use PIXEL_RATE as my test setup uses the adv748x driver which > only implement that control. In the short term I would like to support > both, but I need a setup to test that before I can add support for it. > In the long term, maybe we should deprecate one of the controls? The LINK_FREQ control is meant for the user to select one of the available link frequencies (when multiple values are possible), while the PIXEL_RATE control is a read-only control meant for the connected subdev to query the resulting pixel rate. I think both controls should be kept, and PIXEL_RATE should be used here. > >> + if (!ctrl) { > >> + dev_err(priv->dev, "no link freq control in subdev %s\n", > >> + source->name); > >> + return -EINVAL; > >> + } > >> + > >> + format = rcar_csi2_code_to_fmt(mf->code); > >> + if (!format) { > >> + dev_err(priv->dev, "Unknown format: %d\n", mf->code); > >> + return -EINVAL; > >> + } > >> + > >> + mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * format->bpp; > >> + do_div(mbps, priv->lanes * 100); > >> + > >> + for (hsfreq = priv->info->hsfreqrange; hsfreq->mbps != 0; hsfreq++) > >> + if (hsfreq->mbps >= mbps) > >> + break; > >> + > >> + if (!hsfreq->mbps) { > >> + dev_err(priv->dev, "Unsupported PHY speed (%llu Mbps)", mbps); > >> + return -ERANGE; > >> + } > >> + > >> + dev_dbg(priv->dev, "PHY HSFREQRANGE requested %llu got %u Mbps\n", > >> mbps, > >> + hsfreq->mbps); > >> + > >> + *phypll = PHYPLL_HSFREQRANGE(hsfreq->reg); > >> + > >> + return 0; > >> +} [snip] -- Regards, Laurent Pinchart
[PATCH v7 05/25] rcar-vin: change name of video device
The rcar-vin driver needs to be part of a media controller to support Gen3. Give each VIN instance a unique name so it can be referenced from userspace. Signed-off-by: Niklas SöderlundReviewed-by: Kieran Bingham Reviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 76c0b8fa8602d08d..f501da9df48c288b 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -878,7 +878,8 @@ int rvin_v4l2_register(struct rvin_dev *vin) vdev->fops = _fops; vdev->v4l2_dev = >v4l2_dev; vdev->queue = >queue; - strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name)); + snprintf(vdev->name, sizeof(vdev->name), "%s %s", KBUILD_MODNAME, +dev_name(vin->dev)); vdev->release = video_device_release_empty; vdev->ioctl_ops = _ioctl_ops; vdev->lock = >lock; -- 2.15.0
[PATCH v7 17/25] rcar-vin: use different v4l2 operations in media controller mode
When the driver runs in media controller mode it should not directly control the subdevice instead userspace will be responsible for configuring the pipeline. To be able to run in this mode a different set of v4l2 operations needs to be used. Add a new set of v4l2 operations to support the running without directly interacting with the source subdevice. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-dma.c | 3 +- drivers/media/platform/rcar-vin/rcar-v4l2.c | 153 +++- drivers/media/platform/rcar-vin/rcar-vin.h | 1 + 3 files changed, 154 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 463c656b9878be52..fe1319eb4c5df02d 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -628,7 +628,8 @@ static int rvin_setup(struct rvin_dev *vin) /* Default to TB */ vnmc = VNMC_IM_FULL; /* Use BT if video standard can be read and is 60 Hz format */ - if (!v4l2_subdev_call(vin_to_source(vin), video, g_std, )) { + if (!vin->info->use_mc && + !v4l2_subdev_call(vin_to_source(vin), video, g_std, )) { if (std & V4L2_STD_525_60) vnmc = VNMC_IM_FULL | VNMC_FOC; } diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index c9a3fe21dea4ce5d..11064dd7dcbb53c7 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -23,6 +23,9 @@ #include "rcar-vin.h" #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV +#define RVIN_DEFAULT_WIDTH 800 +#define RVIN_DEFAULT_HEIGHT600 +#define RVIN_DEFAULT_COLORSPACEV4L2_COLORSPACE_SRGB /* - * Format Conversions @@ -671,6 +674,84 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; +/* - + * V4L2 Media Controller + */ + +static int __rvin_mc_try_format(struct rvin_dev *vin, + struct v4l2_pix_format *pix) +{ + /* Keep current field if no specific one is asked for */ + if (pix->field == V4L2_FIELD_ANY) + pix->field = vin->format.field; + + return rvin_format_align(vin, pix); +} + +static int rvin_mc_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct rvin_dev *vin = video_drvdata(file); + + return __rvin_mc_try_format(vin, >fmt.pix); +} + +static int rvin_mc_s_fmt_vid_cap(struct file *file, void *priv, +struct v4l2_format *f) +{ + struct rvin_dev *vin = video_drvdata(file); + int ret; + + if (vb2_is_busy(>queue)) + return -EBUSY; + + ret = __rvin_mc_try_format(vin, >fmt.pix); + if (ret) + return ret; + + vin->format = f->fmt.pix; + + return 0; +} + +static int rvin_mc_enum_input(struct file *file, void *priv, + struct v4l2_input *i) +{ + if (i->index != 0) + return -EINVAL; + + i->type = V4L2_INPUT_TYPE_CAMERA; + strlcpy(i->name, "Camera", sizeof(i->name)); + + return 0; +} + +static const struct v4l2_ioctl_ops rvin_mc_ioctl_ops = { + .vidioc_querycap= rvin_querycap, + .vidioc_try_fmt_vid_cap = rvin_mc_try_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = rvin_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = rvin_mc_s_fmt_vid_cap, + .vidioc_enum_fmt_vid_cap= rvin_enum_fmt_vid_cap, + + .vidioc_enum_input = rvin_mc_enum_input, + .vidioc_g_input = rvin_g_input, + .vidioc_s_input = rvin_s_input, + + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_querybuf= vb2_ioctl_querybuf, + .vidioc_qbuf= vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_streamon= vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = rvin_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + /*
[PATCH v7 01/25] rcar-vin: add Gen3 devicetree bindings documentation
Document the devicetree bindings for the CSI-2 inputs available on Gen3. There is a need to add a custom property 'renesas,id' and to define which CSI-2 input is described in which endpoint under the port@1 node. This information is needed since there are a set of predefined routes between each VIN and CSI-2 block. This routing table will be kept inside the driver but in order for it to act on it it must know which VIN and CSI-2 is which. Signed-off-by: Niklas Söderlund--- .../devicetree/bindings/media/rcar_vin.txt | 116 ++--- 1 file changed, 104 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt index 6e4ef8caf759e5d3..df1abd0fb20386f8 100644 --- a/Documentation/devicetree/bindings/media/rcar_vin.txt +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt @@ -2,8 +2,12 @@ Renesas R-Car Video Input driver (rcar_vin) --- The rcar_vin device provides video input capabilities for the Renesas R-Car -family of devices. The current blocks are always slaves and suppot one input -channel which can be either RGB, YUYV or BT656. +family of devices. + +Each VIN instance has a single parallel input that supports RGB and YUV video, +with both external synchronization and BT.656 synchronization for the latter. +Depending on the instance the VIN input is connected to external SoC pins, or +on Gen3 to a CSI-2 receiver. - compatible: Must be one or more of the following - "renesas,vin-r8a7795" for the R8A7795 device @@ -28,21 +32,38 @@ channel which can be either RGB, YUYV or BT656. Additionally, an alias named vinX will need to be created to specify which video input device this is. -The per-board settings: +The per-board settings Gen2: - port sub-node describing a single endpoint connected to the vin as described in video-interfaces.txt[1]. Only the first one will be considered as each vin interface has one input port. - These settings are used to work out video input format and widths - into the system. +The per-board settings Gen3: + +Gen3 can support both a single connected parallel input source from +external SoC pins (port0) and/or multiple parallel input sources from +local SoC CSI-2 receivers (port1) depending on SoC. +- renesas,id - ID number of the VIN, VINx in the documentation. +- ports +- port0 - sub-node describing a single endpoint connected to the VIN + from external SoC pins described in video-interfaces.txt[1]. Only + the first one will be considered as each VIN interface has at most + one set of SoC external input pins. +- port1 - sub-nodes describing one or more endpoints connected to + the VIN from local SoC CSI-2 receivers. The endpoint numbers must + use the following schema. -Device node example +- Endpoint 0 - sub-node describing the endpoint which is CSI20 +- Endpoint 1 - sub-node describing the endpoint which is CSI21 +- Endpoint 2 - sub-node describing the endpoint which is CSI40 +- Endpoint 3 - sub-node describing the endpoint which is CSI41 - aliases { - vin0 = - }; +Device node example Gen2 + + +aliases { +vin0 = +}; vin0: vin@0xe6ef { compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin"; @@ -52,8 +73,8 @@ Device node example status = "disabled"; }; -Board setup example (vin1 composite video input) - +Board setup example Gen2 (vin1 composite video input) +- { status = "ok"; @@ -92,6 +113,77 @@ Board setup example (vin1 composite video input) }; }; +Device node example Gen3 + + +vin0: video@e6ef { +compatible = "renesas,vin-r8a7795"; +reg = <0 0xe6ef 0 0x1000>; +interrupts = ; +clocks = < CPG_MOD 811>; +power-domains = < R8A7795_PD_ALWAYS_ON>; +resets = < 811>; +renesas,id = <0>; + +ports { +#address-cells = <1>; +#size-cells = <0>; + +port@1 { +#address-cells = <1>; +#size-cells = <0>; + +reg = <1>; + +vin0csi20: endpoint@0 { +reg = <0>; +remote-endpoint= <>; +}; +vin0csi21: endpoint@1 { +reg = <1>; +
[PATCH v7 04/25] rcar-vin: move max width and height information to chip information
On Gen3 the max supported width and height will be different from Gen2. Move the limits to the struct rvin_info to prepare for Gen3 support. Signed-off-by: Niklas SöderlundReviewed-by: Kieran Bingham Reviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-core.c | 6 ++ drivers/media/platform/rcar-vin/rcar-v4l2.c | 6 ++ drivers/media/platform/rcar-vin/rcar-vin.h | 6 ++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index e90e5d014e074d64..cb761057459caa3f 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -244,14 +244,20 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) static const struct rvin_info rcar_info_h1 = { .chip = RCAR_H1, + .max_width = 2048, + .max_height = 2048, }; static const struct rvin_info rcar_info_m1 = { .chip = RCAR_M1, + .max_width = 2048, + .max_height = 2048, }; static const struct rvin_info rcar_info_gen2 = { .chip = RCAR_GEN2, + .max_width = 2048, + .max_height = 2048, }; static const struct of_device_id rvin_of_id_table[] = { diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index be00f4431493eb0a..76c0b8fa8602d08d 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -23,8 +23,6 @@ #include "rcar-vin.h" #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV -#define RVIN_MAX_WIDTH 2048 -#define RVIN_MAX_HEIGHT2048 /* - * Format Conversions @@ -258,8 +256,8 @@ static int __rvin_try_format(struct rvin_dev *vin, walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; /* Limit to VIN capabilities */ - v4l_bound_align_image(>width, 2, RVIN_MAX_WIDTH, walign, - >height, 4, RVIN_MAX_HEIGHT, 2, 0); + v4l_bound_align_image(>width, 2, vin->info->max_width, walign, + >height, 4, vin->info->max_height, 2, 0); pix->bytesperline = max_t(u32, pix->bytesperline, rvin_format_bytesperline(pix)); diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index ab240eb4aad9176c..e41dc3bff7fdc649 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -91,9 +91,15 @@ struct rvin_graph_entity { /** * struct rvin_info - Information about the particular VIN implementation * @chip: type of VIN chip + * + * max_width: max input width the VIN supports + * max_height: max input height the VIN supports */ struct rvin_info { enum chip_id chip; + + unsigned int max_width; + unsigned int max_height; }; /** -- 2.15.0
[PATCH v7 08/25] rcar-vin: do not reset crop and compose when setting format
It was a bad idea to reset the crop and compose settings when a new format is set. This would overwrite any crop/compose set by s_select and cause unexpected behaviors, remove it. Also fold the reset helper in to the only remaining caller. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 21 +++-- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 02b081d2d8826e90..25f2386cb67447f2 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -90,17 +90,6 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix) * V4L2 */ -static void rvin_reset_crop_compose(struct rvin_dev *vin) -{ - vin->crop.top = vin->crop.left = 0; - vin->crop.width = vin->source.width; - vin->crop.height = vin->source.height; - - vin->compose.top = vin->compose.left = 0; - vin->compose.width = vin->format.width; - vin->compose.height = vin->format.height; -} - int rvin_reset_format(struct rvin_dev *vin) { struct v4l2_subdev_format fmt = { @@ -147,7 +136,13 @@ int rvin_reset_format(struct rvin_dev *vin) break; } - rvin_reset_crop_compose(vin); + vin->crop.top = vin->crop.left = 0; + vin->crop.width = mf->width; + vin->crop.height = mf->height; + + vin->compose.top = vin->compose.left = 0; + vin->compose.width = mf->width; + vin->compose.height = mf->height; vin->format.bytesperline = rvin_format_bytesperline(>format); vin->format.sizeimage = rvin_format_sizeimage(>format); @@ -317,8 +312,6 @@ static int rvin_s_fmt_vid_cap(struct file *file, void *priv, vin->format = f->fmt.pix; - rvin_reset_crop_compose(vin); - return 0; } -- 2.15.0
[PATCH v7 06/25] rcar-vin: move functions regarding scaling
In preparation of refactoring the scaling code move the code regarding scaling to to the top of the file to avoid the need to add forward declarations. No code is changed in this commit only whole functions moved inside the same file. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-dma.c | 806 +++-- 1 file changed, 405 insertions(+), 401 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 23fdff7a7370842e..b71259701d2da20f 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -138,305 +138,6 @@ static u32 rvin_read(struct rvin_dev *vin, u32 offset) return ioread32(vin->base + offset); } -static int rvin_setup(struct rvin_dev *vin) -{ - u32 vnmc, dmr, dmr2, interrupts; - v4l2_std_id std; - bool progressive = false, output_is_yuv = false, input_is_yuv = false; - - switch (vin->format.field) { - case V4L2_FIELD_TOP: - vnmc = VNMC_IM_ODD; - break; - case V4L2_FIELD_BOTTOM: - vnmc = VNMC_IM_EVEN; - break; - case V4L2_FIELD_INTERLACED: - /* Default to TB */ - vnmc = VNMC_IM_FULL; - /* Use BT if video standard can be read and is 60 Hz format */ - if (!v4l2_subdev_call(vin_to_source(vin), video, g_std, )) { - if (std & V4L2_STD_525_60) - vnmc = VNMC_IM_FULL | VNMC_FOC; - } - break; - case V4L2_FIELD_INTERLACED_TB: - vnmc = VNMC_IM_FULL; - break; - case V4L2_FIELD_INTERLACED_BT: - vnmc = VNMC_IM_FULL | VNMC_FOC; - break; - case V4L2_FIELD_ALTERNATE: - case V4L2_FIELD_NONE: - if (vin->continuous) { - vnmc = VNMC_IM_ODD_EVEN; - progressive = true; - } else { - vnmc = VNMC_IM_ODD; - } - break; - default: - vnmc = VNMC_IM_ODD; - break; - } - - /* -* Input interface -*/ - switch (vin->digital->code) { - case MEDIA_BUS_FMT_YUYV8_1X16: - /* BT.601/BT.1358 16bit YCbCr422 */ - vnmc |= VNMC_INF_YUV16; - input_is_yuv = true; - break; - case MEDIA_BUS_FMT_UYVY8_2X8: - /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? - VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601; - input_is_yuv = true; - break; - case MEDIA_BUS_FMT_RGB888_1X24: - vnmc |= VNMC_INF_RGB888; - break; - case MEDIA_BUS_FMT_UYVY10_2X10: - /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? - VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601; - input_is_yuv = true; - break; - default: - break; - } - - /* Enable VSYNC Field Toogle mode after one VSYNC input */ - dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1); - - /* Hsync Signal Polarity Select */ - if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) - dmr2 |= VNDMR2_HPS; - - /* Vsync Signal Polarity Select */ - if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) - dmr2 |= VNDMR2_VPS; - - /* -* Output format -*/ - switch (vin->format.pixelformat) { - case V4L2_PIX_FMT_NV16: - rvin_write(vin, - ALIGN(vin->format.width * vin->format.height, 0x80), - VNUVAOF_REG); - dmr = VNDMR_DTMD_YCSEP; - output_is_yuv = true; - break; - case V4L2_PIX_FMT_YUYV: - dmr = VNDMR_BPSM; - output_is_yuv = true; - break; - case V4L2_PIX_FMT_UYVY: - dmr = 0; - output_is_yuv = true; - break; - case V4L2_PIX_FMT_XRGB555: - dmr = VNDMR_DTMD_ARGB1555; - break; - case V4L2_PIX_FMT_RGB565: - dmr = 0; - break; - case V4L2_PIX_FMT_XBGR32: - /* Note: not supported on M1 */ - dmr = VNDMR_EXRGB; - break; - default: - vin_err(vin, "Invalid pixelformat (0x%x)\n", - vin->format.pixelformat); - return -EINVAL; - } - - /* Always update on field change */ - vnmc |= VNMC_VUP; - - /* If input and
[PATCH v7 14/25] rcar-vin: add function to manipulate Gen3 CHSEL value
On Gen3 the CSI-2 routing is controlled by the VnCSI_IFMD register. One feature of this register is that it's only present in the VIN0 and VIN4 instances. The register in VIN0 controls the routing for VIN0-3 and the register in VIN4 controls routing for VIN4-7. To be able to control routing from a media device this function is need to control runtime PM for the subgroup master (VIN0 and VIN4). The subgroup master must be switched on before the register is manipulated, once the operation is complete it's safe to switch the master off and the new routing will still be in effect. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-dma.c | 25 + drivers/media/platform/rcar-vin/rcar-vin.h | 2 ++ 2 files changed, 27 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index c4f8e81e88c99e28..463c656b9878be52 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -16,6 +16,7 @@ #include #include +#include #include @@ -1228,3 +1229,27 @@ int rvin_dma_probe(struct rvin_dev *vin, int irq) return ret; } + +/* - + * Gen3 CHSEL manipulation + */ + +void rvin_set_chsel(struct rvin_dev *vin, u8 chsel) +{ + u32 ifmd, vnmc; + + pm_runtime_get_sync(vin->dev); + + /* Make register writes take effect immediately */ + vnmc = rvin_read(vin, VNMC_REG) & ~VNMC_VUP; + rvin_write(vin, vnmc, VNMC_REG); + + ifmd = VNCSI_IFMD_DES2 | VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 | + VNCSI_IFMD_CSI_CHSEL(chsel); + + rvin_write(vin, ifmd, VNCSI_IFMD_REG); + + vin_dbg(vin, "Set IFMD 0x%x\n", ifmd); + + pm_runtime_put(vin->dev); +} diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 1f761518a6cc60b8..8a7c51724a90786c 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -164,4 +164,6 @@ int rvin_reset_format(struct rvin_dev *vin); const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat); +void rvin_set_chsel(struct rvin_dev *vin, u8 chsel); + #endif -- 2.15.0
[PATCH v7 03/25] rcar-vin: move chip information to own struct
When Gen3 support is added to the driver more than chip ID will be different for the different SoCs. To avoid a lot of if statements in the code create a struct chip_info to store this information. And while we are at it sort the compatible string entries and make use of of_device_get_match_data() which will always work as the driver is DT only, so there's always a valid match. Signed-off-by: Niklas SöderlundReviewed-by: Kieran Bingham Reviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-core.c | 54 ++--- drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 +- drivers/media/platform/rcar-vin/rcar-vin.h | 12 +-- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 856df3e407c05d97..e90e5d014e074d64 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -242,21 +242,53 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) * Platform Device Driver */ +static const struct rvin_info rcar_info_h1 = { + .chip = RCAR_H1, +}; + +static const struct rvin_info rcar_info_m1 = { + .chip = RCAR_M1, +}; + +static const struct rvin_info rcar_info_gen2 = { + .chip = RCAR_GEN2, +}; + static const struct of_device_id rvin_of_id_table[] = { - { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 }, - { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 }, - { .compatible = "renesas,rcar-gen2-vin", .data = (void *)RCAR_GEN2 }, + { + .compatible = "renesas,vin-r8a7778", + .data = _info_m1, + }, + { + .compatible = "renesas,vin-r8a7779", + .data = _info_h1, + }, + { + .compatible = "renesas,vin-r8a7790", + .data = _info_gen2, + }, + { + .compatible = "renesas,vin-r8a7791", + .data = _info_gen2, + }, + { + .compatible = "renesas,vin-r8a7793", + .data = _info_gen2, + }, + { + .compatible = "renesas,vin-r8a7794", + .data = _info_gen2, + }, + { + .compatible = "renesas,rcar-gen2-vin", + .data = _info_gen2, + }, { }, }; MODULE_DEVICE_TABLE(of, rvin_of_id_table); static int rcar_vin_probe(struct platform_device *pdev) { - const struct of_device_id *match; struct rvin_dev *vin; struct resource *mem; int irq, ret; @@ -265,12 +297,8 @@ static int rcar_vin_probe(struct platform_device *pdev) if (!vin) return -ENOMEM; - match = of_match_device(of_match_ptr(rvin_of_id_table), >dev); - if (!match) - return -ENODEV; - vin->dev = >dev; - vin->chip = (enum chip_id)match->data; + vin->info = of_device_get_match_data(>dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (mem == NULL) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 33dd0ec0b82e57dc..be00f4431493eb0a 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -266,7 +266,8 @@ static int __rvin_try_format(struct rvin_dev *vin, pix->sizeimage = max_t(u32, pix->sizeimage, rvin_format_sizeimage(pix)); - if (vin->chip == RCAR_M1 && pix->pixelformat == V4L2_PIX_FMT_XBGR32) { + if (vin->info->chip == RCAR_M1 && + pix->pixelformat == V4L2_PIX_FMT_XBGR32) { vin_err(vin, "pixel format XBGR32 not supported on M1\n"); return -EINVAL; } diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index ab48cdf09889982e..ab240eb4aad9176c 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -88,11 +88,19 @@ struct rvin_graph_entity { unsigned int sink_pad; }; +/** + * struct rvin_info - Information about the particular VIN implementation + * @chip: type of VIN chip + */ +struct rvin_info { + enum chip_id chip; +}; + /** * struct rvin_dev - Renesas VIN device structure * @dev: (OF) device * @base: device I/O register space remapped to virtual memory - * @chip: type of VIN chip + * @info: info about VIN instance
[PATCH v7 02/25] rcar-vin: register the video device at probe time
The driver registers the video device from the async complete callback and unregistered in the async unbind callback. This creates problems if if the subdevice is bound, unbound and later rebound. The second time video_register_device() is called it fails: kobject (eb3be918): tried to init an initialized object, something is seriously wrong. To prevent this register the video device at probe time and don't allow user-space to open the video device if the subdevice is not bound yet. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-core.c | 124 +++- drivers/media/platform/rcar-vin/rcar-v4l2.c | 47 ++- drivers/media/platform/rcar-vin/rcar-vin.h | 5 +- 3 files changed, 95 insertions(+), 81 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 108d776f32651b27..856df3e407c05d97 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -46,54 +46,18 @@ static int rvin_find_pad(struct v4l2_subdev *sd, int direction) return -EINVAL; } -static bool rvin_mbus_supported(struct rvin_graph_entity *entity) -{ - struct v4l2_subdev *sd = entity->subdev; - struct v4l2_subdev_mbus_code_enum code = { - .which = V4L2_SUBDEV_FORMAT_ACTIVE, - }; - - code.index = 0; - code.pad = entity->source_pad; - while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, )) { - code.index++; - switch (code.code) { - case MEDIA_BUS_FMT_YUYV8_1X16: - case MEDIA_BUS_FMT_UYVY8_2X8: - case MEDIA_BUS_FMT_UYVY10_2X10: - case MEDIA_BUS_FMT_RGB888_1X24: - entity->code = code.code; - return true; - default: - break; - } - } - - return false; -} - static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier) { struct rvin_dev *vin = notifier_to_vin(notifier); int ret; - /* Verify subdevices mbus format */ - if (!rvin_mbus_supported(vin->digital)) { - vin_err(vin, "Unsupported media bus format for %s\n", - vin->digital->subdev->name); - return -EINVAL; - } - - vin_dbg(vin, "Found media bus format for %s: %d\n", - vin->digital->subdev->name, vin->digital->code); - ret = v4l2_device_register_subdev_nodes(>v4l2_dev); if (ret < 0) { vin_err(vin, "Failed to register subdev nodes\n"); return ret; } - return rvin_v4l2_probe(vin); + return 0; } static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier, @@ -103,8 +67,15 @@ static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier, struct rvin_dev *vin = notifier_to_vin(notifier); vin_dbg(vin, "unbind digital subdev %s\n", subdev->name); - rvin_v4l2_remove(vin); + + mutex_lock(>lock); + + vin->vdev.ctrl_handler = NULL; + v4l2_ctrl_handler_free(>ctrl_handler); + vin->digital->subdev = NULL; + + mutex_unlock(>lock); } static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier, @@ -112,12 +83,14 @@ static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_async_subdev *asd) { struct rvin_dev *vin = notifier_to_vin(notifier); + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; int ret; v4l2_set_subdev_hostdata(subdev, vin); /* Find source and sink pad of remote subdevice */ - ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE); if (ret < 0) return ret; @@ -126,21 +99,82 @@ static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier, ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK); vin->digital->sink_pad = ret < 0 ? 0 : ret; + /* Find compatible subdevices mbus format */ + vin->digital->code = 0; + code.index = 0; + code.pad = vin->digital->source_pad; + while (!vin->digital->code && + !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, )) { + code.index++; + switch (code.code) { + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY10_2X10: + case MEDIA_BUS_FMT_RGB888_1X24: + vin->digital->code = code.code; + vin_dbg(vin, "Found media bus format for %s: %d\n", + subdev->name, vin->digital->code); + break; + default: + break; +
[PATCH v7 07/25] rcar-vin: all Gen2 boards can scale simplify logic
The logic to preserve the requested format width and height are too complex and come from a premature optimization for Gen3. All Gen2 SoC can scale and the Gen3 implementation will not use these functions at all so simply preserve the width and height when interacting with the subdevice much like the field is preserved simplifies the logic quite a bit. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-dma.c | 8 drivers/media/platform/rcar-vin/rcar-v4l2.c | 22 ++ drivers/media/platform/rcar-vin/rcar-vin.h | 2 -- 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index b71259701d2da20f..daf01bb32b5fc3c2 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -585,14 +585,6 @@ void rvin_crop_scale_comp(struct rvin_dev *vin) 0, 0); } -void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix, - u32 width, u32 height) -{ - /* All VIN channels on Gen2 have scalers */ - pix->width = width; - pix->height = height; -} - /* - * Hardware setup */ diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index f501da9df48c288b..02b081d2d8826e90 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -166,6 +166,7 @@ static int __rvin_try_format_source(struct rvin_dev *vin, .which = which, }; enum v4l2_field field; + u32 width, height; int ret; sd = vin_to_source(vin); @@ -178,7 +179,10 @@ static int __rvin_try_format_source(struct rvin_dev *vin, format.pad = vin->digital->source_pad; + /* Allow the video device to override field and to scale */ field = pix->field; + width = pix->width; + height = pix->height; ret = v4l2_subdev_call(sd, pad, set_fmt, pad_cfg, ); if (ret < 0 && ret != -ENOIOCTLCMD) @@ -191,6 +195,9 @@ static int __rvin_try_format_source(struct rvin_dev *vin, source->width = pix->width; source->height = pix->height; + pix->width = width; + pix->height = height; + vin_dbg(vin, "Source resolution: %ux%u\n", source->width, source->height); @@ -204,13 +211,9 @@ static int __rvin_try_format(struct rvin_dev *vin, struct v4l2_pix_format *pix, struct rvin_source_fmt *source) { - u32 rwidth, rheight, walign; + u32 walign; int ret; - /* Requested */ - rwidth = pix->width; - rheight = pix->height; - /* Keep current field if no specific one is asked for */ if (pix->field == V4L2_FIELD_ANY) pix->field = vin->format.field; @@ -248,10 +251,6 @@ static int __rvin_try_format(struct rvin_dev *vin, break; } - /* If source can't match format try if VIN can scale */ - if (source->width != rwidth || source->height != rheight) - rvin_scale_try(vin, pix, rwidth, rheight); - /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; @@ -270,9 +269,8 @@ static int __rvin_try_format(struct rvin_dev *vin, return -EINVAL; } - vin_dbg(vin, "Requested %ux%u Got %ux%u bpl: %d size: %d\n", - rwidth, rheight, pix->width, pix->height, - pix->bytesperline, pix->sizeimage); + vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n", + pix->width, pix->height, pix->bytesperline, pix->sizeimage); return 0; } diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index e41dc3bff7fdc649..80f38b89ed8d9992 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -177,8 +177,6 @@ int rvin_reset_format(struct rvin_dev *vin); const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat); /* Cropping, composing and scaling */ -void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix, - u32 width, u32 height); void rvin_crop_scale_comp(struct rvin_dev *vin); #endif -- 2.15.0
[PATCH v7 09/25] rcar-vin: do not allow changing scaling and composing while streaming
It is possible on Gen2 to change the registers controlling composing and scaling while the stream is running. It is however not a good idea to do so and could result in trouble. There are also no good reasons to allow this, remove immediate reflection in hardware registers from vidioc_s_selection and only configure scaling and composing when the stream starts. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-dma.c | 2 +- drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 --- drivers/media/platform/rcar-vin/rcar-vin.h | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index daf01bb32b5fc3c2..b478eda84a27bf09 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -514,7 +514,7 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs) rvin_write(vin, p_set->coeff_set[23], VNC8C_REG); } -void rvin_crop_scale_comp(struct rvin_dev *vin) +static void rvin_crop_scale_comp(struct rvin_dev *vin) { u32 xs, ys; diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 25f2386cb67447f2..b3c23634e9dbe095 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -436,9 +436,6 @@ static int rvin_s_selection(struct file *file, void *fh, return -EINVAL; } - /* HW supports modifying configuration while running */ - rvin_crop_scale_comp(vin); - return 0; } diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 80f38b89ed8d9992..111dd8a1974253af 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -176,7 +176,4 @@ int rvin_reset_format(struct rvin_dev *vin); const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat); -/* Cropping, composing and scaling */ -void rvin_crop_scale_comp(struct rvin_dev *vin); - #endif -- 2.15.0
[PATCH v7 21/25] rcar-vin: parse Gen3 OF and setup media graph
Parse the VIN Gen3 OF graph and register all CSI-2 devices in the VIN group common media device. Once all CSI-2 subdevices are added to the common media device create links between them. The parsing and registering CSI-2 subdevices with the v4l2 async framework is a collaborative effort shared between the VIN instances which are part of the group. The first rcar-vin instance parses OF and finds all other VIN and CSI-2 nodes which are part of the graph. It stores a bit mask of all VIN instances found and handles to all CSI-2 nodes. The bit mask is used to figure out when all VIN instances have been probed. Once the last VIN instance is probed this is detected and this instance registers all CSI-2 subdevices in its private async notifier. Once the .complete() callback of this notifier is called it creates the media controller links between all entities in the graph. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-core.c | 297 +++- drivers/media/platform/rcar-vin/rcar-vin.h | 7 +- 2 files changed, 302 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index e204eb3db77c1d2b..78a9766eb7114959 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -405,10 +405,269 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) * Group async notifier */ -static int rvin_group_init(struct rvin_dev *vin) +/* group lock should be held when calling this function */ +static int rvin_group_add_link(struct rvin_dev *vin, + struct media_entity *source, + unsigned int source_idx, + struct media_entity *sink, + unsigned int sink_idx, + u32 flags) +{ + struct media_pad *source_pad, *sink_pad; + int ret = 0; + + source_pad = >pads[source_idx]; + sink_pad = >pads[sink_idx]; + + if (!media_entity_find_link(source_pad, sink_pad)) + ret = media_create_pad_link(source, source_idx, + sink, sink_idx, flags); + + if (ret) + vin_err(vin, "Error adding link from %s to %s\n", + source->name, sink->name); + + return ret; +} + +static int rvin_group_update_links(struct rvin_dev *vin) +{ + struct media_entity *source, *sink; + struct rvin_dev *master; + unsigned int i, n, idx, csi; + int ret = 0; + + mutex_lock(>group->lock); + + for (n = 0; n < RCAR_VIN_NUM; n++) { + + /* Check that VIN is part of the group */ + if (!vin->group->vin[n]) + continue; + + /* Check that subgroup master is part of the group */ + master = vin->group->vin[n < 4 ? 0 : 4]; + if (!master) + continue; + + for (i = 0; i < vin->info->num_chsels; i++) { + csi = vin->info->chsels[n][i].csi; + + /* If the CSI-2 is out of bounds it's a noop, skip */ + if (csi >= RVIN_CSI_MAX) + continue; + + /* Check that CSI-2 are part of the group */ + if (!vin->group->csi[csi].subdev) + continue; + + source = >group->csi[csi].subdev->entity; + sink = >group->vin[n]->vdev.entity; + idx = vin->info->chsels[n][i].chan + 1; + + ret = rvin_group_add_link(vin, source, idx, sink, 0, + 0); + if (ret) + goto out; + } + } +out: + mutex_unlock(>group->lock); + + return ret; +} + +static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) { + struct rvin_dev *vin = notifier_to_vin(notifier); int ret; + ret = v4l2_device_register_subdev_nodes(>v4l2_dev); + if (ret) { + vin_err(vin, "Failed to register subdev nodes\n"); + return ret; + } + + return rvin_group_update_links(vin); +} + +static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, +struct v4l2_subdev *subdev, +struct v4l2_async_subdev *asd) +{ + struct rvin_dev *vin = notifier_to_vin(notifier); + struct rvin_graph_entity *csi = to_rvin_graph_entity(asd); + + mutex_lock(>group->lock); + csi->subdev = NULL; + mutex_unlock(>group->lock); +} + +static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, +
[PATCH v7 15/25] rcar-vin: add flag to switch to media controller mode
On Gen3 a media controller API needs to be used to allow userspace to configure the subdevices in the pipeline instead of directly controlling a single source subdevice, which is and will continue to be the mode of operation on Gen2. Prepare for these two modes of operation by adding a flag to struct rvin_info which will control which mode to use. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-core.c | 6 +- drivers/media/platform/rcar-vin/rcar-vin.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index fa76f494ec0c4bd2..071116eec284ba5f 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -244,18 +244,21 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) static const struct rvin_info rcar_info_h1 = { .chip = RCAR_H1, + .use_mc = false, .max_width = 2048, .max_height = 2048, }; static const struct rvin_info rcar_info_m1 = { .chip = RCAR_M1, + .use_mc = false, .max_width = 2048, .max_height = 2048, }; static const struct rvin_info rcar_info_gen2 = { .chip = RCAR_GEN2, + .use_mc = false, .max_width = 2048, .max_height = 2048, }; @@ -349,7 +352,8 @@ static int rcar_vin_remove(struct platform_device *pdev) v4l2_async_notifier_cleanup(>notifier); /* Checks internaly if handlers have been init or not */ - v4l2_ctrl_handler_free(>ctrl_handler); + if (!vin->info->use_mc) + v4l2_ctrl_handler_free(>ctrl_handler); rvin_v4l2_unregister(vin); diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 8a7c51724a90786c..de269764b00a2fa1 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -77,12 +77,14 @@ struct rvin_graph_entity { /** * struct rvin_info - Information about the particular VIN implementation * @chip: type of VIN chip + * @use_mc:use media controller instead of controlling subdevice * * max_width: max input width the VIN supports * max_height: max input height the VIN supports */ struct rvin_info { enum chip_id chip; + bool use_mc; unsigned int max_width; unsigned int max_height; -- 2.15.0
[PATCH v7 16/25] rcar-vin: break out format alignment and checking
Part of the format alignment and checking can be shared with the Gen3 format handling. Break that part out to its own function. While doing this clean up the checking and add more checks. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 98 +++-- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index f7e04601007edb64..c9a3fe21dea4ce5d 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -86,6 +86,56 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix) return pix->bytesperline * pix->height; } +static int rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) +{ + u32 walign; + + /* If requested format is not supported fallback to the default */ + if (!rvin_format_from_pixel(pix->pixelformat)) { + vin_dbg(vin, "Format 0x%x not found, using default 0x%x\n", + pix->pixelformat, RVIN_DEFAULT_FORMAT); + pix->pixelformat = RVIN_DEFAULT_FORMAT; + } + + switch (pix->field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + break; + default: + pix->field = V4L2_FIELD_NONE; + break; + } + + /* Check that colorspace is reasonable, if not keep current */ + if (!pix->colorspace || pix->colorspace >= 0xff) + pix->colorspace = vin->format.colorspace; + + /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ + walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; + + /* Limit to VIN capabilities */ + v4l_bound_align_image(>width, 2, vin->info->max_width, walign, + >height, 4, vin->info->max_height, 2, 0); + + pix->bytesperline = rvin_format_bytesperline(pix); + pix->sizeimage = rvin_format_sizeimage(pix); + + if (vin->info->chip == RCAR_M1 && + pix->pixelformat == V4L2_PIX_FMT_XBGR32) { + vin_err(vin, "pixel format XBGR32 not supported on M1\n"); + return -EINVAL; + } + + vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n", + pix->width, pix->height, pix->bytesperline, pix->sizeimage); + + return 0; +} + /* - * V4L2 */ @@ -191,64 +241,18 @@ static int __rvin_try_format_source(struct rvin_dev *vin, static int __rvin_try_format(struct rvin_dev *vin, u32 which, struct v4l2_pix_format *pix) { - u32 walign; int ret; /* Keep current field if no specific one is asked for */ if (pix->field == V4L2_FIELD_ANY) pix->field = vin->format.field; - /* If requested format is not supported fallback to the default */ - if (!rvin_format_from_pixel(pix->pixelformat)) { - vin_dbg(vin, "Format 0x%x not found, using default 0x%x\n", - pix->pixelformat, RVIN_DEFAULT_FORMAT); - pix->pixelformat = RVIN_DEFAULT_FORMAT; - } - - /* Always recalculate */ - pix->bytesperline = 0; - pix->sizeimage = 0; - /* Limit to source capabilities */ ret = __rvin_try_format_source(vin, which, pix); if (ret) return ret; - switch (pix->field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_NONE: - case V4L2_FIELD_INTERLACED_TB: - case V4L2_FIELD_INTERLACED_BT: - case V4L2_FIELD_INTERLACED: - break; - default: - pix->field = V4L2_FIELD_NONE; - break; - } - - /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ - walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; - - /* Limit to VIN capabilities */ - v4l_bound_align_image(>width, 2, vin->info->max_width, walign, - >height, 4, vin->info->max_height, 2, 0); - - pix->bytesperline = max_t(u32, pix->bytesperline, - rvin_format_bytesperline(pix)); - pix->sizeimage = max_t(u32, pix->sizeimage, - rvin_format_sizeimage(pix)); - - if (vin->info->chip == RCAR_M1 && - pix->pixelformat == V4L2_PIX_FMT_XBGR32) { - vin_err(vin, "pixel format XBGR32 not supported on M1\n"); - return -EINVAL; - } - - vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n", - pix->width, pix->height, pix->bytesperline,
[PATCH v7 20/25] rcar-vin: add chsel information to rvin_info
Each Gen3 SoC has a limited set of predefined routing possibilities for which CSI-2 device and virtual channel can be routed to which VIN instance. Prepare to store this information in the struct rvin_info. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-vin.h | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index a9bd570d6635fd47..41c81b8d9fb8e851 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -35,6 +35,9 @@ /* Max number on VIN instances that can be in a system */ #define RCAR_VIN_NUM 8 +/* Max number of CHSEL values for any Gen3 SoC */ +#define RCAR_CHSEL_MAX 6 + enum chip_id { RCAR_H1, RCAR_M1, @@ -91,6 +94,22 @@ struct rvin_graph_entity { struct rvin_group; +/** struct rvin_group_chsel - Map a CSI-2 receiver and channel to a CHSEL value + * @csi: VIN internal number for CSI-2 device + * @chan: Output channel of the CSI-2 receiver. Each R-Car CSI-2 + * receiver has four output channels facing the VIN + * devices, each channel can carry one CSI-2 Virtual + * Channel (VC) and there are no correlation between + * output channel number and CSI-2 VC. It's up to the + * CSI-2 receiver driver to configure which VC is + * outputted on which channel, the VIN devices only + * cares about output channels. + */ +struct rvin_group_chsel { + enum rvin_csi_id csi; + unsigned int chan; +}; + /** * struct rvin_info - Information about the particular VIN implementation * @chip: type of VIN chip @@ -98,6 +117,9 @@ struct rvin_group; * * max_width: max input width the VIN supports * max_height: max input height the VIN supports + * + * num_chsels: number of possible chsel values for this VIN + * chsels: routing table VIN <-> CSI-2 for the chsel values */ struct rvin_info { enum chip_id chip; @@ -105,6 +127,9 @@ struct rvin_info { unsigned int max_width; unsigned int max_height; + + unsigned int num_chsels; + struct rvin_group_chsel chsels[RCAR_VIN_NUM][RCAR_CHSEL_MAX]; }; /** -- 2.15.0
[PATCH v7 13/25] rcar-vin: enable Gen3 hardware configuration
Add the register needed to work with Gen3 hardware. This patch adds the logic for how to work with the Gen3 hardware. More work is required to enable the subdevice structure needed to configure capturing. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-dma.c | 94 -- drivers/media/platform/rcar-vin/rcar-vin.h | 1 + 2 files changed, 64 insertions(+), 31 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 9362e7dba5e3ba95..c4f8e81e88c99e28 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -33,21 +33,23 @@ #define VNELPRC_REG0x10/* Video n End Line Pre-Clip Register */ #define VNSPPRC_REG0x14/* Video n Start Pixel Pre-Clip Register */ #define VNEPPRC_REG0x18/* Video n End Pixel Pre-Clip Register */ -#define VNSLPOC_REG0x1C/* Video n Start Line Post-Clip Register */ -#define VNELPOC_REG0x20/* Video n End Line Post-Clip Register */ -#define VNSPPOC_REG0x24/* Video n Start Pixel Post-Clip Register */ -#define VNEPPOC_REG0x28/* Video n End Pixel Post-Clip Register */ #define VNIS_REG 0x2C/* Video n Image Stride Register */ #define VNMB_REG(m)(0x30 + ((m) << 2)) /* Video n Memory Base m Register */ #define VNIE_REG 0x40/* Video n Interrupt Enable Register */ #define VNINTS_REG 0x44/* Video n Interrupt Status Register */ #define VNSI_REG 0x48/* Video n Scanline Interrupt Register */ #define VNMTC_REG 0x4C/* Video n Memory Transfer Control Register */ -#define VNYS_REG 0x50/* Video n Y Scale Register */ -#define VNXS_REG 0x54/* Video n X Scale Register */ #define VNDMR_REG 0x58/* Video n Data Mode Register */ #define VNDMR2_REG 0x5C/* Video n Data Mode Register 2 */ #define VNUVAOF_REG0x60/* Video n UV Address Offset Register */ + +/* Register offsets specific for Gen2 */ +#define VNSLPOC_REG0x1C/* Video n Start Line Post-Clip Register */ +#define VNELPOC_REG0x20/* Video n End Line Post-Clip Register */ +#define VNSPPOC_REG0x24/* Video n Start Pixel Post-Clip Register */ +#define VNEPPOC_REG0x28/* Video n End Pixel Post-Clip Register */ +#define VNYS_REG 0x50/* Video n Y Scale Register */ +#define VNXS_REG 0x54/* Video n X Scale Register */ #define VNC1A_REG 0x80/* Video n Coefficient Set C1A Register */ #define VNC1B_REG 0x84/* Video n Coefficient Set C1B Register */ #define VNC1C_REG 0x88/* Video n Coefficient Set C1C Register */ @@ -73,9 +75,13 @@ #define VNC8B_REG 0xF4/* Video n Coefficient Set C8B Register */ #define VNC8C_REG 0xF8/* Video n Coefficient Set C8C Register */ +/* Register offsets specific for Gen3 */ +#define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */ /* Register bit fields for R-Car VIN */ /* Video n Main Control Register bits */ +#define VNMC_DPINE (1 << 27) /* Gen3 specific */ +#define VNMC_SCLE (1 << 26) /* Gen3 specific */ #define VNMC_FOC (1 << 21) #define VNMC_YCAL (1 << 19) #define VNMC_INF_YUV8_BT656(0 << 16) @@ -119,6 +125,13 @@ #define VNDMR2_FTEV(1 << 17) #define VNDMR2_VLV(n) ((n & 0xf) << 12) +/* Video n CSI2 Interface Mode Register (Gen3) */ +#define VNCSI_IFMD_DES2(1 << 27) +#define VNCSI_IFMD_DES1(1 << 26) +#define VNCSI_IFMD_DES0(1 << 25) +#define VNCSI_IFMD_CSI_CHSEL(n) ((n & 0xf) << 0) +#define VNCSI_IFMD_CSI_CHSEL_MASK 0xf + struct rvin_buffer { struct vb2_v4l2_buffer vb; struct list_head list; @@ -514,28 +527,10 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs) rvin_write(vin, p_set->coeff_set[23], VNC8C_REG); } -static void rvin_crop_scale_comp(struct rvin_dev *vin) +static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin) { u32 xs, ys; - /* Set Start/End Pixel/Line Pre-Clip */ - rvin_write(vin, vin->crop.left, VNSPPRC_REG); - rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG); - switch (vin->format.field) { - case V4L2_FIELD_INTERLACED: - case V4L2_FIELD_INTERLACED_TB: - case V4L2_FIELD_INTERLACED_BT: - rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG); - rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1, - VNELPRC_REG); - break; - default: - rvin_write(vin, vin->crop.top, VNSLPRC_REG); - rvin_write(vin, vin->crop.top + vin->crop.height - 1, - VNELPRC_REG); - break; - } - /* Set scaling coefficient */
[PATCH v7 10/25] rcar-vin: read subdevice format for crop only when needed
Instead of caching the subdevice format each time the video device format is set read it directly when it's needed. As it turns out the format is only needed when figuring out the max rectangle for cropping. This simplifies the code and makes it clearer what the source format is used for. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 88 ++--- drivers/media/platform/rcar-vin/rcar-vin.h | 12 2 files changed, 42 insertions(+), 58 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index b3c23634e9dbe095..ee5df05df2e9561f 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -90,24 +90,30 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix) * V4L2 */ -int rvin_reset_format(struct rvin_dev *vin) +static int rvin_get_sd_format(struct rvin_dev *vin, struct v4l2_pix_format *pix) { struct v4l2_subdev_format fmt = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = vin->digital->source_pad, }; - struct v4l2_mbus_framefmt *mf = int ret; - fmt.pad = vin->digital->source_pad; - ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, ); if (ret) return ret; - vin->format.width = mf->width; - vin->format.height = mf->height; - vin->format.colorspace = mf->colorspace; - vin->format.field = mf->field; + v4l2_fill_pix_format(pix, ); + + return 0; +} + +int rvin_reset_format(struct rvin_dev *vin) +{ + int ret; + + ret = rvin_get_sd_format(vin, >format); + if (ret) + return ret; /* * If the subdevice uses ALTERNATE field mode and G_STD is @@ -137,12 +143,12 @@ int rvin_reset_format(struct rvin_dev *vin) } vin->crop.top = vin->crop.left = 0; - vin->crop.width = mf->width; - vin->crop.height = mf->height; + vin->crop.width = vin->format.width; + vin->crop.height = vin->format.height; vin->compose.top = vin->compose.left = 0; - vin->compose.width = mf->width; - vin->compose.height = mf->height; + vin->compose.width = vin->format.width; + vin->compose.height = vin->format.height; vin->format.bytesperline = rvin_format_bytesperline(>format); vin->format.sizeimage = rvin_format_sizeimage(>format); @@ -151,9 +157,7 @@ int rvin_reset_format(struct rvin_dev *vin) } static int __rvin_try_format_source(struct rvin_dev *vin, - u32 which, - struct v4l2_pix_format *pix, - struct rvin_source_fmt *source) + u32 which, struct v4l2_pix_format *pix) { struct v4l2_subdev *sd; struct v4l2_subdev_pad_config *pad_cfg; @@ -186,25 +190,15 @@ static int __rvin_try_format_source(struct rvin_dev *vin, v4l2_fill_pix_format(pix, ); pix->field = field; - - source->width = pix->width; - source->height = pix->height; - pix->width = width; pix->height = height; - - vin_dbg(vin, "Source resolution: %ux%u\n", source->width, - source->height); - done: v4l2_subdev_free_pad_config(pad_cfg); return ret; } static int __rvin_try_format(struct rvin_dev *vin, -u32 which, -struct v4l2_pix_format *pix, -struct rvin_source_fmt *source) +u32 which, struct v4l2_pix_format *pix) { u32 walign; int ret; @@ -225,7 +219,7 @@ static int __rvin_try_format(struct rvin_dev *vin, pix->sizeimage = 0; /* Limit to source capabilities */ - ret = __rvin_try_format_source(vin, which, pix, source); + ret = __rvin_try_format_source(vin, which, pix); if (ret) return ret; @@ -234,7 +228,6 @@ static int __rvin_try_format(struct rvin_dev *vin, case V4L2_FIELD_BOTTOM: case V4L2_FIELD_ALTERNATE: pix->height /= 2; - source->height /= 2; break; case V4L2_FIELD_NONE: case V4L2_FIELD_INTERLACED_TB: @@ -286,30 +279,23 @@ static int rvin_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct rvin_dev *vin = video_drvdata(file); - struct rvin_source_fmt source; - return __rvin_try_format(vin, V4L2_SUBDEV_FORMAT_TRY, >fmt.pix, -); + return __rvin_try_format(vin, V4L2_SUBDEV_FORMAT_TRY, >fmt.pix); } static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
[PATCH v7 18/25] rcar-vin: prepare for media controller mode initialization
When running in media controller mode a media pad is needed, register one. Also set the media bus format to CSI-2. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-core.c | 24 ++-- drivers/media/platform/rcar-vin/rcar-vin.h | 4 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 071116eec284ba5f..1b3572c8b6691a07 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -46,6 +46,10 @@ static int rvin_find_pad(struct v4l2_subdev *sd, int direction) return -EINVAL; } +/* - + * Digital async notifier + */ + static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier) { struct rvin_dev *vin = notifier_to_vin(notifier); @@ -238,6 +242,20 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) return 0; } +/* - + * Group async notifier + */ + +static int rvin_group_init(struct rvin_dev *vin) +{ + /* All our sources are CSI-2 */ + vin->mbus_cfg.type = V4L2_MBUS_CSI2; + vin->mbus_cfg.flags = 0; + + vin->pad.flags = MEDIA_PAD_FL_SINK; + return media_entity_pads_init(>vdev.entity, 1, >pad); +} + /* - * Platform Device Driver */ @@ -326,8 +344,10 @@ static int rcar_vin_probe(struct platform_device *pdev) return ret; platform_set_drvdata(pdev, vin); - - ret = rvin_digital_graph_init(vin); + if (vin->info->use_mc) + ret = rvin_group_init(vin); + else + ret = rvin_digital_graph_init(vin); if (ret < 0) goto error; diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 2789887efe2f3251..2d92b9dd0aed6cc9 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -103,6 +103,8 @@ struct rvin_info { * @notifier: V4L2 asynchronous subdevs notifier * @digital: entity in the DT for local digital subdevice * + * @pad: pad for media controller + * * @lock: protects @queue * @queue: vb2 buffers queue * @@ -132,6 +134,8 @@ struct rvin_dev { struct v4l2_async_notifier notifier; struct rvin_graph_entity *digital; + struct media_pad pad; + struct mutex lock; struct vb2_queue queue; -- 2.15.0
[PATCH v7 00/25] rcar-vin: Add Gen3 with media controller
Hi, This series adds Gen3 VIN support to rcar-vin driver for Renesas r8a7795 and r8a7796. It is based on the media-tree. The driver is tested on both Renesas H3 (r8a7795, ES2.0) and M3-W (r8a7796) together with the rcar-csi2 driver (posted separately and not yet upstream) and the Salvator-X onboard ADV7482. It is possible to capture both CVBS and HDMI video streams, v4l2-compliance passes with no errors and media-ctl can be used to change the routing and formats for the different entities in the media graph. Gen2 compatibility is verified on Koelsch and no problems where found, video can be captured just like before and v4l2-compliance passes without errors or warnings just like before this series. I have started on a very basic test suite for the VIN driver at: https://git.ragnatech.se/vin-tests And as before the state of the driver and information about how to test it can be found on the elinux wiki: http://elinux.org/R-Car/Tests:rcar-vin * Changes since v6 - Rebase ontop of latest media-tree which brings in the use of the fwnode async helpers for Gen2. - Updated DT binding documentation, thanks Laurent for very helpful input! - Removed help text which where copied in from v4l2_ctrl_handler_init() documentation when moving that code block, this was a residue from the soc_camera conversion and should have been removed at that time. - Removed bad check of tvnorms which disables IOCTLs if it's not set, this was a residue from soc_camera conversion and have use in the current driver. - Moved all subdevice initialization from complete to bound handler while improving the unbind handler. With this move all operations of the ctrl_handler from the subdevice is handled in either bound or unbind removing races pointed out by Laurent. - Renamed rvin_v4l2_probe() -> rvin_v4l2_register() and rvin_v4l2_remove() -> rvin_v4l2_unregister(). - Fold rvin_mbus_supported() into its only caller. - Sort compatible string entries in ascending order. - Improved documentation for struct rvin_group_chsel. - Clarify comment in rvin_group_csi_pad_to_chan(). - Make use of of_device_get_match_data() as suggested by Geert. - Fixed spelling mistakes. - Added review tags from Hans. * Changes since v5 - Extract and make use of common format checking for both Gen2 and Gen3. - Assign pad at declaration time in rvin_get_sd_format() - Always call pm_runtime_{get_sync,put}() and v4l2_pipeline_pm_use() when opening/closing a video device, remove the check of v4l2_fh_is_singular_file(). - Make rvin_set_chsel() return void instead of int since it always return 0. - Simplify the VIN group allocator functions. - Make the group notifier callbacks and setup more robust. - Moved the video device registration back to probe time. - Add H3 ES2.0 support. - Fix handling of single field formats (top, bottom, alternate) as this was obviously wrong before but hidden by the Gen2 scaler support. - Added review tags from Kieran. * Changes since v4 (Not posted to ML) - Updated to the new fwnode functions. - Moved the registration of the video devices to the async notification callback. * Changes since v3 - Only add neighboring subdevices to the async notifier. Instead of parsing the whole OF graph depend on incremental async subnotifier to discover the whole pipeline. This is needed to support arbitrarily long graphs and support the new ADV7482 prototype driver which Kieran is working on. - Fix warning from lockdep, reported by Kieran. - Fix commit messages from feedback from Sergei, thanks. - Fix chip info an OF device ids sorting order, thanks Geert. - Use subdev->of_node instead of subdev->dev->of_node, thanks Kieran. * Changes since v2 - Do not try to control the subdevices in the media graph from the rcar-vin driver. Have user-space configure to format in the pipeline instead. - Add link validation before starting the stream. - Rework on how the subdevices are and the video node behave by defining specific V4L2 operations for the MC mode of operation, this simplified the driver quit a bit, thanks Laurent! - Add a new 'renesas,id' DT property which is needed to to be able to keep the VIN to CSI-2 routing table inside the driver. Previously this information was taken from the CSI-2 DT node which is obviously the wrong way to do things. Thanks Laurent for pointing this out. - Fixed a memory leek in the group allocator function. - Return -EMLINK instead of -EBUSY if a MC link is not possible given the current routing setup. - Add comments to clarify that the 4 channels from the CSI-2 node is not directly related to CSI-2 virtual channels, the CSI-2 node can output any VC on any of its output channels. * Changes since v1 - Remove unneeded casts as pointed out by Geert. - Fix spelling and DT documentation as pointed out by Geert and Sergei, thanks! - Refresh patch 2/32 with an updated version, thanks Sakari for pointing this out. - Add Sakaris Ack to patch 1/32. -
[PATCH v7 19/25] rcar-vin: add group allocator functions
In media controller mode all VIN instances needs to be part of the same media graph. There is also a need to each VIN instance to know and in some cases be able to communicate with other VIN instances. Add an allocator framework where the first VIN instance to be probed creates a shared data structure and creates a media device. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-core.c | 179 +++- drivers/media/platform/rcar-vin/rcar-vin.h | 38 ++ 2 files changed, 216 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 1b3572c8b6691a07..e204eb3db77c1d2b 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -20,12 +20,171 @@ #include #include #include +#include #include #include #include "rcar-vin.h" +/* - + * Gen3 CSI2 Group Allocator + */ + +static int rvin_group_read_id(struct rvin_dev *vin, struct device_node *np) +{ + u32 val; + int ret; + + ret = of_property_read_u32(np, "renesas,id", ); + if (ret) { + vin_err(vin, "%s: No renesas,id property found\n", + of_node_full_name(np)); + return -EINVAL; + } + + if (val >= RCAR_VIN_NUM) { + vin_err(vin, "%s: Invalid renesas,id '%u'\n", + of_node_full_name(np), val); + return -EINVAL; + } + + return val; +} + +static DEFINE_MUTEX(rvin_group_lock); +static struct rvin_group *rvin_group_data; + +static void rvin_group_release(struct kref *kref) +{ + struct rvin_group *group = + container_of(kref, struct rvin_group, refcount); + + mutex_lock(_group_lock); + + media_device_unregister(>mdev); + media_device_cleanup(>mdev); + + rvin_group_data = NULL; + + mutex_unlock(_group_lock); + + kfree(group); +} + +static struct rvin_group *__rvin_group_allocate(struct rvin_dev *vin) +{ + struct rvin_group *group; + + if (rvin_group_data) { + group = rvin_group_data; + kref_get(>refcount); + vin_dbg(vin, "%s: get group=%p\n", __func__, group); + return group; + } + + group = kzalloc(sizeof(*group), GFP_KERNEL); + if (!group) + return NULL; + + kref_init(>refcount); + rvin_group_data = group; + + vin_dbg(vin, "%s: alloc group=%p\n", __func__, group); + return group; +} + +static int rvin_group_add_vin(struct rvin_dev *vin) +{ + int ret; + + ret = rvin_group_read_id(vin, vin->dev->of_node); + if (ret < 0) + return ret; + + mutex_lock(>group->lock); + + if (vin->group->vin[ret]) { + mutex_unlock(>group->lock); + vin_err(vin, "VIN number %d already occupied\n", ret); + return -EINVAL; + } + + vin->group->vin[ret] = vin; + + mutex_unlock(>group->lock); + + vin_dbg(vin, "I'm VIN number %d", ret); + + return 0; +} + +static int rvin_group_allocate(struct rvin_dev *vin) +{ + struct rvin_group *group; + struct media_device *mdev; + int ret; + + mutex_lock(_group_lock); + + group = __rvin_group_allocate(vin); + if (!group) { + mutex_unlock(_group_lock); + return -ENOMEM; + } + + /* Init group data if it is not already initialized */ + mdev = >mdev; + if (!mdev->dev) { + mutex_init(>lock); + mdev->dev = vin->dev; + + strlcpy(mdev->driver_name, "Renesas VIN", + sizeof(mdev->driver_name)); + strlcpy(mdev->model, vin->dev->of_node->name, + sizeof(mdev->model)); + strlcpy(mdev->bus_info, of_node_full_name(vin->dev->of_node), + sizeof(mdev->bus_info)); + media_device_init(mdev); + + ret = media_device_register(mdev); + if (ret) { + vin_err(vin, "Failed to register media device\n"); + kref_put(>refcount, rvin_group_release); + mutex_unlock(_group_lock); + return ret; + } + } + + vin->group = group; + vin->v4l2_dev.mdev = mdev; + + ret = rvin_group_add_vin(vin); + if (ret) { + kref_put(>refcount, rvin_group_release); + mutex_unlock(_group_lock); + return ret; + } + + mutex_unlock(_group_lock); + + return 0; +} + +static void rvin_group_delete(struct rvin_dev *vin) +{ + unsigned int i; + + mutex_lock(>group->lock); +
[PATCH v7 24/25] rcar-vin: enable support for r8a7795
Add the SoC specific information for Renesas r8a7795 ES1.x and ES2.0. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/Kconfig | 2 +- drivers/media/platform/rcar-vin/rcar-core.c | 150 2 files changed, 151 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig index af4c98b44d2e22cb..8fa7ee468c63afb9 100644 --- a/drivers/media/platform/rcar-vin/Kconfig +++ b/drivers/media/platform/rcar-vin/Kconfig @@ -6,7 +6,7 @@ config VIDEO_RCAR_VIN select V4L2_FWNODE ---help--- Support for Renesas R-Car Video Input (VIN) driver. - Supports R-Car Gen2 SoCs. + Supports R-Car Gen2 and Gen3 SoCs. To compile this driver as a module, choose M here: the module will be called rcar-vin. diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 79b0334d8c563328..b22f6596700d2479 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -955,6 +956,134 @@ static const struct rvin_info rcar_info_gen2 = { .max_height = 2048, }; +static const struct rvin_info rcar_info_r8a7795 = { + .chip = RCAR_GEN3, + .use_mc = true, + .max_width = 4096, + .max_height = 4096, + + .num_chsels = 5, + .chsels = { + { + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 1 }, + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + }, { + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 1 }, + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 1 }, + { .csi = RVIN_CSI20, .chan = 1 }, + }, { + { .csi = RVIN_CSI20, .chan = 1 }, + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 2 }, + { .csi = RVIN_CSI20, .chan = 2 }, + }, { + { .csi = RVIN_CSI40, .chan = 1 }, + { .csi = RVIN_CSI20, .chan = 1 }, + { .csi = RVIN_CSI20, .chan = 1 }, + { .csi = RVIN_CSI40, .chan = 3 }, + { .csi = RVIN_CSI20, .chan = 3 }, + }, { + { .csi = RVIN_CSI41, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_CSI41, .chan = 1 }, + { .csi = RVIN_CSI41, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + }, { + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_CSI41, .chan = 1 }, + { .csi = RVIN_CSI41, .chan = 0 }, + { .csi = RVIN_CSI41, .chan = 1 }, + { .csi = RVIN_CSI20, .chan = 1 }, + }, { + { .csi = RVIN_CSI20, .chan = 1 }, + { .csi = RVIN_CSI41, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_CSI41, .chan = 2 }, + { .csi = RVIN_CSI20, .chan = 2 }, + }, { + { .csi = RVIN_CSI41, .chan = 1 }, + { .csi = RVIN_CSI20, .chan = 1 }, + { .csi = RVIN_CSI20, .chan = 1 }, + { .csi = RVIN_CSI41, .chan = 3 }, + { .csi = RVIN_CSI20, .chan = 3 }, + }, + }, +}; + +static const struct rvin_info rcar_info_r8a7795es1 = { + .chip = RCAR_GEN3, + .use_mc = true, + .max_width = 4096, + .max_height = 4096, + + .num_chsels = 6, + .chsels = { + { + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_CSI21, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_CSI21, .chan = 0 }, + }, { + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_CSI21, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 1 }, + { .csi = RVIN_CSI20,
[PATCH v7 11/25] rcar-vin: fix handling of single field frames (top, bottom and alternate fields)
There was never proper support in the VIN driver to deliver ALTERNATING field format to user-space, remove this field option. For sources using this field format instead use the VIN hardware feature of combining the fields to an interlaced format. This mode of operation was previously the default behavior and ALTERNATING was only delivered to user-space if explicitly requested. Allowing this to be explicitly requested was a mistake and was never properly tested and never worked due to the constraints put on the field format when it comes to sequence numbers and timestamps etc. The height should not be cut in half for the format for TOP or BOTTOM fields settings. This was a mistake and it was made visible by the scaling refactoring. Correct behavior is that the user should request a frame size that fits the half height frame reflected in the field setting. If not the VIN will do its best to scale the top or bottom to the requested format and cropping and scaling do not work as expected. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-dma.c | 15 + drivers/media/platform/rcar-vin/rcar-v4l2.c | 48 +++-- 2 files changed, 19 insertions(+), 44 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index b478eda84a27bf09..506d51a13b4f5f40 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -617,7 +617,6 @@ static int rvin_setup(struct rvin_dev *vin) case V4L2_FIELD_INTERLACED_BT: vnmc = VNMC_IM_FULL | VNMC_FOC; break; - case V4L2_FIELD_ALTERNATE: case V4L2_FIELD_NONE: if (vin->continuous) { vnmc = VNMC_IM_ODD_EVEN; @@ -757,18 +756,6 @@ static int rvin_get_active_slot(struct rvin_dev *vin, u32 vnms) return 0; } -static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms) -{ - if (vin->format.field == V4L2_FIELD_ALTERNATE) { - /* If FS is set it's a Even field */ - if (vnms & VNMS_FS) - return V4L2_FIELD_BOTTOM; - return V4L2_FIELD_TOP; - } - - return vin->format.field; -} - static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr) { const struct rvin_video_format *fmt; @@ -941,7 +928,7 @@ static irqreturn_t rvin_irq(int irq, void *data) goto done; /* Capture frame */ - vin->queue_buf[slot]->field = rvin_get_active_field(vin, vnms); + vin->queue_buf[slot]->field = vin->format.field; vin->queue_buf[slot]->sequence = sequence; vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns(); vb2_buffer_done(>queue_buf[slot]->vb2_buf, VB2_BUF_STATE_DONE); diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index ee5df05df2e9561f..b4e96e18ab845f8b 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -102,6 +102,24 @@ static int rvin_get_sd_format(struct rvin_dev *vin, struct v4l2_pix_format *pix) if (ret) return ret; + switch (fmt.format.field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + break; + case V4L2_FIELD_ALTERNATE: + /* Use VIN hardware to combine the two fields */ + fmt.format.field = V4L2_FIELD_INTERLACED; + fmt.format.height *= 2; + break; + default: + vin->format.field = V4L2_FIELD_NONE; + break; + } + v4l2_fill_pix_format(pix, ); return 0; @@ -115,33 +133,6 @@ int rvin_reset_format(struct rvin_dev *vin) if (ret) return ret; - /* -* If the subdevice uses ALTERNATE field mode and G_STD is -* implemented use the VIN HW to combine the two fields to -* one INTERLACED frame. The ALTERNATE field mode can still -* be requested in S_FMT and be respected, this is just the -* default which is applied at probing or when S_STD is called. -*/ - if (vin->format.field == V4L2_FIELD_ALTERNATE && - v4l2_subdev_has_op(vin_to_source(vin), video, g_std)) - vin->format.field = V4L2_FIELD_INTERLACED; - - switch (vin->format.field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_ALTERNATE: - vin->format.height /= 2; - break; - case V4L2_FIELD_NONE: - case V4L2_FIELD_INTERLACED_TB: - case V4L2_FIELD_INTERLACED_BT: - case V4L2_FIELD_INTERLACED:
[PATCH v7 23/25] rcar-vin: extend {start,stop}_streaming to work with media controller
The procedure to start or stop streaming using the non-MC single subdevice and the MC graph and multiple subdevices are quite different. Create a new function to abstract which method is used based on which mode the driver is running in and add logic to start the MC graph. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-dma.c | 113 +++-- 1 file changed, 106 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index fe1319eb4c5df02d..b16b892a4de876bb 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1087,15 +1087,116 @@ static void rvin_buffer_queue(struct vb2_buffer *vb) spin_unlock_irqrestore(>qlock, flags); } +static int rvin_set_stream(struct rvin_dev *vin, int on) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct media_pipeline *pipe; + struct v4l2_subdev *sd; + struct media_pad *pad; + int ret; + + /* No media controller used, simply pass operation to subdevice */ + if (!vin->info->use_mc) { + ret = v4l2_subdev_call(vin->digital->subdev, video, s_stream, + on); + + return ret == -ENOIOCTLCMD ? 0 : ret; + } + + pad = media_entity_remote_pad(>pad); + if (!pad) + return -EPIPE; + + sd = media_entity_to_v4l2_subdev(pad->entity); + if (!sd) + return -EPIPE; + + if (!on) { + media_pipeline_stop(>vdev.entity); + ret = v4l2_subdev_call(sd, video, s_stream, 0); + return 0; + } + + fmt.pad = pad->index; + if (v4l2_subdev_call(sd, pad, get_fmt, NULL, )) + return -EPIPE; + + switch (fmt.format.code) { + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY10_2X10: + case MEDIA_BUS_FMT_RGB888_1X24: + vin->code = fmt.format.code; + break; + default: + return -EPIPE; + } + + switch (fmt.format.field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + case V4L2_FIELD_SEQ_TB: + case V4L2_FIELD_SEQ_BT: + /* Supported nativly */ + break; + case V4L2_FIELD_ALTERNATE: + switch (vin->format.field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + break; + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + case V4L2_FIELD_SEQ_TB: + case V4L2_FIELD_SEQ_BT: + /* Use VIN hardware to combine the two fields */ + fmt.format.height *= 2; + break; + default: + return -EPIPE; + } + break; + default: + return -EPIPE; + } + + if (fmt.format.width != vin->format.width || + fmt.format.height != vin->format.height) + return -EPIPE; + + pipe = sd->entity.pipe ? sd->entity.pipe : >vdev.pipe; + if (media_pipeline_start(>vdev.entity, pipe)) + return -EPIPE; + + ret = v4l2_subdev_call(sd, video, s_stream, 1); + if (ret == -ENOIOCTLCMD) + ret = 0; + if (ret) + media_pipeline_stop(>vdev.entity); + + return ret; +} + static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) { struct rvin_dev *vin = vb2_get_drv_priv(vq); - struct v4l2_subdev *sd; unsigned long flags; int ret; - sd = vin_to_source(vin); - v4l2_subdev_call(sd, video, s_stream, 1); + ret = rvin_set_stream(vin, 1); + if (ret) { + spin_lock_irqsave(>qlock, flags); + return_all_buffers(vin, VB2_BUF_STATE_QUEUED); + spin_unlock_irqrestore(>qlock, flags); + return ret; + } spin_lock_irqsave(>qlock, flags); @@ -1104,7 +1205,7 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) ret = rvin_capture_start(vin); if (ret) { return_all_buffers(vin, VB2_BUF_STATE_QUEUED); - v4l2_subdev_call(sd, video, s_stream, 0); + rvin_set_stream(vin, 0); } spin_unlock_irqrestore(>qlock, flags); @@ -1115,7 +1216,6 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) static void
[PATCH v7 12/25] rcar-vin: move media bus configuration to struct rvin_info
Bus configuration will once the driver is extended to support Gen3 contain information not specific to only the directly connected parallel subdevice. Move it to struct rvin_info to show it's not always coupled to the parallel subdevice. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-core.c | 18 +- drivers/media/platform/rcar-vin/rcar-dma.c | 11 ++- drivers/media/platform/rcar-vin/rcar-v4l2.c | 2 +- drivers/media/platform/rcar-vin/rcar-vin.h | 9 - 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index cb761057459caa3f..fa76f494ec0c4bd2 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -100,10 +100,10 @@ static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier, vin->digital->sink_pad = ret < 0 ? 0 : ret; /* Find compatible subdevices mbus format */ - vin->digital->code = 0; + vin->code = 0; code.index = 0; code.pad = vin->digital->source_pad; - while (!vin->digital->code && + while (!vin->code && !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, )) { code.index++; switch (code.code) { @@ -111,16 +111,16 @@ static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier, case MEDIA_BUS_FMT_UYVY8_2X8: case MEDIA_BUS_FMT_UYVY10_2X10: case MEDIA_BUS_FMT_RGB888_1X24: - vin->digital->code = code.code; + vin->code = code.code; vin_dbg(vin, "Found media bus format for %s: %d\n", - subdev->name, vin->digital->code); + subdev->name, vin->code); break; default: break; } } - if (!vin->digital->code) { + if (!vin->code) { vin_err(vin, "Unsupported media bus format for %s\n", subdev->name); return -EINVAL; @@ -186,16 +186,16 @@ static int rvin_digital_parse_v4l2(struct device *dev, if (vep->base.port || vep->base.id) return -ENOTCONN; - rvge->mbus_cfg.type = vep->bus_type; + vin->mbus_cfg.type = vep->bus_type; - switch (rvge->mbus_cfg.type) { + switch (vin->mbus_cfg.type) { case V4L2_MBUS_PARALLEL: vin_dbg(vin, "Found PARALLEL media bus\n"); - rvge->mbus_cfg.flags = vep->bus.parallel.flags; + vin->mbus_cfg.flags = vep->bus.parallel.flags; break; case V4L2_MBUS_BT656: vin_dbg(vin, "Found BT656 media bus\n"); - rvge->mbus_cfg.flags = 0; + vin->mbus_cfg.flags = 0; break; default: vin_err(vin, "Unknown media bus type\n"); diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 506d51a13b4f5f40..9362e7dba5e3ba95 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -633,7 +633,7 @@ static int rvin_setup(struct rvin_dev *vin) /* * Input interface */ - switch (vin->digital->code) { + switch (vin->code) { case MEDIA_BUS_FMT_YUYV8_1X16: /* BT.601/BT.1358 16bit YCbCr422 */ vnmc |= VNMC_INF_YUV16; @@ -641,7 +641,7 @@ static int rvin_setup(struct rvin_dev *vin) break; case MEDIA_BUS_FMT_UYVY8_2X8: /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? + vnmc |= vin->mbus_cfg.type == V4L2_MBUS_BT656 ? VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601; input_is_yuv = true; break; @@ -650,7 +650,7 @@ static int rvin_setup(struct rvin_dev *vin) break; case MEDIA_BUS_FMT_UYVY10_2X10: /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? + vnmc |= vin->mbus_cfg.type == V4L2_MBUS_BT656 ? VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601; input_is_yuv = true; break; @@ -662,11 +662,11 @@ static int rvin_setup(struct rvin_dev *vin) dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1); /* Hsync Signal Polarity Select */ - if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) + if (!(vin->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) dmr2 |= VNDMR2_HPS; /* Vsync Signal Polarity
[PATCH v7 25/25] rcar-vin: enable support for r8a7796
Add the SoC specific information for Renesas r8a7796. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- .../devicetree/bindings/media/rcar_vin.txt | 1 + drivers/media/platform/rcar-vin/rcar-core.c| 64 ++ 2 files changed, 65 insertions(+) diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt index df1abd0fb20386f8..ddf249c2276600d2 100644 --- a/Documentation/devicetree/bindings/media/rcar_vin.txt +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt @@ -10,6 +10,7 @@ Depending on the instance the VIN input is connected to external SoC pins, or on Gen3 to a CSI-2 receiver. - compatible: Must be one or more of the following + - "renesas,vin-r8a7796" for the R8A7796 device - "renesas,vin-r8a7795" for the R8A7795 device - "renesas,vin-r8a7794" for the R8A7794 device - "renesas,vin-r8a7793" for the R8A7793 device diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index b22f6596700d2479..e329de4ce0172e8d 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -1084,6 +1084,66 @@ static const struct rvin_info rcar_info_r8a7795es1 = { }, }; +static const struct rvin_info rcar_info_r8a7796 = { + .chip = RCAR_GEN3, + .use_mc = true, + .max_width = 4096, + .max_height = 4096, + + .num_chsels = 5, + .chsels = { + { + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_NC, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + }, { + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_NC, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 1 }, + { .csi = RVIN_CSI20, .chan = 1 }, + }, { + { .csi = RVIN_NC, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 2 }, + { .csi = RVIN_CSI20, .chan = 2 }, + }, { + { .csi = RVIN_CSI40, .chan = 1 }, + { .csi = RVIN_CSI20, .chan = 1 }, + { .csi = RVIN_NC, .chan = 1 }, + { .csi = RVIN_CSI40, .chan = 3 }, + { .csi = RVIN_CSI20, .chan = 3 }, + }, { + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_NC, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + }, { + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_NC, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 1 }, + { .csi = RVIN_CSI20, .chan = 1 }, + }, { + { .csi = RVIN_NC, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 0 }, + { .csi = RVIN_CSI20, .chan = 0 }, + { .csi = RVIN_CSI40, .chan = 2 }, + { .csi = RVIN_CSI20, .chan = 2 }, + }, { + { .csi = RVIN_CSI40, .chan = 1 }, + { .csi = RVIN_CSI20, .chan = 1 }, + { .csi = RVIN_NC, .chan = 1 }, + { .csi = RVIN_CSI40, .chan = 3 }, + { .csi = RVIN_CSI20, .chan = 3 }, + }, + }, +}; + static const struct of_device_id rvin_of_id_table[] = { { .compatible = "renesas,vin-r8a7778", @@ -1117,6 +1177,10 @@ static const struct of_device_id rvin_of_id_table[] = { .compatible = "renesas,vin-r8a7795", .data = _info_r8a7795, }, + { + .compatible = "renesas,vin-r8a7796", + .data = _info_r8a7796, + }, { }, }; MODULE_DEVICE_TABLE(of, rvin_of_id_table); -- 2.15.0
[PATCH v7 22/25] rcar-vin: add link notify for Gen3
Add the ability to process media device link change request. Link enabling is a bit complicated on Gen3, whether or not it's possible to enable a link depends on what other links already are enabled. On Gen3 the 8 VINs are split into two subgroup's (VIN0-3 and VIN4-7) and from a routing perspective these two groups are independent of each other. Each subgroup's routing is controlled by the subgroup VIN master instance (VIN0 and VIN4). There are a limited number of possible route setups available for each subgroup and the configuration of each setup is dictated by the hardware. On H3 for example there are 6 possible route setups for each subgroup to choose from. This leads to the media device link notification code being rather large since it will find the best routing configuration to try and accommodate as many links as possible. When it's not possible to enable a new link due to hardware constrains the link_notifier callback will return -EMLINK. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-core.c | 205 1 file changed, 205 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 78a9766eb7114959..79b0334d8c563328 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -27,6 +27,209 @@ #include "rcar-vin.h" +/* - + * Media Controller link notification + */ + +static unsigned int rvin_group_csi_pad_to_chan(unsigned int pad) +{ + /* +* The companion CSI-2 receiver driver (rcar-csi2) is known +* and we know it have one source pad (pad 0) and four sink +* pads (pad 1-4). So to translate a pad on the remote +* CSI-2 receiver to the VIN internal channel number simply +* subtract one from the pad number. +*/ + return pad - 1; +} + +/* group lock should be held when calling this function */ +static int rvin_group_entity_to_vin_num(struct rvin_group *group, + struct media_entity *entity) +{ + struct video_device *vdev; + int i; + + if (!is_media_entity_v4l2_video_device(entity)) + return -ENODEV; + + vdev = media_entity_to_video_device(entity); + + for (i = 0; i < RCAR_VIN_NUM; i++) { + if (!group->vin[i]) + continue; + + if (>vin[i]->vdev == vdev) + return i; + } + + return -ENODEV; +} + +/* group lock should be held when calling this function */ +static int rvin_group_entity_to_csi_num(struct rvin_group *group, + struct media_entity *entity) +{ + struct v4l2_subdev *sd; + int i; + + if (!is_media_entity_v4l2_subdev(entity)) + return -ENODEV; + + sd = media_entity_to_v4l2_subdev(entity); + + for (i = 0; i < RVIN_CSI_MAX; i++) + if (group->csi[i].subdev == sd) + return i; + + return -ENODEV; +} + +/* group lock should be held when calling this function */ +static void __rvin_group_build_link_list(struct rvin_group *group, +struct rvin_group_chsel *map, +int start, int len) +{ + struct media_pad *vin_pad, *remote_pad; + unsigned int n; + + for (n = 0; n < len; n++) { + map[n].csi = -1; + map[n].chan = -1; + + if (!group->vin[start + n]) + continue; + + vin_pad = >vin[start + n]->vdev.entity.pads[0]; + + remote_pad = media_entity_remote_pad(vin_pad); + if (!remote_pad) + continue; + + map[n].csi = + rvin_group_entity_to_csi_num(group, remote_pad->entity); + map[n].chan = rvin_group_csi_pad_to_chan(remote_pad->index); + } +} + +/* group lock should be held when calling this function */ +static int __rvin_group_try_get_chsel(struct rvin_group *group, + struct rvin_group_chsel *map, + int start, int len) +{ + const struct rvin_group_chsel *sel; + unsigned int i, n; + int chsel; + + for (i = 0; i < group->vin[start]->info->num_chsels; i++) { + chsel = i; + for (n = 0; n < len; n++) { + + /* If the link is not active it's OK */ + if (map[n].csi == -1) + continue; + + /* Check if chsel matches requested link */ + sel = >vin[start]->info->chsels[start + n][i]; + if (map[n].csi != sel->csi || + map[n].chan != sel->chan)
[PATCH v11 1/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation
Documentation for Renesas R-Car MIPI CSI-2 receiver. The CSI-2 receivers are located between the video sources (CSI-2 transmitters) and the video grabbers (VIN) on Gen3 of Renesas R-Car SoC. Each CSI-2 device is connected to more then one VIN device which simultaneously can receive video from the same CSI-2 device. Each VIN device can also be connected to more then one CSI-2 device. The routing of which link are used are controlled by the VIN devices. There are only a few possible routes which are set by hardware limitations, which are different for each SoC in the Gen3 family. To work with the limitations of routing possibilities it is necessary for the DT bindings to describe which VIN device is connected to which CSI-2 device. This is why port 1 needs to to assign reg numbers for each VIN device that be connected to it. To setup and to know which links are valid for each SoC is the responsibility of the VIN driver since the register to configure it belongs to the VIN hardware. Signed-off-by: Niklas Söderlund--- .../bindings/media/renesas,rcar-csi2.txt | 104 + MAINTAINERS| 1 + 2 files changed, 105 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt diff --git a/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt new file mode 100644 index ..24705d8997b14a10 --- /dev/null +++ b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt @@ -0,0 +1,104 @@ +Renesas R-Car MIPI CSI-2 + + +The rcar-csi2 device provides MIPI CSI-2 capabilities for the Renesas R-Car +family of devices. It is to be used in conjunction with the R-Car VIN module, +which provides the video capture capabilities. + +Mandatory properties + + - compatible: Must be one or more of the following + - "renesas,r8a7795-csi2" for the R8A7795 device. + - "renesas,r8a7796-csi2" for the R8A7796 device. + + - reg: the register base and size for the device registers + - interrupts: the interrupt for the device + - clocks: Reference to the parent clock + +The device node shall contain two 'port' child nodes according to the +bindings defined in Documentation/devicetree/bindings/media/ +video-interfaces.txt. Port 0 shall connect the node that is the video +source for to the CSI-2. Port 1 shall connect all the R-Car VIN +modules, which can make use of the CSI-2 module. + +- Port 0 - Video source (Mandatory) + - Endpoint 0 - sub-node describing the endpoint that is the video source + +- Port 1 - VIN instances (Mandatory for all VIN present in the SoC) + - Endpoint 0 - sub-node describing the endpoint that is VIN0 + - Endpoint 1 - sub-node describing the endpoint that is VIN1 + - Endpoint 2 - sub-node describing the endpoint that is VIN2 + - Endpoint 3 - sub-node describing the endpoint that is VIN3 + - Endpoint 4 - sub-node describing the endpoint that is VIN4 + - Endpoint 5 - sub-node describing the endpoint that is VIN5 + - Endpoint 6 - sub-node describing the endpoint that is VIN6 + - Endpoint 7 - sub-node describing the endpoint that is VIN7 + +Example: + + csi20: csi2@fea8 { + compatible = "renesas,r8a7796-csi2", "renesas,rcar-gen3-csi2"; + reg = <0 0xfea8 0 0x1>; + interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + clocks = < CPG_MOD 714>; + power-domains = < R8A7796_PD_ALWAYS_ON>; + resets = < 714>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <0>; + + csi20_in: endpoint@0 { + clock-lanes = <0>; + data-lanes = <1>; + remote-endpoint = <_txb>; + }; + }; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + csi20vin0: endpoint@0 { + reg = <0>; + remote-endpoint = <>; + }; + csi20vin1: endpoint@1 { + reg = <1>; + remote-endpoint = <>; + }; + csi20vin2: endpoint@2 { + reg = <2>; +
[PATCH v11 2/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver
A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver supports the rcar-vin driver on 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--- drivers/media/platform/rcar-vin/Kconfig | 12 + drivers/media/platform/rcar-vin/Makefile| 1 + drivers/media/platform/rcar-vin/rcar-csi2.c | 896 3 files changed, 909 insertions(+) create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig index af4c98b44d2e22cb..6875f30c1ae42631 100644 --- a/drivers/media/platform/rcar-vin/Kconfig +++ b/drivers/media/platform/rcar-vin/Kconfig @@ -1,3 +1,15 @@ +config VIDEO_RCAR_CSI2 + tristate "R-Car MIPI CSI-2 Receiver" + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF + depends on ARCH_RENESAS || COMPILE_TEST + select V4L2_FWNODE + ---help--- + Support for Renesas R-Car MIPI CSI-2 receiver. + Supports R-Car Gen3 SoCs. + + To compile this driver as a module, choose M here: the + module will be called rcar-csi2. + config VIDEO_RCAR_VIN tristate "R-Car Video Input (VIN) Driver" depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && MEDIA_CONTROLLER diff --git a/drivers/media/platform/rcar-vin/Makefile b/drivers/media/platform/rcar-vin/Makefile index 48c5632c21dc060b..5ab803d3e7c1aa57 100644 --- a/drivers/media/platform/rcar-vin/Makefile +++ b/drivers/media/platform/rcar-vin/Makefile @@ -1,3 +1,4 @@ rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o 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 ..4202c60b4d0aa7f7 --- /dev/null +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -0,0 +1,896 @@ +/* + * Driver for Renesas R-Car MIPI CSI-2 Receiver + * + * Copyright (C) 2017 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Register offsets and bits */ + +/* Control Timing Select */ +#define TREF_REG 0x00 +#define TREF_TREF BIT(0) + +/* Software Reset */ +#define SRST_REG 0x04 +#define SRST_SRST BIT(0) + +/* PHY Operation Control */ +#define PHYCNT_REG 0x08 +#define PHYCNT_SHUTDOWNZ BIT(17) +#define PHYCNT_RSTZBIT(16) +#define PHYCNT_ENABLECLK BIT(4) +#define PHYCNT_ENABLE_3BIT(3) +#define PHYCNT_ENABLE_2BIT(2) +#define PHYCNT_ENABLE_1BIT(1) +#define PHYCNT_ENABLE_0BIT(0) + +/* Checksum Control */ +#define CHKSUM_REG 0x0c +#define CHKSUM_ECC_EN BIT(1) +#define CHKSUM_CRC_EN BIT(0) + +/* + * Channel Data Type Select + * VCDT[0-15]: Channel 1 VCDT[16-31]: Channel 2 + * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4 + */ +#define VCDT_REG 0x10 +#define VCDT2_REG 0x14 +#define VCDT_VCDTN_EN BIT(15) +#define VCDT_SEL_VC(n) (((n) & 0x3) << 8) +#define VCDT_SEL_DTN_ONBIT(6) +#define VCDT_SEL_DT(n) (((n) & 0x3f) << 0) + +/* Frame Data Type Select */ +#define FRDT_REG 0x18 + +/* Field Detection Control */ +#define FLD_REG0x1c +#define FLD_FLD_NUM(n) (((n) & 0xff) << 16) +#define FLD_FLD_EN4BIT(3) +#define FLD_FLD_EN3BIT(2) +#define FLD_FLD_EN2BIT(1) +#define FLD_FLD_EN BIT(0) + +/* Automatic Standby Control */ +#define ASTBY_REG 0x20 + +/* Long Data Type Setting 0 */ +#define LNGDT0_REG 0x28 + +/* Long Data Type Setting 1 */ +#define LNGDT1_REG 0x2c + +/* Interrupt Enable */ +#define INTEN_REG 0x30 + +/* Interrupt Source Mask */ +#define INTCLOSE_REG 0x34 + +/* Interrupt Status Monitor */ +#define INTSTATE_REG 0x38 +#define INTSTATE_INT_ULPS_STARTBIT(7) +#define INTSTATE_INT_ULPS_END
[PATCH v11 0/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2
Hi, This is the latest incarnation of R-Car MIPI CSI-2 receiver driver. It's based on top of the media-tree and are tested on Renesas Salvator-X together with the out-of-tree patches for rcar-vin to add support for Gen3 VIN. If anyone is interested to test video grabbing using these out of tree patches please see [1]. * Changes since v10 - Renamed Documentation/devicetree/bindings/media/rcar-csi2.txt to Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt - Add extra newline in rcar_csi2_code_to_fmt() - Use locally stored format information instead of reading it from the remote subdevice, Sakari pointed out that the pipeline is validated before .s_stream() is called so this is safe. - Do not check return from media_entity_to_v4l2_subdev() in rcar_csi2_start(), Sakari pointed out it can't fail. Also move logic to find the remote subdevice is moved to the only user of it, rcar_csi2_calc_phypll(). - Move pm_runtime_get_sync() and pm_runtime_put() to rcar_csi2_s_stream() and remove rcar_csi2_s_power(). - Add validation of pixel code to rcar_csi2_set_pad_format(). - Remove static rcar_csi2_notify_unbind() as it only printed a debug message. * Changes since v9 - Add reset property to device tree example - Use BIT(x) instead of (1 << x) - Use u16 in struct phypll_hsfreqrange to pack struct better. - Use unsigned int type for loop variable in rcar_csi2_code_to_fmt - Move fields inside struct struct rcar_csi2_info and struct rcar_csi2 to pack struct's tighter. - Use %u instead of %d when printing __u32. - Don't check return of platform_get_resource(), let devm_ioremap_resource() handle it. - Store quirk workaround for r8a7795 ES1.0 in the data field of struct soc_device_attribute. Changes since v8: - Updated bindings documentation, thanks Rob! - Make use of the now in media-tree sub-notifier V4L2 API - Add delay when resetting the IP to allow for a proper reset - Fix bug in s_stream error path where the usage count was off if an error was hit. - Add support for H3 ES2.0 Changes since v7: - Rebase on top of the latest incremental async patches. - Fix comments on DT documentation. - Use v4l2_ctrl_g_ctrl_int64() instead of v4l2_g_ext_ctrls(). - Handle try formats in .set_fmt() and .get_fmt(). - Don't call v4l2_device_register_subdev_nodes() as this is not needed with the complete() callbacks synchronized. - Fix line over 80 chars. - Fix varies spelling mistakes. Changes since v6: - Rebased on top of Sakaris fwnode patches. - Changed of RCAR_CSI2_PAD_MAX to NR_OF_RCAR_CSI2_PAD. - Remove assumption about unknown media bus type, thanks Sakari for pointing this out. - Created table for supported format information instead of scattering this information around the driver, thanks Sakari! - Small newline fixes and reduce some indentation levels. Changes since v5: - Make use of the incremental async subnotifer and helper to map DT endpoint to media pad number. This moves functionality which previously in the Gen3 patches for R-Car VIN driver to this R-Car CSI-2 driver. This is done in preparation to support the ADV7482 driver in development by Kieran which will register more then one subdevice and the CSI-2 driver needs to cope wit this. Further more it prepares the driver for another use-case where more then one subdevice is present upstream for the CSI-2. - Small cleanups. - Add explicit include for linux/io.h, thanks Kieran. Changes since v4: - Match SoC part numbers and drop trailing space in documentation, thanks Geert for pointing this out. - Clarify that the driver is a CSI-2 receiver by supervised s/interface/receiver/, thanks Laurent. - Add entries in Kconfig and Makefile alphabetically instead of append. - Rename struct rcar_csi2 member swap to lane_swap. - Remove macros to wrap calls to dev_{dbg,info,warn,err}. - Add wrappers for ioread32 and iowrite32. - Remove unused interrupt handler, but keep checking in probe that there are a interrupt define in DT. - Rework how to wait for LP-11 state, thanks Laurent for the great idea! - Remove unneeded delay in rcar_csi2_reset() - Remove check for duplicated lane id:s from DT parsing. Broken out to a separate patch adding this check directly to v4l2_of_parse_endpoint(). - Fixed rcar_csi2_start() to ask it's source subdevice for information about pixel rate and frame format. With this change having {set,get}_fmt operations became redundant, it was only used for figuring out this out so dropped them. - Tabulated frequency settings map. - Dropped V4L2_SUBDEV_FL_HAS_DEVNODE it should never have been set. - Switched from MEDIA_ENT_F_ATV_DECODER to MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER as entity function. I can't find a more suitable function, and what the hardware do is to fetch video from an external chip and passes it on to a another SoC internal IP it's sort of a formatter. - Break out DT documentation and code in two patches. Changes since v3: - Update DT binding documentation with
Re: [PATCH v6 6/9] i2c: smbus: use DMA safe buffers for emulated SMBus transactions
On Sat, 4 Nov 2017 21:20:06 +0100 Wolfram Sangwrote: > For all block commands, try to allocate a DMA safe buffer and mark it > accordingly. Only use the stack, if the buffers cannot be allocated. > > Signed-off-by: Wolfram Sang Hmm. Interesting balance here as this adds allocations to paths where the i2c master can't take advantage. Not ideal, but perhaps not worth the hassle of working around it? It's only for the block calls I guess so not that major an issue. Reviewed-by: Jonathan Cameron > --- > drivers/i2c/i2c-core-smbus.c | 45 > ++-- > 1 file changed, 39 insertions(+), 6 deletions(-) > > diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c > index 4bb9927afd0106..931c274fe26809 100644 > --- a/drivers/i2c/i2c-core-smbus.c > +++ b/drivers/i2c/i2c-core-smbus.c > @@ -18,6 +18,7 @@ > #include > #include > #include > +#include > > #define CREATE_TRACE_POINTS > #include > @@ -291,6 +292,22 @@ s32 i2c_smbus_write_i2c_block_data(const struct > i2c_client *client, u8 command, > } > EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); > > +static void i2c_smbus_try_get_dmabuf(struct i2c_msg *msg, u8 init_val) > +{ > + bool is_read = msg->flags & I2C_M_RD; > + unsigned char *dma_buf; > + > + dma_buf = kzalloc(I2C_SMBUS_BLOCK_MAX + (is_read ? 2 : 3), GFP_KERNEL); > + if (!dma_buf) > + return; > + > + msg->buf = dma_buf; > + msg->flags |= I2C_M_DMA_SAFE; > + > + if (init_val) > + msg->buf[0] = init_val; > + > +} > /* Simulate a SMBus command using the i2c protocol > No checking of parameters is done! */ > static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, > @@ -368,6 +385,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter > *adapter, u16 addr, > msg[1].flags |= I2C_M_RECV_LEN; > msg[1].len = 1; /* block length will be added by > the underlying bus driver */ > + i2c_smbus_try_get_dmabuf([1], 0); > } else { > msg[0].len = data->block[0] + 2; > if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { > @@ -376,8 +394,10 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter > *adapter, u16 addr, > data->block[0]); > return -EINVAL; > } > + > + i2c_smbus_try_get_dmabuf([0], command); > for (i = 1; i < msg[0].len; i++) > - msgbuf0[i] = data->block[i-1]; > + msg[0].buf[i] = data->block[i-1]; > } > break; > case I2C_SMBUS_BLOCK_PROC_CALL: > @@ -389,16 +409,21 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter > *adapter, u16 addr, > data->block[0]); > return -EINVAL; > } > + > msg[0].len = data->block[0] + 2; > + i2c_smbus_try_get_dmabuf([0], command); > for (i = 1; i < msg[0].len; i++) > - msgbuf0[i] = data->block[i-1]; > + msg[0].buf[i] = data->block[i-1]; > + > msg[1].flags |= I2C_M_RECV_LEN; > msg[1].len = 1; /* block length will be added by > the underlying bus driver */ > + i2c_smbus_try_get_dmabuf([1], 0); > break; > case I2C_SMBUS_I2C_BLOCK_DATA: > if (read_write == I2C_SMBUS_READ) { > msg[1].len = data->block[0]; > + i2c_smbus_try_get_dmabuf([1], 0); > } else { > msg[0].len = data->block[0] + 1; > if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) { > @@ -407,8 +432,10 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter > *adapter, u16 addr, > data->block[0]); > return -EINVAL; > } > + > + i2c_smbus_try_get_dmabuf([0], command); > for (i = 1; i <= data->block[0]; i++) > - msgbuf0[i] = data->block[i]; > + msg[0].buf[i] = data->block[i]; > } > break; > default: > @@ -456,14 +483,20 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter > *adapter, u16 addr, > break; > case I2C_SMBUS_I2C_BLOCK_DATA: > for (i = 0; i < data->block[0]; i++) > - data->block[i+1] = msgbuf1[i]; > + data->block[i+1] = msg[1].buf[i]; > break; > case I2C_SMBUS_BLOCK_DATA: >
Re: [PATCH v10 2/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver
Hej Sakari, On 2017-11-11 00:32:27 +0200, Sakari Ailus wrote: > Hej Niklas, > > Tack för uppdaterade lappar! Jag har några kommentar nedan... det ser bra > ut överallt. Tack för din feedback! > > On Fri, Nov 10, 2017 at 02:31:37PM +0100, Niklas Söderlund wrote: > > A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver > > supports the rcar-vin driver on 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> > --- > > drivers/media/platform/rcar-vin/Kconfig | 12 + > > drivers/media/platform/rcar-vin/Makefile| 1 + > > drivers/media/platform/rcar-vin/rcar-csi2.c | 934 > > > > 3 files changed, 947 insertions(+) > > create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c > > > > diff --git a/drivers/media/platform/rcar-vin/Kconfig > > b/drivers/media/platform/rcar-vin/Kconfig > > index af4c98b44d2e22cb..6875f30c1ae42631 100644 > > --- a/drivers/media/platform/rcar-vin/Kconfig > > +++ b/drivers/media/platform/rcar-vin/Kconfig > > @@ -1,3 +1,15 @@ > > +config VIDEO_RCAR_CSI2 > > + tristate "R-Car MIPI CSI-2 Receiver" > > + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF > > + depends on ARCH_RENESAS || COMPILE_TEST > > + select V4L2_FWNODE > > + ---help--- > > + Support for Renesas R-Car MIPI CSI-2 receiver. > > + Supports R-Car Gen3 SoCs. > > + > > + To compile this driver as a module, choose M here: the > > + module will be called rcar-csi2. > > + > > config VIDEO_RCAR_VIN > > tristate "R-Car Video Input (VIN) Driver" > > depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && > > MEDIA_CONTROLLER > > diff --git a/drivers/media/platform/rcar-vin/Makefile > > b/drivers/media/platform/rcar-vin/Makefile > > index 48c5632c21dc060b..5ab803d3e7c1aa57 100644 > > --- a/drivers/media/platform/rcar-vin/Makefile > > +++ b/drivers/media/platform/rcar-vin/Makefile > > @@ -1,3 +1,4 @@ > > rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o > > > > +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o > > obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o > > 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 ..27d09da191a09b39 > > --- /dev/null > > +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c > > @@ -0,0 +1,934 @@ > > +/* > > + * Driver for Renesas R-Car MIPI CSI-2 Receiver > > + * > > + * Copyright (C) 2017 Renesas Electronics Corp. > > + * > > + * This program is free software; you can redistribute it and/or modify it > > + * under the terms of the GNU General Public License as published by the > > + * Free Software Foundation; either version 2 of the License, or (at your > > + * option) any later version. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/* Register offsets and bits */ > > + > > +/* Control Timing Select */ > > +#define TREF_REG 0x00 > > +#define TREF_TREF BIT(0) > > + > > +/* Software Reset */ > > +#define SRST_REG 0x04 > > +#define SRST_SRST BIT(0) > > + > > +/* PHY Operation Control */ > > +#define PHYCNT_REG 0x08 > > +#define PHYCNT_SHUTDOWNZ BIT(17) > > +#define PHYCNT_RSTZBIT(16) > > +#define PHYCNT_ENABLECLK BIT(4) > > +#define PHYCNT_ENABLE_3BIT(3) > > +#define PHYCNT_ENABLE_2BIT(2) > > +#define PHYCNT_ENABLE_1BIT(1) > > +#define PHYCNT_ENABLE_0BIT(0) > > + > > +/* Checksum Control */ > > +#define CHKSUM_REG 0x0c > > +#define CHKSUM_ECC_EN BIT(1) > > +#define CHKSUM_CRC_EN BIT(0) > > + > > +/* > > + * Channel Data Type Select > > + * VCDT[0-15]: Channel 1 VCDT[16-31]: Channel 2 > > + * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4 > > + */ > > +#define VCDT_REG 0x10 > > +#define VCDT2_REG 0x14 > > +#define VCDT_VCDTN_EN BIT(15) > > +#define VCDT_SEL_VC(n) (((n) & 0x3) << 8) > > +#define VCDT_SEL_DTN_ONBIT(6) > > +#define VCDT_SEL_DT(n) (((n) & 0x3f) << 0) > > + > > +/* Frame Data Type Select */ > > +#define FRDT_REG 0x18 > > + > > +/* Field Detection Control */ > > +#define FLD_REG0x1c > > +#define FLD_FLD_NUM(n) (((n) & 0xff) << 16) > > +#define FLD_FLD_EN4BIT(3) > >
Re: [PATCH v6 5/9] i2c: add i2c_master_{send|recv}_dmasafe
On Sat, 4 Nov 2017 21:20:05 +0100 Wolfram Sangwrote: > Use the new helper to create variants of i2c_master_{send|recv} which > mark their buffers as DMA safe. > > Signed-off-by: Wolfram Sang Can't really argue with such a simple patch ;) Acked-by: Jonathan Cameron > --- > include/linux/i2c.h | 31 +++ > 1 file changed, 31 insertions(+) > > diff --git a/include/linux/i2c.h b/include/linux/i2c.h > index ef1a8791c1ae24..8c144e3cbfb261 100644 > --- a/include/linux/i2c.h > +++ b/include/linux/i2c.h > @@ -81,6 +81,22 @@ static inline int i2c_master_recv(const struct i2c_client > *client, > }; > > /** > + * i2c_master_recv_dmasafe - issue a single I2C message in master receive > mode > + *using a DMA safe buffer > + * @client: Handle to slave device > + * @buf: Where to store data read from slave, must be safe to use with DMA > + * @count: How many bytes to read, must be less than 64k since msg.len is u16 > + * > + * Returns negative errno, or else the number of bytes read. > + */ > +static inline int i2c_master_recv_dmasafe(const struct i2c_client *client, > + char *buf, int count) > +{ > + return i2c_transfer_buffer_flags(client, buf, count, > + I2C_M_RD | I2C_M_DMA_SAFE); > +}; > + > +/** > * i2c_master_send - issue a single I2C message in master transmit mode > * @client: Handle to slave device > * @buf: Data that will be written to the slave > @@ -93,6 +109,21 @@ static inline int i2c_master_send(const struct i2c_client > *client, > { > return i2c_transfer_buffer_flags(client, (char *)buf, count, 0); > }; > +/** > + * i2c_master_send_dmasafe - issue a single I2C message in master transmit > mode > + *using a DMA safe buffer > + * @client: Handle to slave device > + * @buf: Data that will be written to the slave, must be safe to use with DMA > + * @count: How many bytes to write, must be less than 64k since msg.len is > u16 > + * > + * Returns negative errno, or else the number of bytes written. > + */ > +static inline int i2c_master_send_dmasafe(const struct i2c_client *client, > + const char *buf, int count) > +{ > + return i2c_transfer_buffer_flags(client, (char *)buf, count, > + I2C_M_DMA_SAFE); > +}; > > /* Transfer num messages. > */
Re: [PATCH v6 4/9] i2c: refactor i2c_master_{send_recv}
On Sat, 4 Nov 2017 21:20:04 +0100 Wolfram Sangwrote: > Those two functions are very similar, the only differences are that one > needs the I2C_M_RD flag for its message while the other one needs the > buffer casted to drop the const. Introduce a generic helper which > allows to specify the flags (also needed later for DMA safe variants of > these calls) and let the casting be done in the inlining fuctions which > are now calling the new helper function. The casting away of the const is a bit nasty, but short of making this whole thing a macro, I can't see a better way. > > Signed-off-by: Wolfram Sang Reviewed-by: Jonathan Cameron > --- > drivers/i2c/i2c-core-base.c | 64 > + > include/linux/i2c.h | 34 +--- > 2 files changed, 48 insertions(+), 50 deletions(-) > > diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c > index de1850bd440659..206c47c85c98c5 100644 > --- a/drivers/i2c/i2c-core-base.c > +++ b/drivers/i2c/i2c-core-base.c > @@ -1972,63 +1972,35 @@ int i2c_transfer(struct i2c_adapter *adap, struct > i2c_msg *msgs, int num) > EXPORT_SYMBOL(i2c_transfer); > > /** > - * i2c_master_send - issue a single I2C message in master transmit mode > + * i2c_transfer_buffer_flags - issue a single I2C message transferring data > + * to/from a buffer > * @client: Handle to slave device > - * @buf: Data that will be written to the slave > - * @count: How many bytes to write, must be less than 64k since msg.len is > u16 > + * @buf: Where the data is stored > + * @count: How many bytes to transfer, must be less than 64k since msg.len > is u16 > + * @flags: The flags to be used for the message, e.g. I2C_M_RD for reads > * > - * Returns negative errno, or else the number of bytes written. > + * Returns negative errno, or else the number of bytes transferred. > */ > -int i2c_master_send(const struct i2c_client *client, const char *buf, int > count) > +int i2c_transfer_buffer_flags(const struct i2c_client *client, char *buf, > + int count, u16 flags) > { > int ret; > - struct i2c_adapter *adap = client->adapter; > - struct i2c_msg msg; > - > - msg.addr = client->addr; > - msg.flags = client->flags & I2C_M_TEN; > - msg.len = count; > - msg.buf = (char *)buf; > - > - ret = i2c_transfer(adap, , 1); > - > - /* > - * If everything went ok (i.e. 1 msg transmitted), return #bytes > - * transmitted, else error code. > - */ > - return (ret == 1) ? count : ret; > -} > -EXPORT_SYMBOL(i2c_master_send); > - > -/** > - * i2c_master_recv - issue a single I2C message in master receive mode > - * @client: Handle to slave device > - * @buf: Where to store data read from slave > - * @count: How many bytes to read, must be less than 64k since msg.len is u16 > - * > - * Returns negative errno, or else the number of bytes read. > - */ > -int i2c_master_recv(const struct i2c_client *client, char *buf, int count) > -{ > - struct i2c_adapter *adap = client->adapter; > - struct i2c_msg msg; > - int ret; > - > - msg.addr = client->addr; > - msg.flags = client->flags & I2C_M_TEN; > - msg.flags |= I2C_M_RD; > - msg.len = count; > - msg.buf = buf; > + struct i2c_msg msg = { > + .addr = client->addr, > + .flags = flags | (client->flags & I2C_M_TEN), > + .len = count, > + .buf = buf, > + }; > > - ret = i2c_transfer(adap, , 1); > + ret = i2c_transfer(client->adapter, , 1); > > /* > - * If everything went ok (i.e. 1 msg received), return #bytes received, > - * else error code. > + * If everything went ok (i.e. 1 msg transferred), return #bytes > + * transferred, else error code. >*/ > return (ret == 1) ? count : ret; > } > -EXPORT_SYMBOL(i2c_master_recv); > +EXPORT_SYMBOL(i2c_transfer_buffer_flags); > > /* > * the i2c address scanning function > diff --git a/include/linux/i2c.h b/include/linux/i2c.h > index a0b57de91e21d3..ef1a8791c1ae24 100644 > --- a/include/linux/i2c.h > +++ b/include/linux/i2c.h > @@ -63,10 +63,36 @@ struct property_entry; > * transmit an arbitrary number of messages without interruption. > * @count must be be less than 64k since msg.len is u16. > */ > -extern int i2c_master_send(const struct i2c_client *client, const char *buf, > -int count); > -extern int i2c_master_recv(const struct i2c_client *client, char *buf, > -int count); > +extern int i2c_transfer_buffer_flags(const struct i2c_client *client, > + char *buf, int count, u16 flags); > + > +/** > + * i2c_master_recv - issue a single I2C message in master receive mode > + * @client:
Re: [PATCH v10 1/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation
Hej Sakari, Tack för din feedback. On 2017-11-11 00:11:13 +0200, Sakari Ailus wrote: > Hejssan, > > On Fri, Nov 10, 2017 at 02:31:36PM +0100, Niklas Söderlund wrote: > > Documentation for Renesas R-Car MIPI CSI-2 receiver. The CSI-2 receivers > > are located between the video sources (CSI-2 transmitters) and the video > > grabbers (VIN) on Gen3 of Renesas R-Car SoC. > > > > Each CSI-2 device is connected to more then one VIN device which > > simultaneously can receive video from the same CSI-2 device. Each VIN > > device can also be connected to more then one CSI-2 device. The routing > > of which link are used are controlled by the VIN devices. There are only > > a few possible routes which are set by hardware limitations, which are > > different for each SoC in the Gen3 family. > > > > To work with the limitations of routing possibilities it is necessary > > for the DT bindings to describe which VIN device is connected to which > > CSI-2 device. This is why port 1 needs to to assign reg numbers for each > > VIN device that be connected to it. To setup and to know which links are > > valid for each SoC is the responsibility of the VIN driver since the > > register to configure it belongs to the VIN hardware. > > > > Signed-off-by: Niklas Söderlund> > --- > > .../devicetree/bindings/media/rcar-csi2.txt| 104 > > + > > MAINTAINERS| 1 + > > 2 files changed, 105 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/media/rcar-csi2.txt > > > > diff --git a/Documentation/devicetree/bindings/media/rcar-csi2.txt > > b/Documentation/devicetree/bindings/media/rcar-csi2.txt > > new file mode 100644 > > index ..24705d8997b14a10 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/media/rcar-csi2.txt > > How about using vendor prefix and comma for the file name? Most others in > the directory do so, including other Renesas bindings. To be clear you are suggesting a rename to 'renesas,rcar-csi2.txt'? I'm not oppose to that but chose this name as this driver is closely tied to the rcar-vin driver which is documented in: Documentation/devicetree/bindings/media/rcar_vin.txt You also had comments on patch 2/2 so I will resend this series once more addressing them so will rename this as you suggests. > > > @@ -0,0 +1,104 @@ > > +Renesas R-Car MIPI CSI-2 > > + > > + > > +The rcar-csi2 device provides MIPI CSI-2 capabilities for the Renesas R-Car > > +family of devices. It is to be used in conjunction with the R-Car VIN > > module, > > +which provides the video capture capabilities. > > + > > +Mandatory properties > > + > > + - compatible: Must be one or more of the following > > + - "renesas,r8a7795-csi2" for the R8A7795 device. > > + - "renesas,r8a7796-csi2" for the R8A7796 device. > > + > > + - reg: the register base and size for the device registers > > + - interrupts: the interrupt for the device > > + - clocks: Reference to the parent clock > > + > > +The device node shall contain two 'port' child nodes according to the > > +bindings defined in Documentation/devicetree/bindings/media/ > > +video-interfaces.txt. Port 0 shall connect the node that is the video > > +source for to the CSI-2. Port 1 shall connect all the R-Car VIN > > +modules, which can make use of the CSI-2 module. > > + > > +- Port 0 - Video source (Mandatory) > > + - Endpoint 0 - sub-node describing the endpoint that is the video source > > + > > +- Port 1 - VIN instances (Mandatory for all VIN present in the SoC) > > + - Endpoint 0 - sub-node describing the endpoint that is VIN0 > > + - Endpoint 1 - sub-node describing the endpoint that is VIN1 > > + - Endpoint 2 - sub-node describing the endpoint that is VIN2 > > + - Endpoint 3 - sub-node describing the endpoint that is VIN3 > > + - Endpoint 4 - sub-node describing the endpoint that is VIN4 > > + - Endpoint 5 - sub-node describing the endpoint that is VIN5 > > + - Endpoint 6 - sub-node describing the endpoint that is VIN6 > > + - Endpoint 7 - sub-node describing the endpoint that is VIN7 > > + > > +Example: > > + > > + csi20: csi2@fea8 { > > + compatible = "renesas,r8a7796-csi2", "renesas,rcar-gen3-csi2"; > > + reg = <0 0xfea8 0 0x1>; > > + interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; > > + clocks = < CPG_MOD 714>; > > + power-domains = < R8A7796_PD_ALWAYS_ON>; > > + resets = < 714>; > > + > > + ports { > > + #address-cells = <1>; > > + #size-cells = <0>; > > + > > + port@0 { > > + #address-cells = <1>; > > + #size-cells = <0>; > > + > > + reg = <0>; > > + > > + csi20_in: endpoint@0 { > > +
Re: [PATCH v10 2/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver
Hej Niklas, Tack för uppdaterade lappar! Jag har några kommentar nedan... det ser bra ut överallt. On Fri, Nov 10, 2017 at 02:31:37PM +0100, Niklas Söderlund wrote: > A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver > supports the rcar-vin driver on 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> --- > drivers/media/platform/rcar-vin/Kconfig | 12 + > drivers/media/platform/rcar-vin/Makefile| 1 + > drivers/media/platform/rcar-vin/rcar-csi2.c | 934 > > 3 files changed, 947 insertions(+) > create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c > > diff --git a/drivers/media/platform/rcar-vin/Kconfig > b/drivers/media/platform/rcar-vin/Kconfig > index af4c98b44d2e22cb..6875f30c1ae42631 100644 > --- a/drivers/media/platform/rcar-vin/Kconfig > +++ b/drivers/media/platform/rcar-vin/Kconfig > @@ -1,3 +1,15 @@ > +config VIDEO_RCAR_CSI2 > + tristate "R-Car MIPI CSI-2 Receiver" > + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF > + depends on ARCH_RENESAS || COMPILE_TEST > + select V4L2_FWNODE > + ---help--- > + Support for Renesas R-Car MIPI CSI-2 receiver. > + Supports R-Car Gen3 SoCs. > + > + To compile this driver as a module, choose M here: the > + module will be called rcar-csi2. > + > config VIDEO_RCAR_VIN > tristate "R-Car Video Input (VIN) Driver" > depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && > MEDIA_CONTROLLER > diff --git a/drivers/media/platform/rcar-vin/Makefile > b/drivers/media/platform/rcar-vin/Makefile > index 48c5632c21dc060b..5ab803d3e7c1aa57 100644 > --- a/drivers/media/platform/rcar-vin/Makefile > +++ b/drivers/media/platform/rcar-vin/Makefile > @@ -1,3 +1,4 @@ > rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o > > +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o > obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o > 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 ..27d09da191a09b39 > --- /dev/null > +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c > @@ -0,0 +1,934 @@ > +/* > + * Driver for Renesas R-Car MIPI CSI-2 Receiver > + * > + * Copyright (C) 2017 Renesas Electronics Corp. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License as published by the > + * Free Software Foundation; either version 2 of the License, or (at your > + * option) any later version. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > + > +/* Register offsets and bits */ > + > +/* Control Timing Select */ > +#define TREF_REG 0x00 > +#define TREF_TREFBIT(0) > + > +/* Software Reset */ > +#define SRST_REG 0x04 > +#define SRST_SRSTBIT(0) > + > +/* PHY Operation Control */ > +#define PHYCNT_REG 0x08 > +#define PHYCNT_SHUTDOWNZ BIT(17) > +#define PHYCNT_RSTZ BIT(16) > +#define PHYCNT_ENABLECLK BIT(4) > +#define PHYCNT_ENABLE_3 BIT(3) > +#define PHYCNT_ENABLE_2 BIT(2) > +#define PHYCNT_ENABLE_1 BIT(1) > +#define PHYCNT_ENABLE_0 BIT(0) > + > +/* Checksum Control */ > +#define CHKSUM_REG 0x0c > +#define CHKSUM_ECC_ENBIT(1) > +#define CHKSUM_CRC_ENBIT(0) > + > +/* > + * Channel Data Type Select > + * VCDT[0-15]: Channel 1 VCDT[16-31]: Channel 2 > + * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4 > + */ > +#define VCDT_REG 0x10 > +#define VCDT2_REG0x14 > +#define VCDT_VCDTN_ENBIT(15) > +#define VCDT_SEL_VC(n) (((n) & 0x3) << 8) > +#define VCDT_SEL_DTN_ON BIT(6) > +#define VCDT_SEL_DT(n) (((n) & 0x3f) << 0) > + > +/* Frame Data Type Select */ > +#define FRDT_REG 0x18 > + > +/* Field Detection Control */ > +#define FLD_REG 0x1c > +#define FLD_FLD_NUM(n) (((n) & 0xff) << 16) > +#define FLD_FLD_EN4 BIT(3) > +#define FLD_FLD_EN3 BIT(2) > +#define FLD_FLD_EN2 BIT(1) > +#define FLD_FLD_EN BIT(0) > + > +/* Automatic Standby Control */ > +#define ASTBY_REG0x20 > + > +/* Long Data Type Setting 0 */ > +#define LNGDT0_REG
Re: [PATCH v10 1/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation
Hejssan, On Fri, Nov 10, 2017 at 02:31:36PM +0100, Niklas Söderlund wrote: > Documentation for Renesas R-Car MIPI CSI-2 receiver. The CSI-2 receivers > are located between the video sources (CSI-2 transmitters) and the video > grabbers (VIN) on Gen3 of Renesas R-Car SoC. > > Each CSI-2 device is connected to more then one VIN device which > simultaneously can receive video from the same CSI-2 device. Each VIN > device can also be connected to more then one CSI-2 device. The routing > of which link are used are controlled by the VIN devices. There are only > a few possible routes which are set by hardware limitations, which are > different for each SoC in the Gen3 family. > > To work with the limitations of routing possibilities it is necessary > for the DT bindings to describe which VIN device is connected to which > CSI-2 device. This is why port 1 needs to to assign reg numbers for each > VIN device that be connected to it. To setup and to know which links are > valid for each SoC is the responsibility of the VIN driver since the > register to configure it belongs to the VIN hardware. > > Signed-off-by: Niklas Söderlund> --- > .../devicetree/bindings/media/rcar-csi2.txt| 104 > + > MAINTAINERS| 1 + > 2 files changed, 105 insertions(+) > create mode 100644 Documentation/devicetree/bindings/media/rcar-csi2.txt > > diff --git a/Documentation/devicetree/bindings/media/rcar-csi2.txt > b/Documentation/devicetree/bindings/media/rcar-csi2.txt > new file mode 100644 > index ..24705d8997b14a10 > --- /dev/null > +++ b/Documentation/devicetree/bindings/media/rcar-csi2.txt How about using vendor prefix and comma for the file name? Most others in the directory do so, including other Renesas bindings. > @@ -0,0 +1,104 @@ > +Renesas R-Car MIPI CSI-2 > + > + > +The rcar-csi2 device provides MIPI CSI-2 capabilities for the Renesas R-Car > +family of devices. It is to be used in conjunction with the R-Car VIN module, > +which provides the video capture capabilities. > + > +Mandatory properties > + > + - compatible: Must be one or more of the following > + - "renesas,r8a7795-csi2" for the R8A7795 device. > + - "renesas,r8a7796-csi2" for the R8A7796 device. > + > + - reg: the register base and size for the device registers > + - interrupts: the interrupt for the device > + - clocks: Reference to the parent clock > + > +The device node shall contain two 'port' child nodes according to the > +bindings defined in Documentation/devicetree/bindings/media/ > +video-interfaces.txt. Port 0 shall connect the node that is the video > +source for to the CSI-2. Port 1 shall connect all the R-Car VIN > +modules, which can make use of the CSI-2 module. > + > +- Port 0 - Video source (Mandatory) > + - Endpoint 0 - sub-node describing the endpoint that is the video source > + > +- Port 1 - VIN instances (Mandatory for all VIN present in the SoC) > + - Endpoint 0 - sub-node describing the endpoint that is VIN0 > + - Endpoint 1 - sub-node describing the endpoint that is VIN1 > + - Endpoint 2 - sub-node describing the endpoint that is VIN2 > + - Endpoint 3 - sub-node describing the endpoint that is VIN3 > + - Endpoint 4 - sub-node describing the endpoint that is VIN4 > + - Endpoint 5 - sub-node describing the endpoint that is VIN5 > + - Endpoint 6 - sub-node describing the endpoint that is VIN6 > + - Endpoint 7 - sub-node describing the endpoint that is VIN7 > + > +Example: > + > + csi20: csi2@fea8 { > + compatible = "renesas,r8a7796-csi2", "renesas,rcar-gen3-csi2"; > + reg = <0 0xfea8 0 0x1>; > + interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; > + clocks = < CPG_MOD 714>; > + power-domains = < R8A7796_PD_ALWAYS_ON>; > + resets = < 714>; > + > + ports { > + #address-cells = <1>; > + #size-cells = <0>; > + > + port@0 { > + #address-cells = <1>; > + #size-cells = <0>; > + > + reg = <0>; > + > + csi20_in: endpoint@0 { > + clock-lanes = <0>; > + data-lanes = <1>; > + remote-endpoint = <_txb>; > + }; > + }; > + > + port@1 { > + #address-cells = <1>; > + #size-cells = <0>; > + > + reg = <1>; > + > + csi20vin0: endpoint@0 { > + reg = <0>; > + remote-endpoint = <>; > + }; > +
[PATCH V2 5/5] PCI: rcar: Add the suspend/resume for pcie-rcar driver
From: Kazufumi IkedaThis adds the suspend/resume supports for pcie-rcar. The resume handler reprograms the hardware based on the software state kept in specific device structures. Also it doesn't need to save any registers. Signed-off-by: Kazufumi Ikeda Signed-off-by: Gaku Inami Signed-off-by: Marek Vasut Cc: Geert Uytterhoeven Cc: Phil Edworthy Cc: Simon Horman Cc: Wolfram Sang Cc: linux-renesas-soc@vger.kernel.org --- V2: - Change return type of rcar_pcie_hw_enable() to void - Drop default: case in switch statement in rcar_pcie_hw_enable() - Sort variables in rcar_pcie_resume() --- drivers/pci/host/pcie-rcar.c | 82 +++- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 068bf9067ec1..f65ad226335d 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c @@ -471,6 +471,32 @@ static void rcar_pcie_force_speedup(struct rcar_pcie *pcie) (macsr & LINK_SPEED) == LINK_SPEED_5_0GTS ? "5" : "2.5"); } +static void rcar_pcie_hw_enable(struct rcar_pcie *pci) +{ + struct resource_entry *win; + LIST_HEAD(res); + int i = 0; + + /* Try setting 5 GT/s link speed */ + rcar_pcie_force_speedup(pci); + + /* Setup PCI resources */ + resource_list_for_each_entry(win, >resources) { + struct resource *res = win->res; + + if (!res->flags) + continue; + + switch (resource_type(res)) { + case IORESOURCE_IO: + case IORESOURCE_MEM: + rcar_pcie_setup_window(i, pci, res); + i++; + break; + } + } +} + static int rcar_pcie_enable(struct rcar_pcie *pcie) { struct device *dev = pcie->dev; @@ -869,11 +895,25 @@ static const struct irq_domain_ops msi_domain_ops = { .map = rcar_msi_map, }; +static void rcar_pcie_hw_enable_msi(struct rcar_pcie *pcie) +{ + struct rcar_msi *msi = >msi; + unsigned long base; + + /* setup MSI data target */ + base = virt_to_phys((void *)msi->pages); + + rcar_pci_write_reg(pcie, base | MSIFE, PCIEMSIALR); + rcar_pci_write_reg(pcie, 0, PCIEMSIAUR); + + /* enable all MSI interrupts */ + rcar_pci_write_reg(pcie, 0x, PCIEMSIIER); +} + static int rcar_pcie_enable_msi(struct rcar_pcie *pcie) { struct device *dev = pcie->dev; struct rcar_msi *msi = >msi; - unsigned long base; int err, i; mutex_init(>lock); @@ -912,13 +952,7 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie) /* setup MSI data target */ msi->pages = __get_free_pages(GFP_KERNEL, 0); - base = virt_to_phys((void *)msi->pages); - - rcar_pci_write_reg(pcie, base | MSIFE, PCIEMSIALR); - rcar_pci_write_reg(pcie, 0, PCIEMSIAUR); - - /* enable all MSI interrupts */ - rcar_pci_write_reg(pcie, 0x, PCIEMSIIER); + rcar_pcie_hw_enable_msi(pcie); return 0; @@ -1193,6 +1227,37 @@ static int rcar_pcie_probe(struct platform_device *pdev) return err; } +static int rcar_pcie_resume(struct device *dev) +{ + struct rcar_pcie *pcie = dev_get_drvdata(dev); + int (*hw_init_fn)(struct rcar_pcie *); + unsigned int data; + int err; + + err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); + if (err) + return 0; + + /* Failure to get a link might just be that no cards are inserted */ + hw_init_fn = of_device_get_match_data(dev); + err = hw_init_fn(pcie); + if (err) { + dev_info(dev, "PCIe link down\n"); + return 0; + } + + data = rcar_pci_read_reg(pcie, MACSR); + dev_info(dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f); + + /* Enable MSI */ + if (IS_ENABLED(CONFIG_PCI_MSI)) + rcar_pcie_hw_enable_msi(pcie); + + rcar_pcie_hw_enable(pcie); + + return 0; +} + static int rcar_pcie_resume_noirq(struct device *dev) { struct rcar_pcie *pcie = dev_get_drvdata(dev); @@ -1207,6 +1272,7 @@ static int rcar_pcie_resume_noirq(struct device *dev) } static const struct dev_pm_ops rcar_pcie_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, rcar_pcie_resume) .resume_noirq = rcar_pcie_resume_noirq, }; -- 2.11.0
[PATCH V2 0/5] PCI: rcar: Add suspend/resume support
This patchset adds support for suspend/resume on the Renesas RCar PCIe controller. First two patches clean the driver up a little, while the remaining three add the required suspend/resume functionality. Kazufumi Ikeda (2): PCI: rcar: Add the initialization of PCIe link in resume_noirq PCI: rcar: Add the suspend/resume for pcie-rcar driver Marek Vasut (2): PCI: rcar: Poll more often in rcar_pcie_wait_for_dl() PCI: rcar: Clean up the macros Phil Edworthy (1): PCI: rcar: Support runtime PM, link state L1 handling drivers/pci/host/pcie-rcar.c | 182 ++- 1 file changed, 146 insertions(+), 36 deletions(-) Cc: Geert UytterhoevenCc: Phil Edworthy Cc: Simon Horman Cc: Wolfram Sang Cc: linux-renesas-soc@vger.kernel.org -- 2.11.0
[PATCH V2 3/5] PCI: rcar: Add the initialization of PCIe link in resume_noirq
From: Kazufumi IkedaReestablish the PCIe link very early in the resume process in case it went down to prevent PCI accesses from hanging the bus. Such accesses can happen early in the PCI resume process, in the resume_noirq, thus the link must be reestablished in the resume_noirq callback of the driver. Signed-off-by: Kazufumi Ikeda Signed-off-by: Gaku Inami Signed-off-by: Marek Vasut Cc: Geert Uytterhoeven Cc: Phil Edworthy Cc: Simon Horman Cc: Wolfram Sang Cc: linux-renesas-soc@vger.kernel.org --- V2: - Use BIT() macro for (1 << n) - Since polling in rcar_pcie_wait_for_dl() uses udelay(), do not add extra changes to this function anymore - Make resume_noirq return early and clean up parenthesis therein --- drivers/pci/host/pcie-rcar.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 811e8194ef74..ab61829db389 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c @@ -43,6 +43,7 @@ /* Transfer control */ #define PCIETCTLR 0x02000 +#define DL_DOWN BIT(3) #define CFINIT1 #define PCIETSTR 0x02004 #define DATA_LINK_ACTIVE 1 @@ -1107,6 +1108,7 @@ static int rcar_pcie_probe(struct platform_device *pdev) pcie = pci_host_bridge_priv(bridge); pcie->dev = dev; + platform_set_drvdata(pdev, pcie); INIT_LIST_HEAD(>resources); @@ -1167,10 +1169,28 @@ static int rcar_pcie_probe(struct platform_device *pdev) return err; } +static int rcar_pcie_resume_noirq(struct device *dev) +{ + struct rcar_pcie *pcie = dev_get_drvdata(dev); + + if (rcar_pci_read_reg(pcie, PMSR) && + !(rcar_pci_read_reg(pcie, PCIETCTLR) & DL_DOWN)) + return 0; + + /* Re-establish the PCIe link */ + rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); + return rcar_pcie_wait_for_dl(pcie); +} + +static const struct dev_pm_ops rcar_pcie_pm_ops = { + .resume_noirq = rcar_pcie_resume_noirq, +}; + static struct platform_driver rcar_pcie_driver = { .driver = { .name = "rcar-pcie", .of_match_table = rcar_pcie_of_match, + .pm = _pcie_pm_ops, .suppress_bind_attrs = true, }, .probe = rcar_pcie_probe, -- 2.11.0
[PATCH V2 2/5] PCI: rcar: Clean up the macros
Just clean up the macros in the RCar PCI driver, no functional change. Signed-off-by: Marek VasutCc: Geert Uytterhoeven Cc: Phil Edworthy Cc: Simon Horman Cc: Wolfram Sang Cc: linux-renesas-soc@vger.kernel.org --- V2: New patch --- drivers/pci/host/pcie-rcar.c | 52 ++-- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 351e1276b90a..811e8194ef74 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c @@ -33,9 +33,9 @@ #define PCIECAR0x10 #define PCIECCTLR 0x18 -#define CONFIG_SEND_ENABLE(1 << 31) +#define CONFIG_SEND_ENABLEBIT(31) #define TYPE0 (0 << 8) -#define TYPE1 (1 << 8) +#define TYPE1 BIT(8) #define PCIECDR0x20 #define PCIEMSR0x28 #define PCIEINTXR 0x000400 @@ -47,7 +47,7 @@ #define PCIETSTR 0x02004 #define DATA_LINK_ACTIVE 1 #define PCIEERRFR 0x02020 -#define UNSUPPORTED_REQUEST (1 << 4) +#define UNSUPPORTED_REQUEST BIT(4) #define PCIEMSIFR 0x02044 #define PCIEMSIALR 0x02048 #define MSIFE 1 @@ -60,17 +60,17 @@ /* local address reg & mask */ #define PCIELAR(x) (0x02200 + ((x) * 0x20)) #define PCIELAMR(x)(0x02208 + ((x) * 0x20)) -#define LAM_PREFETCH (1 << 3) -#define LAM_64BIT (1 << 2) -#define LAR_ENABLE(1 << 1) +#define LAM_PREFETCH BIT(3) +#define LAM_64BIT BIT(2) +#define LAR_ENABLEBIT(1) /* PCIe address reg & mask */ #define PCIEPALR(x)(0x03400 + ((x) * 0x20)) #define PCIEPAUR(x)(0x03404 + ((x) * 0x20)) #define PCIEPAMR(x)(0x03408 + ((x) * 0x20)) #define PCIEPTCTLR(x) (0x0340c + ((x) * 0x20)) -#define PAR_ENABLE(1 << 31) -#define IO_SPACE (1 << 8) +#define PAR_ENABLEBIT(31) +#define IO_SPACE BIT(8) /* Configuration */ #define PCICONF(x) (0x01 + ((x) * 0x4)) @@ -82,23 +82,23 @@ #define IDSETR10x011004 #define TLCTLR 0x011048 #define MACSR 0x011054 -#define SPCHGFIN (1 << 4) -#define SPCHGFAIL (1 << 6) -#define SPCHGSUC (1 << 7) +#define SPCHGFIN BIT(4) +#define SPCHGFAIL BIT(6) +#define SPCHGSUC BIT(7) #define LINK_SPEED(0xf << 16) #define LINK_SPEED_2_5GTS (1 << 16) #define LINK_SPEED_5_0GTS (2 << 16) #define MACCTLR0x011058 -#define SPEED_CHANGE (1 << 24) -#define SCRAMBLE_DISABLE (1 << 27) +#define SPEED_CHANGE BIT(24) +#define SCRAMBLE_DISABLE BIT(27) #define MACS2R 0x011078 #define MACCGSPSETR0x011084 -#define SPCNGRSN (1 << 31) +#define SPCNGRSN BIT(31) /* R-Car H1 PHY */ #define H1_PCIEPHYADRR 0x04000c -#define WRITE_CMD (1 << 16) -#define PHY_ACK (1 << 24) +#define WRITE_CMD BIT(16) +#define PHY_ACK BIT(24) #define RATE_POS 12 #define LANE_POS 8 #define ADR_POS 0 @@ -110,19 +110,19 @@ #define GEN2_PCIEPHYDATA 0x784 #define GEN2_PCIEPHYCTRL 0x78c -#define INT_PCI_MSI_NR 32 +#define INT_PCI_MSI_NR 32 -#define RCONF(x) (PCICONF(0)+(x)) -#define RPMCAP(x) (PMCAP(0)+(x)) -#define REXPCAP(x) (EXPCAP(0)+(x)) -#define RVCCAP(x) (VCCAP(0)+(x)) +#define RCONF(x) (PCICONF(0) + (x)) +#define RPMCAP(x) (PMCAP(0) + (x)) +#define REXPCAP(x) (EXPCAP(0) + (x)) +#define RVCCAP(x) (VCCAP(0) + (x)) -#define PCIE_CONF_BUS(b) (((b) & 0xff) << 24) -#define PCIE_CONF_DEV(d) (((d) & 0x1f) << 19) -#define PCIE_CONF_FUNC(f) (((f) & 0x7) << 16) +#define PCIE_CONF_BUS(b) (((b) & 0xff) << 24) +#define PCIE_CONF_DEV(d) (((d) & 0x1f) << 19) +#define PCIE_CONF_FUNC(f) (((f) & 0x7) << 16) -#define RCAR_PCI_MAX_RESOURCES 4 -#define MAX_NR_INBOUND_MAPS 6 +#define RCAR_PCI_MAX_RESOURCES 4 +#define MAX_NR_INBOUND_MAPS6 struct rcar_msi { DECLARE_BITMAP(used, INT_PCI_MSI_NR); -- 2.11.0
[PATCH V2 4/5] PCI: rcar: Support runtime PM, link state L1 handling
From: Phil EdworthyMost PCIe host controllers support L0s and L1 power states via ASPM. The R-Car hardware only supports L0s, so when the system suspends and resumes we have to manually handle L1. When the system suspends, cards can put themselves into L1 and send a PM_ENTER_L1 DLLP to the host controller. At this point, we can no longer access the card's config registers. The R-Car host controller will handle taking cards out of L1 as long as the host controller has also been transitioned to L1 link state. Ideally, we would detect the PM_ENTER_L1 DLLP using an interrupt and transition the host to L1 immediately. However, this patch just ensures that we can talk to cards after they have gone into L1. When attempting a config access, it checks to see if the card has gone into L1, and if so, does the same for the host controller. This is based on a patch by Hien Dang Signed-off-by: Phil Edworthy Signed-off-by: Marek Vasut Cc: Geert Uytterhoeven Cc: Phil Edworthy Cc: Simon Horman Cc: Wolfram Sang Cc: linux-renesas-soc@vger.kernel.org --- V2: - Drop extra parenthesis - Use GENMASK() - Fix comment "The HW will handle coming of of L1.", s/of of/out of/ --- drivers/pci/host/pcie-rcar.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index ab61829db389..068bf9067ec1 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c @@ -92,6 +92,13 @@ #define MACCTLR0x011058 #define SPEED_CHANGE BIT(24) #define SCRAMBLE_DISABLE BIT(27) +#define PMSR 0x01105c +#define L1FAEGBIT(31) +#define PM_ENTER_L1RX BIT(23) +#define PMSTATE GENMASK(18, 16) +#define PMSTATE_L1GENMASK(17, 16) +#define PMCTLR 0x011060 +#define L1_INIT BIT(31) #define MACS2R 0x011078 #define MACCGSPSETR0x011084 #define SPCNGRSN BIT(31) @@ -191,6 +198,7 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie, unsigned int devfn, int where, u32 *data) { int dev, func, reg, index; + u32 val; dev = PCI_SLOT(devfn); func = PCI_FUNC(devfn); @@ -232,6 +240,22 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie, if (pcie->root_bus_nr < 0) return PCIBIOS_DEVICE_NOT_FOUND; + /* +* If we are not in L1 link state and we have received PM_ENTER_L1 DLLP, +* transition to L1 link state. The HW will handle coming out of L1. +*/ + val = rcar_pci_read_reg(pcie, PMSR); + if (val & PM_ENTER_L1RX && (val & PMSTATE) != PMSTATE_L1) { + rcar_pci_write_reg(pcie, L1_INIT, PMCTLR); + + /* Wait until we are in L1 */ + while (!(val & L1FAEG)) + val = rcar_pci_read_reg(pcie, PMSR); + + /* Clear flags indicating link has transitioned to L1 */ + rcar_pci_write_reg(pcie, L1FAEG | PM_ENTER_L1RX, PMSR); + } + /* Clear errors */ rcar_pci_write_reg(pcie, rcar_pci_read_reg(pcie, PCIEERRFR), PCIEERRFR); -- 2.11.0
[PATCH V2 1/5] PCI: rcar: Poll more often in rcar_pcie_wait_for_dl()
The data link active signal usually takes ~20 uSec to be asserted, poll the bit more often to avoid useless delays in this function. Signed-off-by: Marek VasutCc: Geert Uytterhoeven Cc: Phil Edworthy Cc: Simon Horman Cc: Wolfram Sang Cc: linux-renesas-soc@vger.kernel.org --- V2: New patch --- drivers/pci/host/pcie-rcar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index e00f865952d5..351e1276b90a 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c @@ -531,13 +531,13 @@ static void phy_write_reg(struct rcar_pcie *pcie, static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie) { - unsigned int timeout = 10; + unsigned int timeout = 1; while (timeout--) { if ((rcar_pci_read_reg(pcie, PCIETSTR) & DATA_LINK_ACTIVE)) return 0; - msleep(5); + udelay(5); } return -ETIMEDOUT; -- 2.11.0
Re: [PATCH V2] PCI: rcar: Use runtime PM to control controller clock
On 11/08/2017 11:08 AM, Geert Uytterhoeven wrote: > Hi Marek, Hi Geert, > On Wed, Nov 8, 2017 at 10:58 AM, Marek Vasutwrote: >> From: Dien Pham >> >> The controller clock can be switched off during suspend/resume, >> let runtime PM take care of that. >> >> Signed-off-by: Dien Pham >> Signed-off-by: Hien Dang >> Signed-off-by: Marek Vasut > >> --- a/drivers/pci/host/pcie-rcar.c >> +++ b/drivers/pci/host/pcie-rcar.c >> @@ -1125,6 +1112,13 @@ static int rcar_pcie_probe(struct platform_device >> *pdev) >> >> rcar_pcie_parse_request_of_pci_ranges(pcie); >> >> + pm_runtime_enable(pcie->dev); >> + err = pm_runtime_get_sync(pcie->dev); >> + if (err < 0) { >> + dev_err(pcie->dev, "pm_runtime_get_sync failed\n"); >> + goto err_pm_disable; >> + } >> + >> err = rcar_pcie_get_resources(pcie); >> if (err < 0) { >> dev_err(dev, "failed to request resources: %d\n", err); > > (out of context) > goto err_free_bridge; > > But that should do pm_runtime_put(), too. > >> @@ -1135,13 +1129,6 @@ static int rcar_pcie_probe(struct platform_device >> *pdev) >> if (err) >> goto err_free_bridge; >> >> - pm_runtime_enable(dev); >> - err = pm_runtime_get_sync(dev); >> - if (err < 0) { >> - dev_err(dev, "pm_runtime_get_sync failed\n"); >> - goto err_pm_disable; >> - } >> - >> /* Failure to get a link might just be that no cards are inserted */ >> hw_init_fn = of_device_get_match_data(dev); >> err = hw_init_fn(pcie); >> @@ -1173,13 +1160,13 @@ static int rcar_pcie_probe(struct platform_device >> *pdev) >> err_pm_put: >> pm_runtime_put(dev); > > "err_pm_put" should be moved, too. ACK. I combed through the probe function one more time and I hope I'll have it right in V3. >> -err_pm_disable: >> - pm_runtime_disable(dev); >> - >> err_free_bridge: >> pci_free_host_bridge(bridge); >> pci_free_resource_list(>resources); ^ IMO this should happen after pm_runtime_disable too , just to be consistent. >> +err_pm_disable: >> + pm_runtime_disable(dev); >> + >> return err; >> } [...] -- Best regards, Marek Vasut
Re: [PATCH 3/3] PCI: rcar: Add the suspend/resume for pcie-rcar driver
On 11/10/2017 10:09 AM, Simon Horman wrote: > On Wed, Nov 08, 2017 at 10:28:06AM +0100, Marek Vasut wrote: >> From: Kazufumi Ikeda>> >> This adds the suspend/resume supports for pcie-rcar. The resume handler >> reprogram the hardware based on the software state kept in specific >> device structures. Also it doesn't need to save any registers. >> >> Signed-off-by: Kazufumi Ikeda >> Signed-off-by: Gaku Inami >> Signed-off-by: Marek Vasut >> Cc: Geert Uytterhoeven >> Cc: Simon Horman >> Cc: Wolfram Sang >> Cc: linux-renesas-soc@vger.kernel.org >> --- >> drivers/pci/host/pcie-rcar.c | 86 >> +++- >> 1 file changed, 78 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c >> index 2b28292de93a..7a9e30185c79 100644 >> --- a/drivers/pci/host/pcie-rcar.c >> +++ b/drivers/pci/host/pcie-rcar.c >> @@ -471,6 +471,36 @@ static void rcar_pcie_force_speedup(struct rcar_pcie >> *pcie) >> (macsr & LINK_SPEED) == LINK_SPEED_5_0GTS ? "5" : "2.5"); >> } >> >> +static int rcar_pcie_hw_enable(struct rcar_pcie *pcie) > > This function always returns 0 and the value is not checked by the caller. > Can we change the return type to void? Yes, done >> +{ >> +struct resource_entry *win; >> +LIST_HEAD(res); >> +int i = 0; >> + >> +/* Try setting 5 GT/s link speed */ > > What if it fails? If it fails, we're back at 2.5 GT/s . The rcar_pcie_force_speedup() first checks if the PCIe IP can do 5 GT/s at all. Only if so, tries to initiate transition to 5 GT/s operation , checks whether that succeeded and if it failed, falls back to 2.5 GT/s . >> +rcar_pcie_force_speedup(pcie); >> + >> +/* Setup PCI resources */ >> +resource_list_for_each_entry(win, >resources) { >> +struct resource *res = win->res; >> + >> +if (!res->flags) >> +continue; >> + >> +switch (resource_type(res)) { >> +case IORESOURCE_IO: >> +case IORESOURCE_MEM: >> +rcar_pcie_setup_window(i, pcie, res); >> +i++; >> +break; >> +default: >> +continue; > > Can the default case be omitted? Sure >> +} >> +} >> + >> +return 0; >> +} >> + >> static int rcar_pcie_enable(struct rcar_pcie *pcie) >> { >> struct device *dev = pcie->dev; >> @@ -872,11 +902,25 @@ static const struct irq_domain_ops msi_domain_ops = { >> .map = rcar_msi_map, >> }; >> >> +static void rcar_pcie_hw_enable_msi(struct rcar_pcie *pcie) >> +{ >> +struct rcar_msi *msi = >msi; >> +unsigned long base; >> + >> +/* setup MSI data target */ >> +base = virt_to_phys((void *)msi->pages); > > Why do you need to cast to void *? > I expect such casting can be done implicitly. Because __get_free_pages() returns unsigned long and that's what's used to assign msi->pages . And virt_to_phys() expects void * instead, thus the cast. >> + >> +rcar_pci_write_reg(pcie, base | MSIFE, PCIEMSIALR); >> +rcar_pci_write_reg(pcie, 0, PCIEMSIAUR); >> + >> +/* enable all MSI interrupts */ >> +rcar_pci_write_reg(pcie, 0x, PCIEMSIIER); >> +} >> + >> static int rcar_pcie_enable_msi(struct rcar_pcie *pcie) >> { >> struct device *dev = pcie->dev; >> struct rcar_msi *msi = >msi; >> -unsigned long base; >> int err, i; >> >> mutex_init(>lock); >> @@ -915,13 +959,7 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie) >> >> /* setup MSI data target */ >> msi->pages = __get_free_pages(GFP_KERNEL, 0); >> -base = virt_to_phys((void *)msi->pages); >> - >> -rcar_pci_write_reg(pcie, base | MSIFE, PCIEMSIALR); >> -rcar_pci_write_reg(pcie, 0, PCIEMSIAUR); >> - >> -/* enable all MSI interrupts */ >> -rcar_pci_write_reg(pcie, 0x, PCIEMSIIER); >> +rcar_pcie_hw_enable_msi(pcie); >> >> return 0; >> >> @@ -1202,6 +1240,37 @@ static int rcar_pcie_probe(struct platform_device >> *pdev) >> return err; >> } >> >> +static int rcar_pcie_resume(struct device *dev) >> +{ >> +struct rcar_pcie *pcie = dev_get_drvdata(dev); >> +unsigned int data; >> +int err; >> +int (*hw_init_fn)(struct rcar_pcie *); > > Please sort local variables in reverse xmas tree order. OK >> + >> +err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); >> +if (err) >> +return 0; >> + >> +/* Failure to get a link might just be that no cards are inserted */ >> +hw_init_fn = of_device_get_match_data(dev); >> +err = hw_init_fn(pcie); >> +if (err) { >> +dev_info(dev, "PCIe link down\n"); >> +return 0; >> +} >> + >> +data = rcar_pci_read_reg(pcie,
Re: [PATCH 1/3] PCI: rcar: Add the initialization of PCIe link in resume_noirq
On 11/08/2017 12:00 PM, Sergei Shtylyov wrote: > On 11/8/2017 12:28 PM, Marek Vasut wrote: > >> From: Kazufumi Ikeda>> >> Reestablish the PCIe link very early in the resume process in case it >> went down to prevent PCI accesses from hanging the bus. Such accesses >> can happen early in the PCI resume process, in the resume_noirq, thus >> the link must be reestablished in the resume_noirq callback of the >> driver. >> >> Signed-off-by: Kazufumi Ikeda >> Signed-off-by: Gaku Inami >> Signed-off-by: Marek Vasut >> Cc: Geert Uytterhoeven >> Cc: Simon Horman >> Cc: Wolfram Sang >> Cc: linux-renesas-soc@vger.kernel.org >> --- >> drivers/pci/host/pcie-rcar.c | 31 --- >> 1 file changed, 28 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c >> index 889603783f01..aa588a7d4811 100644 >> --- a/drivers/pci/host/pcie-rcar.c >> +++ b/drivers/pci/host/pcie-rcar.c > [...] >> @@ -529,7 +530,7 @@ static void phy_write_reg(struct rcar_pcie *pcie, >> phy_wait_for_ack(pcie); >> } >> -static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie) >> +static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie, int atomic) > > How about *bool* atomic? Not a big fan of bool in C, but I think I can avoid this altogether. If I poll more often, I can just use udelay(5) for such a short delay. > [...] > > MBR, Sergei -- Best regards, Marek Vasut
Re: [PATCH 2/3] PCI: rcar: Support runtime PM, link state L1 handling
On 11/10/2017 10:03 AM, Simon Horman wrote: > On Wed, Nov 08, 2017 at 10:28:05AM +0100, Marek Vasut wrote: >> From: Phil Edworthy>> >> Most PCIe host controllers support L0s and L1 power states via ASPM. >> The R-Car hardware only supports L0s, so when the system suspends and >> resumes we have to manually handle L1. >> >> When the system suspends, cards can put themselves into L1 and send a >> PM_ENTER_L1 DLLP to the host controller. At this point, we can no longer >> access the card's config registers. >> >> The R-Car host controller will handle taking cards out of L1 as long as >> the host controller has also been transitioned to L1 link state. >> >> Ideally, we would detect the PM_ENTER_L1 DLLP using an interrupt and >> transition the host to L1 immediately. However, this patch just ensures >> that we can talk to cards after they have gone into L1. >> When attempting a config access, it checks to see if the card has gone >> into L1, and if so, does the same for the host controller. >> >> This is based on a patch by Hien Dang >> >> Signed-off-by: Phil Edworthy >> Signed-off-by: Marek Vasut >> Cc: Geert Uytterhoeven >> Cc: Simon Horman >> Cc: Wolfram Sang >> Cc: linux-renesas-soc@vger.kernel.org > > Hi Marek, > > With my nit addressed please feel free to add: > > Acked-by: Simon Horman > >> --- >> drivers/pci/host/pcie-rcar.c | 24 >> 1 file changed, 24 insertions(+) >> >> diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c >> index aa588a7d4811..2b28292de93a 100644 >> --- a/drivers/pci/host/pcie-rcar.c >> +++ b/drivers/pci/host/pcie-rcar.c >> @@ -92,6 +92,13 @@ >> #define MACCTLR 0x011058 >> #define SPEED_CHANGE (1 << 24) >> #define SCRAMBLE_DISABLE (1 << 27) >> +#define PMSR0x01105c >> +#define L1FAEG (1 << 31) >> +#define PM_ENTER_L1RX (1 << 23) >> +#define PMSTATE(7 << 16) >> +#define PMSTATE_L1 (3 << 16) >> +#define PMCTLR 0x011060 >> +#define L1_INIT(1 << 31) > > The BIT() and GENMASK() macros are nice in my opinion. > But I see what you have added follows the style of the existing code > in the driver. I added a patch into the series to clean this up and will then use BIT() and GENMASK() here too. >> #define MACS2R 0x011078 >> #define MACCGSPSETR 0x011084 >> #define SPCNGRSN (1 << 31) >> @@ -191,6 +198,7 @@ static int rcar_pcie_config_access(struct rcar_pcie >> *pcie, >> unsigned int devfn, int where, u32 *data) >> { >> int dev, func, reg, index; >> +u32 val; >> >> dev = PCI_SLOT(devfn); >> func = PCI_FUNC(devfn); >> @@ -232,6 +240,22 @@ static int rcar_pcie_config_access(struct rcar_pcie >> *pcie, >> if (pcie->root_bus_nr < 0) >> return PCIBIOS_DEVICE_NOT_FOUND; >> >> +/* >> + * If we are not in L1 link state and we have received PM_ENTER_L1 DLLP, >> + * transition to L1 link state. The HW will handle coming of of L1. >> + */ >> +val = rcar_pci_read_reg(pcie, PMSR); >> +if ((val & PM_ENTER_L1RX) && ((val & PMSTATE) != PMSTATE_L1)) { > > nit: please remove the unnecessary parentheses from the line above. Fixed >> +rcar_pci_write_reg(pcie, L1_INIT, PMCTLR); >> + >> +/* Wait until we are in L1 */ >> +while (!(val & L1FAEG)) >> +val = rcar_pci_read_reg(pcie, PMSR); >> + >> +/* Clear flags indicating link has transitioned to L1 */ >> +rcar_pci_write_reg(pcie, L1FAEG | PM_ENTER_L1RX, PMSR); >> +} >> + >> /* Clear errors */ >> rcar_pci_write_reg(pcie, rcar_pci_read_reg(pcie, PCIEERRFR), PCIEERRFR); >> >> -- >> 2.11.0 >> -- Best regards, Marek Vasut
Re: [PATCH 1/3] PCI: rcar: Add the initialization of PCIe link in resume_noirq
On 11/10/2017 09:59 AM, Simon Horman wrote: > Hi Marek, Hi Simon, > On Wed, Nov 08, 2017 at 10:28:04AM +0100, Marek Vasut wrote: >> From: Kazufumi Ikeda>> >> Reestablish the PCIe link very early in the resume process in case it >> went down to prevent PCI accesses from hanging the bus. Such accesses >> can happen early in the PCI resume process, in the resume_noirq, thus >> the link must be reestablished in the resume_noirq callback of the >> driver. >> >> Signed-off-by: Kazufumi Ikeda >> Signed-off-by: Gaku Inami >> Signed-off-by: Marek Vasut >> Cc: Geert Uytterhoeven >> Cc: Simon Horman >> Cc: Wolfram Sang >> Cc: linux-renesas-soc@vger.kernel.org > > For patch-sets (with more than one patch) please provide a cover-letter. > The --cover-letter option to git format-patch can help. > >> --- >> drivers/pci/host/pcie-rcar.c | 31 --- >> 1 file changed, 28 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c >> index 889603783f01..aa588a7d4811 100644 >> --- a/drivers/pci/host/pcie-rcar.c >> +++ b/drivers/pci/host/pcie-rcar.c >> @@ -43,6 +43,7 @@ >> >> /* Transfer control */ >> #define PCIETCTLR 0x02000 >> +#define DL_DOWN(1 << 3) > > Can you use the BIT() macro here? Yes, I'll also add a patch to the series to convert all the others to the BIT() macro, to keep things consistent. >> #define CFINIT 1 >> #define PCIETSTR0x02004 >> #define DATA_LINK_ACTIVE 1 >> @@ -529,7 +530,7 @@ static void phy_write_reg(struct rcar_pcie *pcie, >> phy_wait_for_ack(pcie); >> } >> >> -static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie) >> +static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie, int atomic) > > As Sergei mentioned bool seems like a more appropriate type for atomic. I can actually get rid of this altogether. >> { >> unsigned int timeout = 10; >> >> @@ -537,7 +538,10 @@ static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie) >> if ((rcar_pci_read_reg(pcie, PCIETSTR) & DATA_LINK_ACTIVE)) >> return 0; >> >> -msleep(5); >> +if (atomic) >> +mdelay(5); >> +else >> +msleep(5); > > If we must delay, then I suppose this is reasonable. See above >> } >> >> return -ETIMEDOUT; >> @@ -595,7 +599,7 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie) >> rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); >> >> /* This will timeout if we don't have a link. */ >> -err = rcar_pcie_wait_for_dl(pcie); >> +err = rcar_pcie_wait_for_dl(pcie, 0); >> if (err) >> return err; >> >> @@ -1110,6 +1114,7 @@ static int rcar_pcie_probe(struct platform_device >> *pdev) >> pcie = pci_host_bridge_priv(bridge); >> >> pcie->dev = dev; >> +platform_set_drvdata(pdev, pcie); >> >> INIT_LIST_HEAD(>resources); >> >> @@ -1173,10 +1178,30 @@ static int rcar_pcie_probe(struct platform_device >> *pdev) >> return err; >> } >> >> +static int rcar_pcie_resume_noirq(struct device *dev) >> +{ >> +struct rcar_pcie *pcie = dev_get_drvdata(dev); >> +u32 val = rcar_pci_read_reg(pcie, PMSR); >> +int ret = 0; >> + >> +if ((val == 0) || (rcar_pci_read_reg(pcie, PCIETCTLR) & DL_DOWN)) { > > Please remove the unnecessary parentheses from the line above. > > Also, I would prefer if the function returned early. > Something like (completely untested!): This should work. > if (rcar_pci_read_reg(pcie, PMSR) && > !(rcar_pci_read_reg(pcie, PCIETCTLR) & DL_DOWN)) > return 0; > > rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); > return rcar_pcie_wait_for_dl(pcie, 1); > >> +/* Re-establish the PCIe link */ >> +rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); >> +ret = rcar_pcie_wait_for_dl(pcie, 1); >> +} >> + >> +return ret; >> +} >> + >> +static const struct dev_pm_ops rcar_pcie_pm_ops = { >> +.resume_noirq = rcar_pcie_resume_noirq, >> +}; >> + >> static struct platform_driver rcar_pcie_driver = { >> .driver = { >> .name = "rcar-pcie", >> .of_match_table = rcar_pcie_of_match, >> +.pm = _pcie_pm_ops, >> .suppress_bind_attrs = true, >> }, >> .probe = rcar_pcie_probe, >> -- >> 2.11.0 >> -- Best regards, Marek Vasut
[PATCH V3] PCI: rcar: Use runtime PM to control controller clock
From: Dien PhamThe controller clock can be switched off during suspend/resume, let runtime PM take care of that. Signed-off-by: Dien Pham Signed-off-by: Hien Dang Signed-off-by: Marek Vasut Cc: Geert Uytterhoeven Cc: Phil Edworthy Cc: Simon Horman Cc: Wolfram Sang Cc: linux-renesas-soc@vger.kernel.org To: linux-...@vger.kernel.org --- V2: - Reorder the fail path in rcar_pcie_probe() to cater for the reordering of function calls in probe - Dispose of fail_clk in rcar_pcie_get_resources() V3: - Fix up the failpath in probe function --- drivers/pci/host/pcie-rcar.c | 40 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 12796eccb2be..e00f865952d5 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c @@ -145,7 +145,6 @@ struct rcar_pcie { void __iomem*base; struct list_headresources; int root_bus_nr; - struct clk *clk; struct clk *bus_clk; struct rcar_msi msi; }; @@ -917,24 +916,14 @@ static int rcar_pcie_get_resources(struct rcar_pcie *pcie) if (IS_ERR(pcie->base)) return PTR_ERR(pcie->base); - pcie->clk = devm_clk_get(dev, "pcie"); - if (IS_ERR(pcie->clk)) { - dev_err(dev, "cannot get platform clock\n"); - return PTR_ERR(pcie->clk); - } - err = clk_prepare_enable(pcie->clk); - if (err) - return err; - pcie->bus_clk = devm_clk_get(dev, "pcie_bus"); if (IS_ERR(pcie->bus_clk)) { dev_err(dev, "cannot get pcie bus clock\n"); - err = PTR_ERR(pcie->bus_clk); - goto fail_clk; + return PTR_ERR(pcie->bus_clk); } err = clk_prepare_enable(pcie->bus_clk); if (err) - goto fail_clk; + return err; i = irq_of_parse_and_map(dev->of_node, 0); if (!i) { @@ -956,8 +945,6 @@ static int rcar_pcie_get_resources(struct rcar_pcie *pcie) err_map_reg: clk_disable_unprepare(pcie->bus_clk); -fail_clk: - clk_disable_unprepare(pcie->clk); return err; } @@ -1125,22 +1112,22 @@ static int rcar_pcie_probe(struct platform_device *pdev) rcar_pcie_parse_request_of_pci_ranges(pcie); + pm_runtime_enable(pcie->dev); + err = pm_runtime_get_sync(pcie->dev); + if (err < 0) { + dev_err(pcie->dev, "pm_runtime_get_sync failed\n"); + goto err_pm_disable; + } + err = rcar_pcie_get_resources(pcie); if (err < 0) { dev_err(dev, "failed to request resources: %d\n", err); - goto err_free_bridge; + goto err_pm_put; } err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); if (err) - goto err_free_bridge; - - pm_runtime_enable(dev); - err = pm_runtime_get_sync(dev); - if (err < 0) { - dev_err(dev, "pm_runtime_get_sync failed\n"); - goto err_pm_disable; - } + goto err_pm_put; /* Failure to get a link might just be that no cards are inserted */ hw_init_fn = of_device_get_match_data(dev); @@ -1172,13 +1159,10 @@ static int rcar_pcie_probe(struct platform_device *pdev) err_pm_put: pm_runtime_put(dev); - err_pm_disable: pm_runtime_disable(dev); - -err_free_bridge: - pci_free_host_bridge(bridge); pci_free_resource_list(>resources); + pci_free_host_bridge(bridge); return err; } -- 2.11.0
Re: [PATCH 1/8] dt-bindings: can: rcar_can: document r8a774[35] can support
On Tue, Nov 07, 2017 at 03:10:42PM +, Fabrizio Castro wrote: > Document "renesas,can-r8a7743" and "renesas,can-r8a7745" compatible > strings. Since the fallback compatible string ("renesas,rcar-gen2-can") > activates the right code in the driver, no driver change is needed. > > Signed-off-by: Fabrizio Castro> Reviewed-by: Biju Das > --- > Documentation/devicetree/bindings/net/can/rcar_can.txt | 7 +-- > 1 file changed, 5 insertions(+), 2 deletions(-) Acked-by: Rob Herring
[PATCH 3/3] arm64: dts: renesas: eagle: add EtherAVB pins
Add the (previously omitted) EtherAVB pin data to the Eagle board's device tree. Signed-off-by: Sergei Shtylyov--- arch/arm64/boot/dts/renesas/r8a77970-eagle.dts |8 1 file changed, 8 insertions(+) Index: renesas/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts === --- renesas.orig/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts +++ renesas/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts @@ -34,6 +34,9 @@ }; { + pinctrl-0 = <_pins>; + pinctrl-names = "default"; + renesas,no-ether-link; phy-handle = <>; status = "okay"; @@ -53,6 +56,11 @@ }; { + avb_pins: avb { + groups = "avb0_mdio", "avb0_mii"; + function = "avb0"; + }; + scif0_pins: scif0 { groups = "scif0_data"; function = "scif0";
[PATCH 0/3] Add R8A77970/Eagle PFC support
Hello! Here's the set of 3 patches against Simon Horman's 'renesas.git' repo's 'renesas-devel-20171110-v4.14-rc8' tag. We're adding the R8A77970 PFC node and then describing the pins for SCIF0 and EtherAVB devices declared earlier. These patches depend on the R8A77970 PFC suport in order to work properly. [1/3] arm64: dts: renesas: r8a77970: add PFC support [2/3] arm64: dts: renesas: eagle: add SCIF0 pins [3/3] arm64: dts: renesas: eagle: add EtherAVB pins WBR, Sergei
[PATCH 1/3] arm64: dts: renesas: r8a77970: add PFC support
Define the generic R8A77970 part of the PFC device node. Signed-off-by: Sergei Shtylyov--- arch/arm64/boot/dts/renesas/r8a77970.dtsi |5 + 1 file changed, 5 insertions(+) Index: renesas/arch/arm64/boot/dts/renesas/r8a77970.dtsi === --- renesas.orig/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ renesas/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -134,6 +134,11 @@ #power-domain-cells = <1>; }; + pfc: pin-controller@e606 { + compatible = "renesas,pfc-r8a77970"; + reg = <0 0xe606 0 0x504>; + }; + intc_ex: interrupt-controller@e61c { compatible = "renesas,intc-ex-r8a77970", "renesas,irqc"; #interrupt-cells = <2>;
[PATCH 2/3] arm64: dts: renesas: eagle: add SCIF0 pins
Add the (previously omitted) SCIF0 pin data to the Eagle board's device tree. Signed-off-by: Sergei Shtylyov--- arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 10 ++ 1 file changed, 10 insertions(+) Index: renesas/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts === --- renesas.orig/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts +++ renesas/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts @@ -52,11 +52,21 @@ clock-frequency = <32768>; }; + { + scif0_pins: scif0 { + groups = "scif0_data"; + function = "scif0"; + }; +}; + { timeout-sec = <60>; status = "okay"; }; { + pinctrl-0 = <_pins>; + pinctrl-names = "default"; + status = "okay"; };
[PATCH 1/2] pinctrl: sh-pfc: add PORT_GP_CFG_{6|22}() helper macros
They follow the style of the existing PORT_GP_CFG_() macros and will be used by a follow-up patch for the R8A77970 SoC. Based on the original (and large) patch by Daisuke Matsushita. Signed-off-by: Vladimir Barinov Signed-off-by: Sergei Shtylyov --- drivers/pinctrl/sh-pfc/sh_pfc.h | 16 1 file changed, 12 insertions(+), 4 deletions(-) Index: renesas-drivers/drivers/pinctrl/sh-pfc/sh_pfc.h === --- renesas-drivers.orig/drivers/pinctrl/sh-pfc/sh_pfc.h +++ renesas-drivers/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -389,10 +389,14 @@ extern const struct sh_pfc_soc_info shx3 PORT_GP_CFG_1(bank, 3, fn, sfx, cfg) #define PORT_GP_4(bank, fn, sfx) PORT_GP_CFG_4(bank, fn, sfx, 0) -#define PORT_GP_CFG_8(bank, fn, sfx, cfg) \ +#define PORT_GP_CFG_6(bank, fn, sfx, cfg) \ PORT_GP_CFG_4(bank, fn, sfx, cfg), \ PORT_GP_CFG_1(bank, 4, fn, sfx, cfg), \ - PORT_GP_CFG_1(bank, 5, fn, sfx, cfg), \ + PORT_GP_CFG_1(bank, 5, fn, sfx, cfg) +#define PORT_GP_6(bank, fn, sfx) PORT_GP_CFG_6(bank, fn, sfx, 0) + +#define PORT_GP_CFG_8(bank, fn, sfx, cfg) \ + PORT_GP_CFG_6(bank, fn, sfx, cfg), \ PORT_GP_CFG_1(bank, 6, fn, sfx, cfg), \ PORT_GP_CFG_1(bank, 7, fn, sfx, cfg) #define PORT_GP_8(bank, fn, sfx) PORT_GP_CFG_8(bank, fn, sfx, 0) @@ -450,9 +454,13 @@ extern const struct sh_pfc_soc_info shx3 PORT_GP_CFG_1(bank, 20, fn, sfx, cfg) #define PORT_GP_21(bank, fn, sfx) PORT_GP_CFG_21(bank, fn, sfx, 0) -#define PORT_GP_CFG_23(bank, fn, sfx, cfg) \ +#define PORT_GP_CFG_22(bank, fn, sfx, cfg) \ PORT_GP_CFG_21(bank, fn, sfx, cfg), \ - PORT_GP_CFG_1(bank, 21, fn, sfx, cfg), \ + PORT_GP_CFG_1(bank, 21, fn, sfx, cfg) +#define PORT_GP_22(bank, fn, sfx) PORT_GP_CFG_22(bank, fn, sfx, 0) + +#define PORT_GP_CFG_23(bank, fn, sfx, cfg) \ + PORT_GP_CFG_22(bank, fn, sfx, cfg), \ PORT_GP_CFG_1(bank, 22, fn, sfx, cfg) #define PORT_GP_23(bank, fn, sfx) PORT_GP_CFG_23(bank, fn, sfx, 0)
[PATCH 2/2] pinctrl: sh-pfc: add R8A77970 PFC support
Add the PFC support for the R8A77970 SoC including pin groups for some on-chip devices such as CAN-FD, EtherAVB, [H]SCIF, I2C, INTC-EX, MMC, MSIOF, PWM, VIN... Based on the original (and large) patch by Daisuke Matsushita. Signed-off-by: Vladimir Barinov Signed-off-by: Sergei Shtylyov --- Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt |1 drivers/pinctrl/sh-pfc/Kconfig|5 drivers/pinctrl/sh-pfc/Makefile |1 drivers/pinctrl/sh-pfc/core.c |6 drivers/pinctrl/sh-pfc/pfc-r8a77970.c | 2421 ++ drivers/pinctrl/sh-pfc/sh_pfc.h |1 6 files changed, 2435 insertions(+) Index: renesas-drivers/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt === --- renesas-drivers.orig/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt +++ renesas-drivers/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt @@ -24,6 +24,7 @@ Required Properties: - "renesas,pfc-r8a7794": for R8A7794 (R-Car E2) compatible pin-controller. - "renesas,pfc-r8a7795": for R8A7795 (R-Car H3) compatible pin-controller. - "renesas,pfc-r8a7796": for R8A7796 (R-Car M3-W) compatible pin-controller. +- "renesas,pfc-r8a77970": for R8A77970 (R-Car V3M) compatible pin-controller. - "renesas,pfc-r8a77995": for R8A77995 (R-Car D3) compatible pin-controller. - "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller. Index: renesas-drivers/drivers/pinctrl/sh-pfc/Kconfig === --- renesas-drivers.orig/drivers/pinctrl/sh-pfc/Kconfig +++ renesas-drivers/drivers/pinctrl/sh-pfc/Kconfig @@ -89,6 +89,11 @@ config PINCTRL_PFC_R8A7796 depends on ARCH_R8A7796 select PINCTRL_SH_PFC +config PINCTRL_PFC_R8A77970 + def_bool y + depends on ARCH_R8A77970 + select PINCTRL_SH_PFC + config PINCTRL_PFC_R8A77995 def_bool y depends on ARCH_R8A77995 Index: renesas-drivers/drivers/pinctrl/sh-pfc/Makefile === --- renesas-drivers.orig/drivers/pinctrl/sh-pfc/Makefile +++ renesas-drivers/drivers/pinctrl/sh-pfc/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A7794) += pfc obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795.o obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795-es1.o obj-$(CONFIG_PINCTRL_PFC_R8A7796) += pfc-r8a7796.o +obj-$(CONFIG_PINCTRL_PFC_R8A77970) += pfc-r8a77970.o obj-$(CONFIG_PINCTRL_PFC_R8A77995) += pfc-r8a77995.o obj-$(CONFIG_PINCTRL_PFC_SH7203) += pfc-sh7203.o obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o Index: renesas-drivers/drivers/pinctrl/sh-pfc/core.c === --- renesas-drivers.orig/drivers/pinctrl/sh-pfc/core.c +++ renesas-drivers/drivers/pinctrl/sh-pfc/core.c @@ -557,6 +557,12 @@ static const struct of_device_id sh_pfc_ .data = _pinmux_info, }, #endif +#ifdef CONFIG_PINCTRL_PFC_R8A77970 + { + .compatible = "renesas,pfc-r8a77970", + .data = _pinmux_info, + }, +#endif #ifdef CONFIG_PINCTRL_PFC_R8A77995 { .compatible = "renesas,pfc-r8a77995", Index: renesas-drivers/drivers/pinctrl/sh-pfc/pfc-r8a77970.c === --- /dev/null +++ renesas-drivers/drivers/pinctrl/sh-pfc/pfc-r8a77970.c @@ -0,0 +1,2421 @@ +/* + * R8A77970 processor support - PFC hardware block. + * + * Copyright (C) 2016 Renesas Electronics Corp. + * Copyright (C) 2017 Cogent Embedded, Inc. + * + * This file is based on the drivers/pinctrl/sh-pfc/pfc-r8a7795.c + * + * R-Car Gen3 processor support - PFC hardware block. + * + * Copyright (C) 2015 Renesas Electronics Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include + +#include "core.h" +#include "sh_pfc.h" + +#define CPU_ALL_PORT(fn, sfx) \ + PORT_GP_CFG_22(0, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_28(1, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_17(2, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_17(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_6(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_15(5, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH)
[PATCH 0/2] Add Renesas R8A77970 PFC driver
Hello! Here's a set of 2 patches against the 'sh-pfcl' branch of Geert Uyyterhoeven's 'renesas-drivers.git' repo. The patches add support for the R8A77970 PFC (note that the pin pull-up/down support was removed in the last minute since that part of the PFC driver has been reworked by Geert -- I will convert my code to the new pull-up/down API later... [1/2] pinctrl: sh-pfc: add PORT_GP_CFG_{6|22}() helper macros [2/2] pinctrl: sh-pfc: add R8A77970 PFC support MBR, Sergei
[RFC PATCH 1/2] pinctrl: sh-pfc: r8a7794: Add can_clk function
This patch adds can_clk function to r8a7745/r8a7794 which is cleaner, as it reduces duplication, and allows for independent configuration. Signed-off-by: Fabrizio CastroReviewed-by: Ramesh Shanmugasundaram --- drivers/pinctrl/sh-pfc/pfc-r8a7794.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7794.c b/drivers/pinctrl/sh-pfc/pfc-r8a7794.c index e5b3d5f..73796aa 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7794.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7794.c @@ -3858,10 +3858,6 @@ static const char * const can0_groups[] = { "can0_data_b", "can0_data_c", "can0_data_d", - "can_clk", - "can_clk_b", - "can_clk_c", - "can_clk_d", }; static const char * const can1_groups[] = { @@ -3869,6 +3865,9 @@ static const char * const can1_groups[] = { "can1_data_b", "can1_data_c", "can1_data_d", +}; + +static const char * const can_clk_groups[] = { "can_clk", "can_clk_b", "can_clk_c", @@ -4248,6 +4247,7 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(avb), SH_PFC_FUNCTION(can0), SH_PFC_FUNCTION(can1), + SH_PFC_FUNCTION(can_clk), SH_PFC_FUNCTION(du0), SH_PFC_FUNCTION(du1), SH_PFC_FUNCTION(eth), -- 2.7.4
[RFC PATCH 2/2] pinctrl: sh-pfc: r8a7791: Add can_clk function
This patch adds can_clk function to r8a7743/r8a7791 which is cleaner, as it reduces duplication, and allows for independent configuration. Signed-off-by: Fabrizio CastroReviewed-by: Ramesh Shanmugasundaram --- drivers/pinctrl/sh-pfc/pfc-r8a7791.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c index 10bd35f..2dbf2419 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c @@ -4826,10 +4826,6 @@ static const char * const can0_groups[] = { "can0_data_d", "can0_data_e", "can0_data_f", - "can_clk", - "can_clk_b", - "can_clk_c", - "can_clk_d", }; static const char * const can1_groups[] = { @@ -4837,6 +4833,9 @@ static const char * const can1_groups[] = { "can1_data_b", "can1_data_c", "can1_data_d", +}; + +static const char * const can_clk_groups[] = { "can_clk", "can_clk_b", "can_clk_c", @@ -5308,7 +5307,7 @@ static const char * const vin2_groups[] = { }; static const struct { - struct sh_pfc_function common[56]; + struct sh_pfc_function common[57]; struct sh_pfc_function r8a779x[2]; } pinmux_functions = { .common = { @@ -5316,6 +5315,7 @@ static const struct { SH_PFC_FUNCTION(avb), SH_PFC_FUNCTION(can0), SH_PFC_FUNCTION(can1), + SH_PFC_FUNCTION(can_clk), SH_PFC_FUNCTION(du), SH_PFC_FUNCTION(du0), SH_PFC_FUNCTION(du1), -- 2.7.4
[RFC PATCH 0/2] Add can_clk function
Hello Geert, All thank you for your comments on patch: "pinctrl: sh-pfc: r8a7745: Add CAN[01] support" Looking at file drivers/pinctrl/sh-pfc/pfc-r8a7791.c, it looks like it could use the same enhancement. This series applies Geert's recommendation to both pfc-r8a7791.c and pfc-r8a7794.c. Unfortunately I wasn't able to actually test this patch set as I don't have access to HW providing can_clk. Best regards, Fabrizio Castro (2): pinctrl: sh-pfc: r8a7745: Add can_clk function pinctrl: sh-pfc: r8a7743: Add can_clk function drivers/pinctrl/sh-pfc/pfc-r8a7791.c | 10 +- drivers/pinctrl/sh-pfc/pfc-r8a7794.c | 8 2 files changed, 9 insertions(+), 9 deletions(-) -- 2.7.4
Re: [PATCH v2 0/3] PM / Domain: renesas: Fix active wakeup behavior
On 10 November 2017 at 14:22, Geert Uytterhoevenwrote: > Hi Ulf, > > On Fri, Nov 10, 2017 at 1:49 PM, Ulf Hansson wrote: >> On 10 November 2017 at 11:22, Geert Uytterhoeven >> wrote: >>> On Fri, Nov 10, 2017 at 10:57 AM, Ulf Hansson >>> wrote: On 9 November 2017 at 14:26, Geert Uytterhoeven wrote: > If a device in a Renesas ARM SoC is part of a Clock Domain, and it is > used as a wakeup source, it must be kept active during system suspend. Geert, I think we discussed this a bit already. I wonder if the above is a correct statement for all devices in these PM domains, that has wakeups? >>> >>> It is true for all wakeup sources (e.g. Ethernet and serial). >>> Don't these SoCs make use of any external logic (out-of-band IRQ) to deal with the wakeup IRQs? For example, how is GPIO irqs dealt with in this regards? >>> >>> Interrupt controllers (incl. GPIO) may, depending on SoC type: >>> - be located in a controllable power area (SH/R-Mobile), >>> - may run from a controllable module clock (SH/R-Mobile, R-Car Gen2/Gen3, >>> RZ/A1, RZ/G1). >>> >>> So there are no out-of-band IRQs in the wakeup path, unless on SoCs where >>> the interrupt controllers are in an always-on power area, AND run from a >>> fixed clock. I think only R-Car Gen1 falls in that category. >>> Still, R-Car Gen1 needs active_wakeup for wakeup sources. >> >> Perhaps out-of-band IRQ is a too vague term. :-) Anyway, let me >> elaborate a bit more. >> >> Apologize for being so persistent, but I really want to get to bottom with >> this. >> >> According to the statement above, it seems like IRQs (including GPIOs) >> is controllable from a separate "power area" (or module clock). In > > There are two ways to save power: disabling the module clock, and powering > down the module logic. > >> many ARM SoCs that "power area" is a separate piece of external logic, >> sometimes it may even consist a small co-processor. I guess you >> already know that, but wanted to point it out for clarity. > > Sure. > > I think on some older SH/R-Mobile SoCs you can do something similar, > but even there you have to keep the interrupt controller's power area powered. > This makes sense, given those SoCs also have an SH core, which could be used > as the small co-processor that powers down the whole ARM subsystem and > handles wakeup through the SH subsystem's interrupt controller. > >> For that reason, some serial drivers re-routs its serial rx pin to a >> GPIO IRQ to deal with wakeup, instead of keeping the serial device >> always powered. This enables the GPIO IRQ to be managed by the >> external logic, thus allowing the serial device and the PM domain it >> is attached to, to be powered off. Especially during system suspend, >> that may avoid wasting lots of power. > > Doesn't re-routing a pin to a GPIO require using pinctrl? Yes. > > Here the serial device is the wakeup source, but it doesn't handle wakeup > itself... Exactly. > >> Another example, where I think a more fine grained method is preferred >> over using GENPD_FLAG_ACTIVE_WAKEUP, is when an SD card controller has >> an card detect pin hooked up to a GPIO. Thus the device_may_wakeup() >> would return true for the SD card controller's struct device, but that >> does not mean that the device needs to stay powered during system >> suspend. > > This one is more tricky, as I think we're already using a GPIO for CD on > many boards. > Then the SD device is the wakeup source, but it doesn't handle wakeup > itself... Exactly! > > So you not only need a flag to opt-in, but also a flag to opt-out? >From a genpd point of view, the default method is to trusts the driver to deal with the wakeup, then it treats the device (and thus the PM domain) as it can be powered down, even if it is configured as a wakeup source. Therefore, I have so far, only seen a reason to enable an opt-in method, to let drivers instruct genpd that it needs to change its default behavior. > >>> See series "[PATCH/RFC 0/3] renesas: irqchip: Use wakeup_path i.s.o. >>> explicit clock handling", which includes GPIO interrupts. >>> If that is the case, you should really avoid using the big hammer method of setting the GENPD_FLAG_ACTIVE_WAKEUP. >>> >>> So I think I do need the big hammer ;-) >> >> From a hypothetical point of view, if you were to use the more fine >> grained method I proposed [1] (or something very similar), how many >> drivers would you need to change, to be able to remove the current >> workaround? > > I think five: > > - drivers/gpio/gpio-rcar.c > - drivers/irqchip/irq-renesas-intc-irqpin.c > - drivers/irqchip/irq-renesas-irqc.c > - drivers/net/ethernet/renesas/ravb_main.c > - drivers/net/ethernet/renesas/sh_eth.c Great, that sounds quite limited. :-) > > Note that while setting the flag wouldn't harm, it would
[PATCH 0/2] Add CAN & CAN FD pinctrl support for R-Car H3 ES2.0
Hi Geert, All, This series adds CAN and CAN FD pinctrl support for R-Car H3 ES2.0. The pin config is identical to H3 ES1.x. This series is based on renesas-drivers repo commit: cdf382160c46b29ce99532ed4378ddc044a5a1c9 Thanks, Ramesh. Ramesh Shanmugasundaram (2): pinctrl: sh-pfc: r8a7795: Add CAN support pinctrl: sh-pfc: r8a7795: Add CAN FD support drivers/pinctrl/sh-pfc/pfc-r8a7795.c | 89 1 file changed, 89 insertions(+) -- 2.12.2
[PATCH 1/2] pinctrl: sh-pfc: r8a7795: Add CAN support
This patch adds CAN[0-1] pinmux support for R-Car H3 ES2.0. The pin config is identical to H3 ES1.*. Signed-off-by: Ramesh ShanmugasundaramReviewed-by: Fabrizio Castro --- drivers/pinctrl/sh-pfc/pfc-r8a7795.c | 52 1 file changed, 52 insertions(+) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c index d1cec6d12e81..59249a990cef 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c @@ -1781,6 +1781,38 @@ static const unsigned int avb_avtp_capture_b_mux[] = { AVB_AVTP_CAPTURE_B_MARK, }; +/* - CAN -- */ +static const unsigned int can0_data_a_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 24), +}; +static const unsigned int can0_data_a_mux[] = { + CAN0_TX_A_MARK, CAN0_RX_A_MARK, +}; +static const unsigned int can0_data_b_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1), +}; +static const unsigned int can0_data_b_mux[] = { + CAN0_TX_B_MARK, CAN0_RX_B_MARK, +}; +static const unsigned int can1_data_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 26), +}; +static const unsigned int can1_data_mux[] = { + CAN1_TX_MARK, CAN1_RX_MARK, +}; + +/* - CAN Clock -- */ +static const unsigned int can_clk_pins[] = { + /* CLK */ + RCAR_GP_PIN(1, 25), +}; +static const unsigned int can_clk_mux[] = { + CAN_CLK_MARK, +}; + /* - DRIF0 --- */ static const unsigned int drif0_ctrl_a_pins[] = { /* CLK, SYNC */ @@ -3843,6 +3875,10 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(avb_avtp_capture_a), SH_PFC_PIN_GROUP(avb_avtp_match_b), SH_PFC_PIN_GROUP(avb_avtp_capture_b), + SH_PFC_PIN_GROUP(can0_data_a), + SH_PFC_PIN_GROUP(can0_data_b), + SH_PFC_PIN_GROUP(can1_data), + SH_PFC_PIN_GROUP(can_clk), SH_PFC_PIN_GROUP(drif0_ctrl_a), SH_PFC_PIN_GROUP(drif0_data0_a), SH_PFC_PIN_GROUP(drif0_data1_a), @@ -4154,6 +4190,19 @@ static const char * const avb_groups[] = { "avb_avtp_capture_b", }; +static const char * const can0_groups[] = { + "can0_data_a", + "can0_data_b", +}; + +static const char * const can1_groups[] = { + "can1_data", +}; + +static const char * const can_clk_groups[] = { + "can_clk", +}; + static const char * const drif0_groups[] = { "drif0_ctrl_a", "drif0_data0_a", @@ -4559,6 +4608,9 @@ static const char * const usb30_groups[] = { static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(audio_clk), SH_PFC_FUNCTION(avb), + SH_PFC_FUNCTION(can0), + SH_PFC_FUNCTION(can1), + SH_PFC_FUNCTION(can_clk), SH_PFC_FUNCTION(drif0), SH_PFC_FUNCTION(drif1), SH_PFC_FUNCTION(drif2), -- 2.12.2
[PATCH 2/2] pinctrl: sh-pfc: r8a7795: Add CAN FD support
This patch adds CAN FD[0-1] pinmux support for R-Car H3 ES2.0. The pin config is identical to H3 ES1.*. Signed-off-by: Ramesh ShanmugasundaramReviewed-by: Fabrizio Castro --- drivers/pinctrl/sh-pfc/pfc-r8a7795.c | 37 1 file changed, 37 insertions(+) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c index 59249a990cef..34a2dc471e5a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c @@ -1813,6 +1813,29 @@ static const unsigned int can_clk_mux[] = { CAN_CLK_MARK, }; +/* - CAN FD --- */ +static const unsigned int canfd0_data_a_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 24), +}; +static const unsigned int canfd0_data_a_mux[] = { + CANFD0_TX_A_MARK, CANFD0_RX_A_MARK, +}; +static const unsigned int canfd0_data_b_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1), +}; +static const unsigned int canfd0_data_b_mux[] = { + CANFD0_TX_B_MARK, CANFD0_RX_B_MARK, +}; +static const unsigned int canfd1_data_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 26), +}; +static const unsigned int canfd1_data_mux[] = { + CANFD1_TX_MARK, CANFD1_RX_MARK, +}; + /* - DRIF0 --- */ static const unsigned int drif0_ctrl_a_pins[] = { /* CLK, SYNC */ @@ -3879,6 +3902,9 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(can0_data_b), SH_PFC_PIN_GROUP(can1_data), SH_PFC_PIN_GROUP(can_clk), + SH_PFC_PIN_GROUP(canfd0_data_a), + SH_PFC_PIN_GROUP(canfd0_data_b), + SH_PFC_PIN_GROUP(canfd1_data), SH_PFC_PIN_GROUP(drif0_ctrl_a), SH_PFC_PIN_GROUP(drif0_data0_a), SH_PFC_PIN_GROUP(drif0_data1_a), @@ -4203,6 +4229,15 @@ static const char * const can_clk_groups[] = { "can_clk", }; +static const char * const canfd0_groups[] = { + "canfd0_data_a", + "canfd0_data_b", +}; + +static const char * const canfd1_groups[] = { + "canfd1_data", +}; + static const char * const drif0_groups[] = { "drif0_ctrl_a", "drif0_data0_a", @@ -4611,6 +4646,8 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(can0), SH_PFC_FUNCTION(can1), SH_PFC_FUNCTION(can_clk), + SH_PFC_FUNCTION(canfd0), + SH_PFC_FUNCTION(canfd1), SH_PFC_FUNCTION(drif0), SH_PFC_FUNCTION(drif1), SH_PFC_FUNCTION(drif2), -- 2.12.2
[PATCH v10 1/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation
Documentation for Renesas R-Car MIPI CSI-2 receiver. The CSI-2 receivers are located between the video sources (CSI-2 transmitters) and the video grabbers (VIN) on Gen3 of Renesas R-Car SoC. Each CSI-2 device is connected to more then one VIN device which simultaneously can receive video from the same CSI-2 device. Each VIN device can also be connected to more then one CSI-2 device. The routing of which link are used are controlled by the VIN devices. There are only a few possible routes which are set by hardware limitations, which are different for each SoC in the Gen3 family. To work with the limitations of routing possibilities it is necessary for the DT bindings to describe which VIN device is connected to which CSI-2 device. This is why port 1 needs to to assign reg numbers for each VIN device that be connected to it. To setup and to know which links are valid for each SoC is the responsibility of the VIN driver since the register to configure it belongs to the VIN hardware. Signed-off-by: Niklas Söderlund--- .../devicetree/bindings/media/rcar-csi2.txt| 104 + MAINTAINERS| 1 + 2 files changed, 105 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/rcar-csi2.txt diff --git a/Documentation/devicetree/bindings/media/rcar-csi2.txt b/Documentation/devicetree/bindings/media/rcar-csi2.txt new file mode 100644 index ..24705d8997b14a10 --- /dev/null +++ b/Documentation/devicetree/bindings/media/rcar-csi2.txt @@ -0,0 +1,104 @@ +Renesas R-Car MIPI CSI-2 + + +The rcar-csi2 device provides MIPI CSI-2 capabilities for the Renesas R-Car +family of devices. It is to be used in conjunction with the R-Car VIN module, +which provides the video capture capabilities. + +Mandatory properties + + - compatible: Must be one or more of the following + - "renesas,r8a7795-csi2" for the R8A7795 device. + - "renesas,r8a7796-csi2" for the R8A7796 device. + + - reg: the register base and size for the device registers + - interrupts: the interrupt for the device + - clocks: Reference to the parent clock + +The device node shall contain two 'port' child nodes according to the +bindings defined in Documentation/devicetree/bindings/media/ +video-interfaces.txt. Port 0 shall connect the node that is the video +source for to the CSI-2. Port 1 shall connect all the R-Car VIN +modules, which can make use of the CSI-2 module. + +- Port 0 - Video source (Mandatory) + - Endpoint 0 - sub-node describing the endpoint that is the video source + +- Port 1 - VIN instances (Mandatory for all VIN present in the SoC) + - Endpoint 0 - sub-node describing the endpoint that is VIN0 + - Endpoint 1 - sub-node describing the endpoint that is VIN1 + - Endpoint 2 - sub-node describing the endpoint that is VIN2 + - Endpoint 3 - sub-node describing the endpoint that is VIN3 + - Endpoint 4 - sub-node describing the endpoint that is VIN4 + - Endpoint 5 - sub-node describing the endpoint that is VIN5 + - Endpoint 6 - sub-node describing the endpoint that is VIN6 + - Endpoint 7 - sub-node describing the endpoint that is VIN7 + +Example: + + csi20: csi2@fea8 { + compatible = "renesas,r8a7796-csi2", "renesas,rcar-gen3-csi2"; + reg = <0 0xfea8 0 0x1>; + interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + clocks = < CPG_MOD 714>; + power-domains = < R8A7796_PD_ALWAYS_ON>; + resets = < 714>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <0>; + + csi20_in: endpoint@0 { + clock-lanes = <0>; + data-lanes = <1>; + remote-endpoint = <_txb>; + }; + }; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + csi20vin0: endpoint@0 { + reg = <0>; + remote-endpoint = <>; + }; + csi20vin1: endpoint@1 { + reg = <1>; + remote-endpoint = <>; + }; + csi20vin2: endpoint@2 { + reg = <2>; +
[PATCH v10 2/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver
A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver supports the rcar-vin driver on 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--- drivers/media/platform/rcar-vin/Kconfig | 12 + drivers/media/platform/rcar-vin/Makefile| 1 + drivers/media/platform/rcar-vin/rcar-csi2.c | 934 3 files changed, 947 insertions(+) create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig index af4c98b44d2e22cb..6875f30c1ae42631 100644 --- a/drivers/media/platform/rcar-vin/Kconfig +++ b/drivers/media/platform/rcar-vin/Kconfig @@ -1,3 +1,15 @@ +config VIDEO_RCAR_CSI2 + tristate "R-Car MIPI CSI-2 Receiver" + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF + depends on ARCH_RENESAS || COMPILE_TEST + select V4L2_FWNODE + ---help--- + Support for Renesas R-Car MIPI CSI-2 receiver. + Supports R-Car Gen3 SoCs. + + To compile this driver as a module, choose M here: the + module will be called rcar-csi2. + config VIDEO_RCAR_VIN tristate "R-Car Video Input (VIN) Driver" depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && MEDIA_CONTROLLER diff --git a/drivers/media/platform/rcar-vin/Makefile b/drivers/media/platform/rcar-vin/Makefile index 48c5632c21dc060b..5ab803d3e7c1aa57 100644 --- a/drivers/media/platform/rcar-vin/Makefile +++ b/drivers/media/platform/rcar-vin/Makefile @@ -1,3 +1,4 @@ rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o 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 ..27d09da191a09b39 --- /dev/null +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -0,0 +1,934 @@ +/* + * Driver for Renesas R-Car MIPI CSI-2 Receiver + * + * Copyright (C) 2017 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Register offsets and bits */ + +/* Control Timing Select */ +#define TREF_REG 0x00 +#define TREF_TREF BIT(0) + +/* Software Reset */ +#define SRST_REG 0x04 +#define SRST_SRST BIT(0) + +/* PHY Operation Control */ +#define PHYCNT_REG 0x08 +#define PHYCNT_SHUTDOWNZ BIT(17) +#define PHYCNT_RSTZBIT(16) +#define PHYCNT_ENABLECLK BIT(4) +#define PHYCNT_ENABLE_3BIT(3) +#define PHYCNT_ENABLE_2BIT(2) +#define PHYCNT_ENABLE_1BIT(1) +#define PHYCNT_ENABLE_0BIT(0) + +/* Checksum Control */ +#define CHKSUM_REG 0x0c +#define CHKSUM_ECC_EN BIT(1) +#define CHKSUM_CRC_EN BIT(0) + +/* + * Channel Data Type Select + * VCDT[0-15]: Channel 1 VCDT[16-31]: Channel 2 + * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4 + */ +#define VCDT_REG 0x10 +#define VCDT2_REG 0x14 +#define VCDT_VCDTN_EN BIT(15) +#define VCDT_SEL_VC(n) (((n) & 0x3) << 8) +#define VCDT_SEL_DTN_ONBIT(6) +#define VCDT_SEL_DT(n) (((n) & 0x3f) << 0) + +/* Frame Data Type Select */ +#define FRDT_REG 0x18 + +/* Field Detection Control */ +#define FLD_REG0x1c +#define FLD_FLD_NUM(n) (((n) & 0xff) << 16) +#define FLD_FLD_EN4BIT(3) +#define FLD_FLD_EN3BIT(2) +#define FLD_FLD_EN2BIT(1) +#define FLD_FLD_EN BIT(0) + +/* Automatic Standby Control */ +#define ASTBY_REG 0x20 + +/* Long Data Type Setting 0 */ +#define LNGDT0_REG 0x28 + +/* Long Data Type Setting 1 */ +#define LNGDT1_REG 0x2c + +/* Interrupt Enable */ +#define INTEN_REG 0x30 + +/* Interrupt Source Mask */ +#define INTCLOSE_REG 0x34 + +/* Interrupt Status Monitor */ +#define INTSTATE_REG 0x38 +#define INTSTATE_INT_ULPS_STARTBIT(7) +#define INTSTATE_INT_ULPS_END
[PATCH v10 0/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2
Hi, This is the latest incarnation of R-Car MIPI CSI-2 receiver driver. It's based on top of the media-tree and are tested on Renesas Salvator-X together with the out-of-tree patches for rcar-vin to add support for Gen3 VIN. If anyone is interested to test video grabbing using these out of tree patches please see [1]. * Changes since v9 - Add reset property to device tree example - Use BIT(x) instead of (1 << x) - Use u16 in struct phypll_hsfreqrange to pack struct better. - Use unsigned int type for loop variable in rcar_csi2_code_to_fmt - Move fields inside struct struct rcar_csi2_info and struct rcar_csi2 to pack struct's tighter. - Use %u instead of %d when printing __u32. - Don't check return of platform_get_resource(), let devm_ioremap_resource() handle it. - Store quirk workaround for r8a7795 ES1.0 in the data field of struct soc_device_attribute. Changes since v8: - Updated bindings documentation, thanks Rob! - Make use of the now in media-tree sub-notifier V4L2 API - Add delay when resetting the IP to allow for a proper reset - Fix bug in s_stream error path where the usage count was off if an error was hit. - Add support for H3 ES2.0 Changes since v7: - Rebase on top of the latest incremental async patches. - Fix comments on DT documentation. - Use v4l2_ctrl_g_ctrl_int64() instead of v4l2_g_ext_ctrls(). - Handle try formats in .set_fmt() and .get_fmt(). - Don't call v4l2_device_register_subdev_nodes() as this is not needed with the complete() callbacks synchronized. - Fix line over 80 chars. - Fix varies spelling mistakes. Changes since v6: - Rebased on top of Sakaris fwnode patches. - Changed of RCAR_CSI2_PAD_MAX to NR_OF_RCAR_CSI2_PAD. - Remove assumption about unknown media bus type, thanks Sakari for pointing this out. - Created table for supported format information instead of scattering this information around the driver, thanks Sakari! - Small newline fixes and reduce some indentation levels. Changes since v5: - Make use of the incremental async subnotifer and helper to map DT endpoint to media pad number. This moves functionality which previously in the Gen3 patches for R-Car VIN driver to this R-Car CSI-2 driver. This is done in preparation to support the ADV7482 driver in development by Kieran which will register more then one subdevice and the CSI-2 driver needs to cope wit this. Further more it prepares the driver for another use-case where more then one subdevice is present upstream for the CSI-2. - Small cleanups. - Add explicit include for linux/io.h, thanks Kieran. Changes since v4: - Match SoC part numbers and drop trailing space in documentation, thanks Geert for pointing this out. - Clarify that the driver is a CSI-2 receiver by supervised s/interface/receiver/, thanks Laurent. - Add entries in Kconfig and Makefile alphabetically instead of append. - Rename struct rcar_csi2 member swap to lane_swap. - Remove macros to wrap calls to dev_{dbg,info,warn,err}. - Add wrappers for ioread32 and iowrite32. - Remove unused interrupt handler, but keep checking in probe that there are a interrupt define in DT. - Rework how to wait for LP-11 state, thanks Laurent for the great idea! - Remove unneeded delay in rcar_csi2_reset() - Remove check for duplicated lane id:s from DT parsing. Broken out to a separate patch adding this check directly to v4l2_of_parse_endpoint(). - Fixed rcar_csi2_start() to ask it's source subdevice for information about pixel rate and frame format. With this change having {set,get}_fmt operations became redundant, it was only used for figuring out this out so dropped them. - Tabulated frequency settings map. - Dropped V4L2_SUBDEV_FL_HAS_DEVNODE it should never have been set. - Switched from MEDIA_ENT_F_ATV_DECODER to MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER as entity function. I can't find a more suitable function, and what the hardware do is to fetch video from an external chip and passes it on to a another SoC internal IP it's sort of a formatter. - Break out DT documentation and code in two patches. Changes since v3: - Update DT binding documentation with input from Geert Uytterhoeven, thanks! Changes since v2: - Added media control pads as this is needed by the new rcar-vin driver. - Update DT bindings after review comments and to add r8a7796 support. - Add get_fmt handler. - Fix media bus format error s/YUYV8/UYVY8/ Changes since v1: - Drop dependency on a pad aware s_stream operation. - Use the DT bindings format "renesas,-", thanks Geert for pointing this out. 1. http://elinux.org/R-Car/Tests:rcar-vin Niklas Söderlund (2): media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver .../devicetree/bindings/media/rcar-csi2.txt| 104 +++ MAINTAINERS| 1 + drivers/media/platform/rcar-vin/Kconfig| 12 + drivers/media/platform/rcar-vin/Makefile |
Re: [PATCH] i2c: sh_mobile: send STOP according to datasheet
Hi Wolfram, On 2017-11-10 12:52:10 +0100, Wolfram Sang wrote: > We initiate STOP (or REP_START) on the second last WAIT interrupt > currently. This works fine but is not according to the datasheet which > says to do it on the last WAIT interrupt. This also simplifies the code > quite a lot, so let's do it. I like this change and I checked the flow diagrams in chapter '56.4 Operation' of the Gen2 datasheet rev 2.0 and chapter '58.3 Operation' of the Gen3 datasheet rev 0.80, and it makes sens for both. > > Signed-off-by: Wolfram SangFor Gen2 and Gen3: Reviewed-by: Niklas Söderlund > --- > > Jacopo: another one to test, pretty please. > > drivers/i2c/busses/i2c-sh_mobile.c | 29 ++--- > 1 file changed, 6 insertions(+), 23 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-sh_mobile.c > b/drivers/i2c/busses/i2c-sh_mobile.c > index 40a66d466c3c49..c904be631db302 100644 > --- a/drivers/i2c/busses/i2c-sh_mobile.c > +++ b/drivers/i2c/busses/i2c-sh_mobile.c > @@ -40,21 +40,21 @@ > /* BUS: S A8 ACK P(*) > */ > /* IRQ: DTE WAIT > */ > /* ICIC: > */ > -/* ICCR: 0x94 0x90 > */ > +/* ICCR: 0x94 0x90 > */ > /* ICDR: A8 > */ > /* > */ > /* 1 byte transmit > */ > /* BUS: S A8 ACK D8(1) ACK P(*) > */ > /* IRQ: DTE WAIT WAIT > */ > /* ICIC: -DTE > */ > -/* ICCR: 0x94 0x90 > */ > +/* ICCR: 0x940x90 > */ > /* ICDR: A8D8(1) > */ > /* > */ > /* 2 byte transmit > */ > /* BUS: S A8 ACK D8(1) ACK D8(2) ACK P(*) > */ > /* IRQ: DTE WAIT WAIT WAIT > */ > /* ICIC: -DTE > */ > -/* ICCR: 0x940x90 > */ > +/* ICCR: 0x94 0x90 > */ > /* ICDR: A8D8(1)D8(2) > */ > /* > */ > /* 3 bytes or more, +-+ gets repeated > */ > @@ -113,7 +113,6 @@ enum sh_mobile_i2c_op { > OP_TX_FIRST, > OP_TX, > OP_TX_STOP, > - OP_TX_STOP_DATA, > OP_TX_TO_RX, > OP_RX, > OP_RX_STOP, > @@ -319,10 +318,7 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data > *pd, > case OP_TX: /* write data */ > iic_wr(pd, ICDR, data); > break; > - case OP_TX_STOP_DATA: /* write data and issue a stop afterwards */ > - iic_wr(pd, ICDR, data); > - /* fallthrough */ > - case OP_TX_STOP: /* issue a stop */ > + case OP_TX_STOP: /* issue a stop (or rep_start) */ > iic_wr(pd, ICCR, pd->send_stop ? ICCR_ICE | ICCR_TRS > : ICCR_ICE | ICCR_TRS | > ICCR_BBSY); > break; > @@ -356,11 +352,6 @@ static bool sh_mobile_i2c_is_first_byte(struct > sh_mobile_i2c_data *pd) > return pd->pos == -1; > } > > -static bool sh_mobile_i2c_is_last_byte(struct sh_mobile_i2c_data *pd) > -{ > - return pd->pos == pd->msg->len - 1; > -} > - > static void sh_mobile_i2c_get_data(struct sh_mobile_i2c_data *pd, > unsigned char *buf) > { > @@ -378,20 +369,12 @@ static int sh_mobile_i2c_isr_tx(struct > sh_mobile_i2c_data *pd) > unsigned char data; > > if (pd->pos == pd->msg->len) { > - /* Send stop if we haven't yet (DMA case) */ > - if (pd->send_stop && pd->stop_after_dma) > - i2c_op(pd, OP_TX_STOP, 0); > + i2c_op(pd, OP_TX_STOP, 0); > return 1; > } > > sh_mobile_i2c_get_data(pd, ); > - > - if (sh_mobile_i2c_is_last_byte(pd)) > - i2c_op(pd, OP_TX_STOP_DATA, data); > - else if (sh_mobile_i2c_is_first_byte(pd)) > - i2c_op(pd, OP_TX_FIRST, data); > - else > -
[PATCH v2 1/5] arm64: dts: renesas: r8a77970: sort includes
Sort includes used in r8a77970 DTS to improve maintainability and for consistency with other R-Car DTS files. Signed-off-by: Simon Horman--- arch/arm64/boot/dts/renesas/r8a77970.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi index 75d09f1724f0..8b97842aedb7 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -9,9 +9,9 @@ * kind, whether express or implied. */ -#include -#include #include +#include +#include / { compatible = "renesas,r8a77970"; -- 2.11.0
[PATCH v2 2/5] arm64: dts: renesas: r8a77970: Add IPMMU device nodes
Add r8a77970 IPMMU nodes and keep all disabled by default. Based on work for the r8a7796 by Magnus Damm Signed-off-by: Simon HormanReviewed-by: Geert Uytterhoeven --- v2 * Drop mostly redundant comments from nodes * Add power domains * Correct compat string used for IPMMU-DS1 * Added reviewed by tag from Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a77970.dtsi | 47 +++ 1 file changed, 47 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi index 8b97842aedb7..5f73ee2dfd6d 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -12,6 +12,7 @@ #include #include #include +#include / { compatible = "renesas,r8a77970"; @@ -134,6 +135,52 @@ #power-domain-cells = <1>; }; + ipmmu_vi0: mmu@febd { + compatible = "renesas,ipmmu-r8a77970"; + reg = <0 0xfebd 0 0x1000>; + renesas,ipmmu-main = <_mm 9>; + power-domains = < R8A77970_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_ir: mmu@ff8b { + compatible = "renesas,ipmmu-r8a77970"; + reg = <0 0xff8b 0 0x1000>; + renesas,ipmmu-main = <_mm 3>; + power-domains = < R8A77970_PD_A3IR>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_rt: mmu@ffc8 { + compatible = "renesas,ipmmu-r8a77970"; + reg = <0 0xffc8 0 0x1000>; + renesas,ipmmu-main = <_mm 7>; + power-domains = < R8A77970_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_ds1: mmu@e774 { + compatible = "renesas,ipmmu-r8a77970"; + reg = <0 0xe774 0 0x1000>; + renesas,ipmmu-main = <_mm 1>; + power-domains = < R8A77970_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_mm: mmu@e67b { + compatible = "renesas,ipmmu-r8a77970"; + reg = <0 0xe67b 0 0x1000>; + interrupts = , +; + power-domains = < R8A77970_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + intc_ex: interrupt-controller@e61c { compatible = "renesas,intc-ex-r8a77970", "renesas,irqc"; #interrupt-cells = <2>; -- 2.11.0
[PATCH v2 4/5] arm64: dts: renesas: r8a77970: Connect Ethernet-AVB to IPMMU-RT
Add IPMMU-RT to the Ethernet-AVB device node. Based on work by Magnus Damm for the r8a7795. Signed-off-by: Simon HormanReviewed-by: Geert Uytterhoeven --- v2 * Added reviewed by tag from Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a77970.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi index 108c6159c847..0f93484e650a 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -440,6 +440,7 @@ power-domains = < 32>; resets = < 812>; phy-mode = "rgmii-id"; + iommus = <_rt 3>; #address-cells = <1>; #size-cells = <0>; }; -- 2.11.0
[PATCH v2 5/7] arm64: dts: renesas: r8a7796: Point VSPI via FCPVI to IPMMU-VC0
Hook up the FCPVI devices to allow use of VSPI with IPMMU-VC0. Based on work for the r8a7795 by Magnus Damm. Signed-off-by: Simon HormanReviewed-by: Geert Uytterhoeven --- v2 * Added reviewed by tag from Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index efb80c554ad6..47250b0c9ee9 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -1883,6 +1883,7 @@ clocks = < CPG_MOD 611>; power-domains = < R8A7796_PD_A3VC>; resets = < 611>; + iommus = <_vc0 19>; }; vspd0: vsp@fea2 { -- 2.11.0
[PATCH v2 3/5] arm64: dts: renesas: r8a77970: Tie SYS-DMAC to IPMMU-DS1
Hook up r8a77970 DMAC nodes to the IPMMU. In particular SYS-DMAC1 and SYS-DMAC2 get tied to IPMMU-DS1. Based on work for the r8a7796 by Magnus Damm. Signed-off-by: Simon HormanReviewed-by: Geert Uytterhoeven --- v2 * Added reviewed by tag from Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a77970.dtsi | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi index 5f73ee2dfd6d..108c6159c847 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -224,6 +224,10 @@ resets = < 218>; #dma-cells = <1>; dma-channels = <8>; + iommus = <_ds1 0>, <_ds1 1>, + <_ds1 2>, <_ds1 3>, + <_ds1 4>, <_ds1 5>, + <_ds1 6>, <_ds1 7>; }; dmac2: dma-controller@e731 { @@ -248,6 +252,10 @@ resets = < 217>; #dma-cells = <1>; dma-channels = <8>; + iommus = <_ds1 16>, <_ds1 17>, + <_ds1 18>, <_ds1 19>, + <_ds1 20>, <_ds1 21>, + <_ds1 22>, <_ds1 23>; }; hscif0: serial@e654 { -- 2.11.0
[PATCH v2 4/7] arm64: dts: renesas: r8a7796: Point FDP1 via FCPF to IPMMU-VI0
Hook up the FCPF devices to allow use of FDP1 with IPMMU-VI0. Based on work by Magnus Damm for the r8a7795. Signed-off-by: Simon HormanReviewed-by: Geert Uytterhoeven --- v2 * Added reviewed by tag from Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index 8a67177cccd6..efb80c554ad6 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -1902,6 +1902,7 @@ clocks = < CPG_MOD 603>; power-domains = < R8A7796_PD_ALWAYS_ON>; resets = < 603>; + iommus = <_vi0 8>; }; vspd1: vsp@fea28000 { @@ -1921,6 +1922,7 @@ clocks = < CPG_MOD 602>; power-domains = < R8A7796_PD_ALWAYS_ON>; resets = < 602>; + iommus = <_vi0 9>; }; vspd2: vsp@fea3 { @@ -1940,6 +1942,7 @@ clocks = < CPG_MOD 601>; power-domains = < R8A7796_PD_ALWAYS_ON>; resets = < 601>; + iommus = <_vi0 10>; }; hdmi0: hdmi@fead { -- 2.11.0
[PATCH v2 6/7] arm64: dts: renesas: r8a7796: Connect Ethernet-AVB to IPMMU-DS0
Add IPMMU-DS0 to the Ethernet-AVB device node. Based on work by Magnus Damm for the r8a7795. Signed-off-by: Simon HormanReviewed-by: Geert Uytterhoeven --- v2 * Added reviewed by tag from Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index 47250b0c9ee9..530de7176a6f 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -916,6 +916,7 @@ power-domains = < R8A7796_PD_ALWAYS_ON>; resets = < 812>; phy-mode = "rgmii-txid"; + iommus = <_ds0 16>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; -- 2.11.0
[PATCH v2 0/5] arm64: dts: renesas: r8a77970: IPMMU upstream integration
This series adds DT nodes for IPMMU instances on r8a77970 together with connections to r8a77970 on-chip devices: SYS-DMAC and Ethernet-AVB. With these patches applied a white list enabled IPMMU driver may be used to check silicon revision and then enable IPMMU in the known working cases. The recommended test stack for this patchset is a merge of * The iommu/next branch of the vfio tree * renesas-devel-20171110-v4.14-rc8 tag of the renesas tree With the following applied: * [PATCH v4 0/3] iommu/ipmmu-vmsa: r8a7796 support V4 * [PATCH 0/2] iommu/ipmmu-vmsa: r8a779(70|95) support The final patch in the series enable IPMMU support for all IPMMU instances on r8a77970 that are used by IPMMU devices listed above. The DT binding for r8a77970 are been submitted (as part of the r8a779(70|95) series noted above) in conjunction with this patchset. This is based on work by Magnus Damm. Based on renesas-devel-20171110-v4.14-rc8 Changes since V1: * Drop mostly redundant comments from nodes * Add power domains * Correct compat string used for IPMMU-DS1 Simon Horman (5): arm64: dts: renesas: r8a77970: sort includes arm64: dts: renesas: r8a77970: Add IPMMU device nodes arm64: dts: renesas: r8a77970: Tie SYS-DMAC to IPMMU-DS1 arm64: dts: renesas: r8a77970: Connect Ethernet-AVB to IPMMU-RT arm64: dts: renesas: r8a77970: Enable IPMMU-DS1, RT and MM arch/arm64/boot/dts/renesas/r8a77970.dtsi | 57 +-- 1 file changed, 55 insertions(+), 2 deletions(-) -- 2.11.0
[PATCH v2 7/7] arm64: dts: renesas: r8a7796: Enable IPMMU-DS0, DS1, MP, VI0, VC0 and MM
From: Magnus DammEnable the r8a7795 device nodes for IPMMU-DS0, IPMMU-DS1, IPMMU-MP, IPMMU-VI0, IPMMU-VC0 and the shared IPMMU-MM device. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v2 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v1 [Simon Horman] * Enable IPMMU-MP, VI0 and VC0 v0 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 6 -- 1 file changed, 6 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index 530de7176a6f..0db69add3f74 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -363,7 +363,6 @@ renesas,ipmmu-main = <_mm 9>; power-domains = < R8A7796_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_vc0: mmu@fe6b { @@ -372,7 +371,6 @@ renesas,ipmmu-main = <_mm 8>; power-domains = < R8A7796_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_pv0: mmu@fd80 { @@ -426,7 +424,6 @@ renesas,ipmmu-main = <_mm 4>; power-domains = < R8A7796_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_ds0: mmu@e674 { @@ -434,7 +431,6 @@ reg = <0 0xe674 0 0x1000>; renesas,ipmmu-main = <_mm 0>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_ds1: mmu@e774 { @@ -443,7 +439,6 @@ renesas,ipmmu-main = <_mm 1>; power-domains = < R8A7796_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_mm: mmu@e67b { @@ -453,7 +448,6 @@ ; power-domains = < R8A7796_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; cpg: clock-controller@e615 { -- 2.11.0
[PATCH v5 15/15] arm64: dts: renesas: r8a7795-es1: Enable IPMMU-MP1
From: Magnus DammEnable the r8a7795 ES1.x device node for IPMMU-MP1. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] * Broke out of larger patch v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index 6713eeeab52a..29b52d89c78a 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -31,7 +31,6 @@ reg = <0 0xec68 0 0x1000>; renesas,ipmmu-main = <_mm 5>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_sy: mmu@e773 { -- 2.11.0
[PATCH v2 2/2] arm64: dts: renesas: r8a77995: Connect Ethernet-AVB to IPMMU-RT
Add IPMMU-RT to the Ethernet-AVB device node. Based on work by Magnus Damm for the r8a7795. Signed-off-by: Simon HormanReviewed-by: Geert Uytterhoeven --- v2 * Added reviewed by tag from Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a77995.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi index cbcd982542a3..7f269fbe44d1 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi @@ -389,6 +389,7 @@ power-domains = < R8A77995_PD_ALWAYS_ON>; resets = < 812>; phy-mode = "rgmii-txid"; + iommus = <_ds0 16>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; -- 2.11.0
[PATCH v5 13/15] arm64: dts: renesas: r8a7795: Connect SATA to IPMMU-HC
From: Magnus DammAdd IPMMU-HC to the SATA device node. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 0fd1d1ab97d2..f42387473a9c 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -1645,6 +1645,7 @@ power-domains = < R8A7795_PD_ALWAYS_ON>; resets = < 815>; status = "disabled"; + iommus = <_hc 2>; }; xhci0: usb@ee00 { -- 2.11.0
[PATCH v5 11/15] arm64: dts: renesas: r8a7795-es1: Point VSPI via FCPVI to IPMMU-VP
From: Magnus DammHook up the FCPVI devices to allow use of VSPI with IPMMU-VP. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] * Broke out of larger patch v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index b2d2f04c5e1c..6713eeeab52a 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -76,6 +76,7 @@ clocks = < CPG_MOD 609>; power-domains = < R8A7795_PD_A3VP>; resets = < 609>; + iommus = <_vp0 10>; }; vspd3: vsp@fea38000 { -- 2.11.0
[PATCH v2 3/7] arm64: dts: renesas: r8a7796: Tie Audio-DMAC to IPMMU-MP
Hook up r8a7796 Audio-DMAC nodes to the IPMMU-MP. Based on work for the r8a7795 by Magnus Damm. Signed-off-by: Simon HormanReviewed-by: Geert Uytterhoeven --- v2 * Added reviewed by tag from Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 16 1 file changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index 8ae481504dd4..8a67177cccd6 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -1326,6 +1326,14 @@ resets = < 502>; #dma-cells = <1>; dma-channels = <16>; + iommus = <_mp 0>, <_mp 1>, + <_mp 2>, <_mp 3>, + <_mp 4>, <_mp 5>, + <_mp 6>, <_mp 7>, + <_mp 8>, <_mp 9>, + <_mp 10>, <_mp 11>, + <_mp 12>, <_mp 13>, + <_mp 14>, <_mp 15>; }; audma1: dma-controller@ec72 { @@ -1360,6 +1368,14 @@ resets = < 501>; #dma-cells = <1>; dma-channels = <16>; + iommus = <_mp 16>, <_mp 17>, + <_mp 18>, <_mp 19>, + <_mp 20>, <_mp 21>, + <_mp 22>, <_mp 23>, + <_mp 24>, <_mp 25>, + <_mp 26>, <_mp 27>, + <_mp 28>, <_mp 29>, + <_mp 30>, <_mp 31>; }; usb_dmac0: dma-controller@e65a { -- 2.11.0
[PATCH v2 2/7] arm64: dts: renesas: r8a7796: Tie SYS-DMAC to IPMMU-DS0/1
From: Magnus DammHook up r8a7796 DMAC nodes to the IPMMUs. In particular SYS-DMAC0 gets tied to IPMMU-DS0, and SYS-DMAC1 and SYS-DMAC2 get tied to IPMMU-DS1. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v2 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v1 [Simon Horman] v0 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 24 1 file changed, 24 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index cb66b722ceb9..8ae481504dd4 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -1200,6 +1200,14 @@ resets = < 219>; #dma-cells = <1>; dma-channels = <16>; + iommus = <_ds0 0>, <_ds0 1>, + <_ds0 2>, <_ds0 3>, + <_ds0 4>, <_ds0 5>, + <_ds0 6>, <_ds0 7>, + <_ds0 8>, <_ds0 9>, + <_ds0 10>, <_ds0 11>, + <_ds0 12>, <_ds0 13>, + <_ds0 14>, <_ds0 15>; }; dmac1: dma-controller@e730 { @@ -1234,6 +1242,14 @@ resets = < 218>; #dma-cells = <1>; dma-channels = <16>; + iommus = <_ds1 0>, <_ds1 1>, + <_ds1 2>, <_ds1 3>, + <_ds1 4>, <_ds1 5>, + <_ds1 6>, <_ds1 7>, + <_ds1 8>, <_ds1 9>, + <_ds1 10>, <_ds1 11>, + <_ds1 12>, <_ds1 13>, + <_ds1 14>, <_ds1 15>; }; dmac2: dma-controller@e731 { @@ -1268,6 +1284,14 @@ resets = < 217>; #dma-cells = <1>; dma-channels = <16>; + iommus = <_ds1 16>, <_ds1 17>, + <_ds1 18>, <_ds1 19>, + <_ds1 20>, <_ds1 21>, + <_ds1 22>, <_ds1 23>, + <_ds1 24>, <_ds1 25>, + <_ds1 26>, <_ds1 27>, + <_ds1 28>, <_ds1 29>, + <_ds1 30>, <_ds1 31>; }; audma0: dma-controller@ec70 { -- 2.11.0
[PATCH v5 02/15] arm64: dts: renesas: r8a7795-es1: Add IPMMU device nodes
From: Magnus DammAdd r8a7795 ES1.x IPMMU nodes and keep all disabled by default. This is a follow-up to a patch that adds IPMMU device nodes that are common to r8a7795 ES1.x and ES2.0 Power domains are omitted as they appear to be undocumented. Signed-off-by: Magnus Damm Reviewed-by: Laurent Pinchart Signed-off-by: Simon Horman --- v5 [Simon Horman] * Added reviewed-by tag from Geert Uytterhoeven * Dropped somewhat redundant comments from nodes v4 [Simon Horman] * Broke out of larger patch v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 16 1 file changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index 246323eacb56..38b7cfb3b428 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -26,6 +26,22 @@ /delete-node/ mmu@fd96; /delete-node/ mmu@fd97; + ipmmu_mp1: mmu@ec68 { + compatible = "renesas,ipmmu-r8a7795"; + reg = <0 0xec68 0 0x1000>; + renesas,ipmmu-main = <_mm 5>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_sy: mmu@e773 { + compatible = "renesas,ipmmu-r8a7795"; + reg = <0 0xe773 0 0x1000>; + renesas,ipmmu-main = <_mm 8>; + #iommu-cells = <1>; + status = "disabled"; + }; + /delete-node/ usb-phy@ee0e0200; /delete-node/ usb@ee0e0100; /delete-node/ usb@ee0e; -- 2.11.0
[PATCH v5 14/15] arm64: dts: renesas: r8a7795: Enable IPMMU-VI0, VP1, DS0, DS1 and MM
From: Magnus DammEnable the r8a7795 device nodes for IPMMU-VI0, IPMMU-VP1, IPMMU-DS0, IPMMU-DS1 and the shared IPMMU-MM device. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Update changelog to reflect new IPMMU names * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] * Broke out of larger patch v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 5 - 1 file changed, 5 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index f42387473a9c..6aa00d9b1d50 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -427,7 +427,6 @@ renesas,ipmmu-main = <_mm 14>; power-domains = < R8A7795_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_vi1: mmu@febe { @@ -454,7 +453,6 @@ renesas,ipmmu-main = <_mm 17>; power-domains = < R8A7795_PD_A3VP>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_vc0: mmu@fe6b { @@ -544,7 +542,6 @@ renesas,ipmmu-main = <_mm 0>; power-domains = < R8A7795_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_ds1: mmu@e774 { @@ -553,7 +550,6 @@ renesas,ipmmu-main = <_mm 1>; power-domains = < R8A7795_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_mm: mmu@e67b { @@ -563,7 +559,6 @@ ; power-domains = < R8A7795_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; dmac0: dma-controller@e670 { -- 2.11.0
[PATCH v2 1/2] arm64: dts: renesas: r8a77995: Add IPMMU device nodes
Add r8a77995 IPMMU nodes and keep all disabled by default. Based on work for the r8a7795 and r8a7796 by Magnus Damm Signed-off-by: Simon HormanReviewed-by: Geert Uytterhoeven --- v2 * Drop mostly redundant comments from nodes * Added reviewed by tag from Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a77995.dtsi | 82 +++ 1 file changed, 82 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi index 788e3afae6e3..cbcd982542a3 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi @@ -108,6 +108,88 @@ interrupts = ; }; + ipmmu_vi0: mmu@febd { + compatible = "renesas,ipmmu-r8a77995"; + reg = <0 0xfebd 0 0x1000>; + renesas,ipmmu-main = <_mm 14>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_vp0: mmu@fe99 { + compatible = "renesas,ipmmu-r8a77995"; + reg = <0 0xfe99 0 0x1000>; + renesas,ipmmu-main = <_mm 16>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_vc0: mmu@fe6b { + compatible = "renesas,ipmmu-r8a77995"; + reg = <0 0xfe6b 0 0x1000>; + renesas,ipmmu-main = <_mm 12>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_pv0: mmu@fd80 { + compatible = "renesas,ipmmu-r8a77995"; + reg = <0 0xfd80 0 0x1000>; + renesas,ipmmu-main = <_mm 6>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_hc: mmu@e657 { + compatible = "renesas,ipmmu-r8a77995"; + reg = <0 0xe657 0 0x1000>; + renesas,ipmmu-main = <_mm 2>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_rt: mmu@ffc8 { + compatible = "renesas,ipmmu-r8a77995"; + reg = <0 0xffc8 0 0x1000>; + renesas,ipmmu-main = <_mm 10>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_mp: mmu@ec67 { + compatible = "renesas,ipmmu-r8a77995"; + reg = <0 0xec67 0 0x1000>; + renesas,ipmmu-main = <_mm 4>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_ds0: mmu@e674 { + compatible = "renesas,ipmmu-r8a77995"; + reg = <0 0xe674 0 0x1000>; + renesas,ipmmu-main = <_mm 0>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_ds1: mmu@e774 { + compatible = "renesas,ipmmu-r8a77995"; + reg = <0 0xe774 0 0x1000>; + renesas,ipmmu-main = <_mm 1>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_mm: mmu@e67b { + compatible = "renesas,ipmmu-r8a77995"; + reg = <0 0xe67b 0 0x1000>; + interrupts = , +; + #iommu-cells = <1>; + status = "disabled"; + }; + + cpg: clock-controller@e615 { compatible = "renesas,r8a77995-cpg-mssr"; reg = <0 0xe615 0 0x1000>; -- 2.11.0
[PATCH v2 0/7] arm64: dts: renesas: r8a7796: IPMMU upstream integration
This series adds DT nodes for IPMMU instances on r8a7796 together with connections to various r8a7796 on-chip devices such as Audio-DMAC, SYS-DMAC, Ethernet-AVB and a bunch of multimedia devices that make use of FCP. With these patches applied a white list enabled IPMMU driver may be used to check silicon revision and then enable IPMMU in the known working cases. The recommended test stack for this patchset is a merge of * The iommu/next branch of the vfio tree * renesas-devel-20171110-v4.14-rc8 tag of the renesas tree With the following applied: [PATCH v4 0/3] iommu/ipmmu-vmsa: r8a7796 support V4 The final patch in the series enable IPMMU support for all IPMMU instances on r8a7796 that are used by IPMMU devices listed above. The DT binding for r8a7796 have been acked (as part of the r8a7796 series noted above) but have not yet been merged. Changes since V1: * Drop mostly redundant comments from nodes * Add power domains Based on work by Magnus Damm. Based on renesas-devel-20171110-v4.14-rc8 Magnus Damm (3): arm64: dts: renesas: r8a7796: Add IPMMU device nodes arm64: dts: renesas: r8a7796: Tie SYS-DMAC to IPMMU-DS0/1 arm64: dts: renesas: r8a7796: Enable IPMMU-DS0, DS1, MP, VI0, VC0 and MM Simon Horman (4): arm64: dts: renesas: r8a7796: Tie Audio-DMAC to IPMMU-MP arm64: dts: renesas: r8a7796: Point FDP1 via FCPF to IPMMU-VI0 arm64: dts: renesas: r8a7796: Point VSPI via FCPVI to IPMMU-VC0 arm64: dts: renesas: r8a7796: Connect Ethernet-AVB to IPMMU-DS0 arch/arm64/boot/dts/renesas/r8a7796.dtsi | 138 +++ 1 file changed, 138 insertions(+) -- 2.11.0
[PATCH v5 06/15] arm64: dts: renesas: r8a7795-es1: Point DU/VSPD via FCPVD to IPMMU-VI0
From: Magnus DammHook up the FCPVD devices to allow use of the VSP and DU together with IPMMU-VI0. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] * broke out of a larger patch v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index 71499d193ddb..1eafa5382e86 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -94,6 +94,7 @@ clocks = < CPG_MOD 600>; power-domains = < R8A7795_PD_ALWAYS_ON>; resets = < 600>; + iommus = <_vi0 11>; }; fdp1@fe948000 { -- 2.11.0
[PATCH v5 00/15] arm64: dts: renesas: r8a7795: IPMMU upstream integration
This series adds DT nodes for IPMMU instances on r8a7795 together with connections to various r8a7795 on-chip devices such as Audio-DMAC, SYS-DMAC, Ethernet-AVB, SATA and a bunch of multimedia devices that make use of FCP. With these patches applied a white list enabled IPMMU driver may be used to check silicon revision and then enable IPMMU in the known working cases. The recommended test stack for this patchset is a merge of * The iommu/next branch of the vfio tree * renesas-devel-20171110-v4.14-rc8 tag of the renesas tree The final two patches in the series enable IPMMU support for all IPMMU instances on r8a7795 that are used by IPMMU devices listed above with one exception. The exception is the SATA device connected to IPMMU-HC which still is disabled pending IPMMU USB integration support. I expect IPMMU USB integration to be handled as a second step once this series is agreed on. The DT binding for r8a7795 has since long been included in mainline and this series implements support following such format: d4e42e7 iommu/ipmmu-vmsa: Add r8a7795 DT binding Changes since V4: - Correct ES1.x override for ipmmu_vc0 - Add ES1.x override for ipmmu_vc1 - Drop mostly redundant comments from nodes - Add power domains Changes since V3: - Rework to support ES2.0 - Other minor changes as noted in per-patch changelogs Changes since V2: - Added the iommus property before power domains - thanks Geert! - Added reviewed-by to patch 2 and 3 from Laurent - thanks! - Re-added Ethernet and FCPVD patches (They were present in V1 but not V2) - Added remaining FCP devices such as FCPF, FCPVB and FCPVI - Added SATA device - Added final patch to enable various IPMMU devices in the DTS file Since the DT binding has been merged quite some time ago and the interface seems stable enough I see no reason not to queue these up for upstream merge. This is a minor rework of work by Magnus Damm. Based on renesas-devel-20171110-v4.14-rc8 Magnus Damm (15): arm64: dts: renesas: r8a7795: Add IPMMU device nodes arm64: dts: renesas: r8a7795-es1: Add IPMMU device nodes arm64: dts: renesas: r8a7795: Tie SYS-DMAC to IPMMU-DS0/1 arm64: dts: renesas: r8a7795: Tie Audio-DMAC to IPMMU-MP0/1 arm64: dts: renesas: r8a7795: Point DU/VSPD via FCPVD to IPMMU-VI0/1 arm64: dts: renesas: r8a7795-es1: Point DU/VSPD via FCPVD to IPMMU-VI0 arm64: dts: renesas: r8a7795: Point FDP1 via FCPF to IPMMU-VP0/1 arm64: dts: renesas: r8a7795-es1: Point FDP1 via FCPF to IPMMU-VP0 arm64: dts: renesas: r8a7795: Point VSPBC/VSPBD via FCPVB to IPMMU-VP0/1 arm64: dts: renesas: r8a7795: Point VSPI via FCPVI to IPMMU-VP0/1 arm64: dts: renesas: r8a7795-es1: Point VSPI via FCPVI to IPMMU-VP arm64: dts: renesas: r8a7795: Connect Ethernet-AVB to IPMMU-DS0 arm64: dts: renesas: r8a7795: Connect SATA to IPMMU-HC arm64: dts: renesas: r8a7795: Enable IPMMU-VI0, VP1, DS0, DS1 and MM arm64: dts: renesas: r8a7795-es1: Enable IPMMU-MP1 arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 81 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 191 +++ 2 files changed, 272 insertions(+) -- 2.11.0
[PATCH v2 5/5] arm64: dts: renesas: r8a77970: Enable IPMMU-DS1, RT and MM
Enable the r8a77970 device nodes for IPMMU-DS1, IPMMU-RT and the shared IPMMU-MM device. Based on work for the r8a7796 by Magnus Damm. Signed-off-by: Simon HormanReviewed-by: Geert Uytterhoeven --- v2 * Added reviewed by tag from Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a77970.dtsi | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi index 0f93484e650a..636b57a2edde 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -159,7 +159,6 @@ renesas,ipmmu-main = <_mm 7>; power-domains = < R8A77970_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_ds1: mmu@e774 { @@ -168,7 +167,6 @@ renesas,ipmmu-main = <_mm 1>; power-domains = < R8A77970_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; ipmmu_mm: mmu@e67b { @@ -178,7 +176,6 @@ ; power-domains = < R8A77970_PD_ALWAYS_ON>; #iommu-cells = <1>; - status = "disabled"; }; intc_ex: interrupt-controller@e61c { -- 2.11.0
[PATCH v2 0/2] dts: renesas: r8a77995: IPMMU upstream integration
This series adds DT nodes for IPMMU instances on r8a77995 together with connections to the r8a77995 on-chip device Ethernet-AVB. With these patches applied a white list enabled IPMMU driver may be used to check silicon revision and then enable IPMMU in the known working cases. The recommended test stack for this patchset is a merge of * The iommu/next branch of the vfio tree * renesas-devel-20171110-v4.14-rc8 tag of the renesas tree With the following applied: [PATCH v4 0/3] iommu/ipmmu-vmsa: r8a7796 support V4 [PATCH 0/2] iommu/ipmmu-vmsa: r8a779(70|95) support A patch to enable IPMMU devices is not included in this series as Ethernet-AVB, the only device to which IPMMU is hooked up to, is disabled. The DT binding for r8a77995 has been submitted (as part of the r8a779(70|95) series noted above) in conjunction with this patchset. This is based on work by Magnus Damm. Based on renesas-devel-20171110-v4.14-rc8 Changes since V1: * Drop mostly redundant comments from nodes Simon Horman (2): arm64: dts: renesas: r8a77995: Add IPMMU device nodes arm64: dts: renesas: r8a77995: Connect Ethernet-AVB to IPMMU-RT arch/arm64/boot/dts/renesas/r8a77995.dtsi | 83 +++ 1 file changed, 83 insertions(+) -- 2.11.0 Simon Horman (2): arm64: dts: renesas: r8a77995: Add IPMMU device nodes arm64: dts: renesas: r8a77995: Connect Ethernet-AVB to IPMMU-RT arch/arm64/boot/dts/renesas/r8a77995.dtsi | 83 +++ 1 file changed, 83 insertions(+) -- 2.11.0
[PATCH v5 10/15] arm64: dts: renesas: r8a7795: Point VSPI via FCPVI to IPMMU-VP0/1
From: Magnus DammHook up the FCPVI devices to allow use of VSPI with IPMMU-VP0 and IPMMU-VP1. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] * broke out of larger patch * Use IPMMU-VP1 for FCPVI1 on ES2.0 v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 4 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 2 ++ 2 files changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index 3d50627c0670..b2d2f04c5e1c 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -159,6 +159,10 @@ iommus = <_vp0 1>; }; + { + iommus = <_vp0 9>; +}; + { iommus = <_vi0 10>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index cf9708ac46eb..851324eac5ed 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -2120,6 +2120,7 @@ clocks = < CPG_MOD 611>; power-domains = < R8A7795_PD_A3VP>; resets = < 611>; + iommus = <_vp0 8>; }; vspi1: vsp@fe9b { @@ -2139,6 +2140,7 @@ clocks = < CPG_MOD 610>; power-domains = < R8A7795_PD_A3VP>; resets = < 610>; + iommus = <_vp1 9>; }; vspd0: vsp@fea2 { -- 2.11.0
[PATCH v2 1/7] arm64: dts: renesas: r8a7796: Add IPMMU device nodes
From: Magnus DammAdd r8a7796 IPMMU nodes and keep all disabled by default. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- v2 [Simon Horman] * Drop mostly redundant comments from nodes * Add power domains v4 [Simon Horman] * Update node names as per recent datasheet naming v0 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 99 1 file changed, 99 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index 8c94a313d9e1..cb66b722ceb9 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -357,6 +357,105 @@ <_3>; }; + ipmmu_vi0: mmu@febd { + compatible = "renesas,ipmmu-r8a7796"; + reg = <0 0xfebd 0 0x1000>; + renesas,ipmmu-main = <_mm 9>; + power-domains = < R8A7796_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_vc0: mmu@fe6b { + compatible = "renesas,ipmmu-r8a7796"; + reg = <0 0xfe6b 0 0x1000>; + renesas,ipmmu-main = <_mm 8>; + power-domains = < R8A7796_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_pv0: mmu@fd80 { + compatible = "renesas,ipmmu-r8a7796"; + reg = <0 0xfd80 0 0x1000>; + renesas,ipmmu-main = <_mm 5>; + power-domains = < R8A7796_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_pv1: mmu@fd95 { + compatible = "renesas,ipmmu-r8a7796"; + reg = <0 0xfd95 0 0x1000>; + renesas,ipmmu-main = <_mm 6>; + power-domains = < R8A7796_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_ir: mmu@ff8b { + compatible = "renesas,ipmmu-r8a7796"; + reg = <0 0xff8b 0 0x1000>; + renesas,ipmmu-main = <_mm 3>; + power-domains = < R8A7796_PD_A3IR>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_hc: mmu@e657 { + compatible = "renesas,ipmmu-r8a7796"; + reg = <0 0xe657 0 0x1000>; + renesas,ipmmu-main = <_mm 2>; + power-domains = < R8A7796_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_rt: mmu@ffc8 { + compatible = "renesas,ipmmu-r8a7796"; + reg = <0 0xffc8 0 0x1000>; + renesas,ipmmu-main = <_mm 7>; + power-domains = < R8A7796_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_mp: mmu@ec67 { + compatible = "renesas,ipmmu-r8a7796"; + reg = <0 0xec67 0 0x1000>; + renesas,ipmmu-main = <_mm 4>; + power-domains = < R8A7796_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_ds0: mmu@e674 { + compatible = "renesas,ipmmu-r8a7796"; + reg = <0 0xe674 0 0x1000>; + renesas,ipmmu-main = <_mm 0>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_ds1: mmu@e774 { + compatible = "renesas,ipmmu-r8a7796"; + reg = <0 0xe774 0 0x1000>; + renesas,ipmmu-main = <_mm 1>; + power-domains = < R8A7796_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_mm: mmu@e67b { + compatible = "renesas,ipmmu-r8a7796"; + reg = <0 0xe67b 0 0x1000>; + interrupts = , +; + power-domains = < R8A7796_PD_ALWAYS_ON>; + #iommu-cells = <1>; +
[PATCH v5 04/15] arm64: dts: renesas: r8a7795: Tie Audio-DMAC to IPMMU-MP0/1
From: Magnus DammHook up r8a7795 ES2.0 Audio-DMAC nodes to the IPMMU-MP0. Hook up r8a7795 ES1.x Audio-DMAC nodes to the IPMMU-MP1. Signed-off-by: Magnus Damm Reviewed-by: Laurent Pinchart Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] * Broke out of larger patch * Use IPMMU-MP0 rather than IPMMU-MP1 for ES2.0 * Added reviewed by tag from Laurent Pinchart v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 22 ++ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 16 2 files changed, 38 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index 38b7cfb3b428..2dfe8108072c 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -127,6 +127,28 @@ renesas,ipmmu-main = <_mm 7>; }; + { + iommus = <_mp1 0>, <_mp1 1>, + <_mp1 2>, <_mp1 3>, + <_mp1 4>, <_mp1 5>, + <_mp1 6>, <_mp1 7>, + <_mp1 8>, <_mp1 9>, + <_mp1 10>, <_mp1 11>, + <_mp1 12>, <_mp1 13>, + <_mp1 14>, <_mp1 15>; +}; + + { + iommus = <_mp1 16>, <_mp1 17>, + <_mp1 18>, <_mp1 19>, + <_mp1 20>, <_mp1 21>, + <_mp1 22>, <_mp1 23>, + <_mp1 24>, <_mp1 25>, + <_mp1 26>, <_mp1 27>, + <_mp1 28>, <_mp1 29>, + <_mp1 30>, <_mp1 31>; +}; + { vsps = < >; }; diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index bff0e3a3e582..b13176feec89 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -724,6 +724,14 @@ resets = < 502>; #dma-cells = <1>; dma-channels = <16>; + iommus = <_mp0 0>, <_mp0 1>, + <_mp0 2>, <_mp0 3>, + <_mp0 4>, <_mp0 5>, + <_mp0 6>, <_mp0 7>, + <_mp0 8>, <_mp0 9>, + <_mp0 10>, <_mp0 11>, + <_mp0 12>, <_mp0 13>, + <_mp0 14>, <_mp0 15>; }; audma1: dma-controller@ec72 { @@ -758,6 +766,14 @@ resets = < 501>; #dma-cells = <1>; dma-channels = <16>; + iommus = <_mp0 16>, <_mp0 17>, + <_mp0 18>, <_mp0 19>, + <_mp0 20>, <_mp0 21>, + <_mp0 22>, <_mp0 23>, + <_mp0 24>, <_mp0 25>, + <_mp0 26>, <_mp0 27>, + <_mp0 28>, <_mp0 29>, + <_mp0 30>, <_mp0 31>; }; avb: ethernet@e680 { -- 2.11.0
[PATCH v5 07/15] arm64: dts: renesas: r8a7795: Point FDP1 via FCPF to IPMMU-VP0/1
From: Magnus DammHook up the FCPF devices to allow use of FDP1 with IPMMU-VP. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] * Broke out of larger patch * Use IPMMU-VP1 for FCPF1 on ES2.0 v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 4 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 2 ++ 2 files changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index 1eafa5382e86..6b4dfa42f5b2 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -150,6 +150,10 @@ <_mp1 30>, <_mp1 31>; }; + { + iommus = <_vp0 1>; +}; + { iommus = <_vi0 10>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index d5e3d208bc37..1202b84104a0 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -2070,6 +2070,7 @@ clocks = < CPG_MOD 615>; power-domains = < R8A7795_PD_A3VP>; resets = < 615>; + iommus = <_vp0 0>; }; fcpf1: fcp@fe951000 { @@ -2078,6 +2079,7 @@ clocks = < CPG_MOD 614>; power-domains = < R8A7795_PD_A3VP>; resets = < 614>; + iommus = <_vp1 1>; }; vspbd: vsp@fe96 { -- 2.11.0
[PATCH v5 08/15] arm64: dts: renesas: r8a7795-es1: Point FDP1 via FCPF to IPMMU-VP0
From: Magnus DammHook up the FCPF devices to allow use of FDP1 with IPMMU-VP0. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] * broke out of larger patch v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index 6b4dfa42f5b2..736281335653 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -56,6 +56,7 @@ clocks = < CPG_MOD 613>; power-domains = < R8A7795_PD_A3VP>; resets = < 613>; + iommus = <_vp0 2>; }; vspi2: vsp@fe9c { -- 2.11.0
[PATCH v5 03/15] arm64: dts: renesas: r8a7795: Tie SYS-DMAC to IPMMU-DS0/1
From: Magnus DammHook up r8a7795 SYS-DMAC nodes to the IPMMUs. In particular SYS-DMAC0 gets tied to IPMMU-DS0, and SYS-DMAC1 and SYS-DMAC2 get tied to IPMMU-DS1. Signed-off-by: Magnus Damm Reviewed-by: Laurent Pinchart Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] * Broke out of a larger patch * Added reviewed by tag from Laurent Pinchart v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 24 1 file changed, 24 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 469ce4081b29..bff0e3a3e582 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -598,6 +598,14 @@ resets = < 219>; #dma-cells = <1>; dma-channels = <16>; + iommus = <_ds0 0>, <_ds0 1>, + <_ds0 2>, <_ds0 3>, + <_ds0 4>, <_ds0 5>, + <_ds0 6>, <_ds0 7>, + <_ds0 8>, <_ds0 9>, + <_ds0 10>, <_ds0 11>, + <_ds0 12>, <_ds0 13>, + <_ds0 14>, <_ds0 15>; }; dmac1: dma-controller@e730 { @@ -632,6 +640,14 @@ resets = < 218>; #dma-cells = <1>; dma-channels = <16>; + iommus = <_ds1 0>, <_ds1 1>, + <_ds1 2>, <_ds1 3>, + <_ds1 4>, <_ds1 5>, + <_ds1 6>, <_ds1 7>, + <_ds1 8>, <_ds1 9>, + <_ds1 10>, <_ds1 11>, + <_ds1 12>, <_ds1 13>, + <_ds1 14>, <_ds1 15>; }; dmac2: dma-controller@e731 { @@ -666,6 +682,14 @@ resets = < 217>; #dma-cells = <1>; dma-channels = <16>; + iommus = <_ds1 16>, <_ds1 17>, + <_ds1 18>, <_ds1 19>, + <_ds1 20>, <_ds1 21>, + <_ds1 22>, <_ds1 23>, + <_ds1 24>, <_ds1 25>, + <_ds1 26>, <_ds1 27>, + <_ds1 28>, <_ds1 29>, + <_ds1 30>, <_ds1 31>; }; audma0: dma-controller@ec70 { -- 2.11.0
[PATCH v5 01/15] arm64: dts: renesas: r8a7795: Add IPMMU device nodes
From: Magnus DammAdd r8a7795 IPMMU nodes and keep all disabled by default. This includes all IPMMU devices for r8a7795 ES2.0. Those not present in r8a7795 ES1.x are removed from the DT for those SoCs using delete-node. A follow-up patch will add IPMMU devices to ES1.x which are not also present in ES2.0. Signed-off-by: Magnus Damm Reviewed-by: Laurent Pinchart Signed-off-by: Simon Horman --- v5 [Simon Horman] * Correct ES1.x override for ipmmu_vc0 * Add ES1.x override for ipmmu_vc1 * Drop mostly redundant comments from nodes * Add power domains * Consistently mark all nodes as disabled v4 [Simon Horman] * Add IPMMU-VI1, IPMMU-VP1 IPMMU-PV2 and IPMMU-PV3 * Rename IPMMU-VP as IPMMU-VP0 and IPMMU-VI as IPMMU-VI0 as per recent datasheet naming * Do not add IPMMU-MP1 or IPMMU-SY, these will be added to ES1.x by follow-up patch v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 25 + arch/arm64/boot/dts/renesas/r8a7795.dtsi | 145 +++ 2 files changed, 170 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index 655dd30639c5..246323eacb56 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -21,6 +21,11 @@ status = "disabled"; }; + /delete-node/ mmu@febe; + /delete-node/ mmu@fe98; + /delete-node/ mmu@fd96; + /delete-node/ mmu@fd97; + /delete-node/ usb-phy@ee0e0200; /delete-node/ usb@ee0e0100; /delete-node/ usb@ee0e; @@ -86,6 +91,26 @@ }; }; +_vi0 { + renesas,ipmmu-main = <_mm 11>; +}; + +_vp0 { + renesas,ipmmu-main = <_mm 12>; +}; + +_vc0 { + renesas,ipmmu-main = <_mm 9>; +}; + +_vc1 { + renesas,ipmmu-main = <_mm 10>; +}; + +_rt { + renesas,ipmmu-main = <_mm 7>; +}; + { vsps = < >; }; diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 42c51f2ec30b..469ce4081b29 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -421,6 +421,151 @@ resets = < 407>; }; + ipmmu_vi0: mmu@febd { + compatible = "renesas,ipmmu-r8a7795"; + reg = <0 0xfebd 0 0x1000>; + renesas,ipmmu-main = <_mm 14>; + power-domains = < R8A7795_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_vi1: mmu@febe { + compatible = "renesas,ipmmu-r8a7795"; + reg = <0 0xfebe 0 0x1000>; + renesas,ipmmu-main = <_mm 15>; + power-domains = < R8A7795_PD_ALWAYS_ON>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_vp0: mmu@fe99 { + compatible = "renesas,ipmmu-r8a7795"; + reg = <0 0xfe99 0 0x1000>; + renesas,ipmmu-main = <_mm 16>; + power-domains = < R8A7795_PD_A3VP>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_vp1: mmu@fe98 { + compatible = "renesas,ipmmu-r8a7795"; + reg = <0 0xfe98 0 0x1000>; + renesas,ipmmu-main = <_mm 17>; + power-domains = < R8A7795_PD_A3VP>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_vc0: mmu@fe6b { + compatible = "renesas,ipmmu-r8a7795"; + reg = <0 0xfe6b 0 0x1000>; + renesas,ipmmu-main = <_mm 12>; + power-domains = < R8A7795_PD_A3VP>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_vc1: mmu@fe6f { + compatible = "renesas,ipmmu-r8a7795"; + reg = <0 0xfe6f 0 0x1000>; + renesas,ipmmu-main = <_mm 13>; + power-domains = < R8A7795_PD_A3VP>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_pv0: mmu@fd80 { + compatible = "renesas,ipmmu-r8a7795"; + reg = <0 0xfd80 0 0x1000>; + renesas,ipmmu-main = <_mm 6>; + power-domains = < R8A7795_PD_ALWAYS_ON>; +
[PATCH v5 12/15] arm64: dts: renesas: r8a7795: Connect Ethernet-AVB to IPMMU-DS0
From: Magnus DammAdd IPMMU-DS0 to the Ethernet-AVB device node. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] v1 - v3 [Magnus Damm] --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 851324eac5ed..0fd1d1ab97d2 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -816,6 +816,7 @@ power-domains = < R8A7795_PD_ALWAYS_ON>; resets = < 812>; phy-mode = "rgmii-txid"; + iommus = <_ds0 16>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; -- 2.11.0
[PATCH v5 09/15] arm64: dts: renesas: r8a7795: Point VSPBC/VSPBD via FCPVB to IPMMU-VP0/1
From: Magnus DammHook up the FCPVB devices to allow use of VSPBC/VSPBD with IPMMU-VP0 and IPMMU-VP1. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- v5 [Simon Horman] * Added reviewed by tag from Geert Uytterhoeven v4 [Simon Horman] * Use IPMMU-VP1 for FCPVP1 on ES2.0 --- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 4 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 2 ++ 2 files changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index 736281335653..3d50627c0670 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -151,6 +151,10 @@ <_mp1 30>, <_mp1 31>; }; + { + iommus = <_vp0 7>; +}; + { iommus = <_vp0 1>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 1202b84104a0..cf9708ac46eb 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -2062,6 +2062,7 @@ clocks = < CPG_MOD 606>; power-domains = < R8A7795_PD_A3VP>; resets = < 606>; + iommus = <_vp1 7>; }; fcpf0: fcp@fe95 { @@ -2099,6 +2100,7 @@ clocks = < CPG_MOD 607>; power-domains = < R8A7795_PD_A3VP>; resets = < 607>; + iommus = <_vp0 5>; }; vspi0: vsp@fe9a { -- 2.11.0