Re: [PATCH mmc/next v3 0/4] mmc: renesas_sdhi: add support for R-Car Gen3 SDHI DMAC
> this series adds support for the internal DMAC used by r8a779[56] SoCs. > This is achieved by adding a new variant of the SDHI driver for this > DMA controller with compat strings for the r8a779[56] SoCs. > Compat strings for these SoCs are also removed from the existing SYS DMAC > variant of the SDHI driver. Okay, I tested some more today. My conclusion is that the series works so far. However, it quite often triggers a SDR50 retune with one card. And that sends an explicit CMD12 which we don't handle well. I always suspected the code to be imperfect, now I have a proof. So, that is a good thing but seems unrelated to this series to me. Another card does not retune and works flawlessly. I will sleep over it, re-test tomorrow and if my findings will get confirmed, then I'll give my Reviewed-by tags to this series. signature.asc Description: PGP signature
Re: [PATCH v6] media: platform: Renesas IMR driver
Hi Sergei, On Mon, Jun 26, 2017 at 9:56 PM, Sergei Shtylyovwrote: > On 06/26/2017 10:49 PM, Rob Herring wrote: >>> From: Konstantin Kozhevnikov >>> >>> The image renderer, or the distortion correction engine, is a drawing >>> processor with a simple instruction system capable of referencing video >>> capture data or data in an external memory as the 2D texture data and >>> performing texture mapping and drawing with respect to any shape that is >>> split into triangular objects. >>> >>> This V4L2 memory-to-memory device driver only supports image renderer >>> light >>> extended 4 (IMR-LX4) found in the R-Car gen3 SoCs; the R-Car gen2 support >>> can be added later... >>> >>> [Sergei: merged 2 original patches, added the patch description, removed [...] >>> macros.] >> >> >> TL;DR needed here IMO. > >Not sure I understand... stands for "too long; didn't read", right? > >> Not sure anyone really cares every detail you >> changed in re-writing this. If they did, it should all be separate >> commits. > >AFAIK this is a way that's things are dealt with when you submit somebody > else's work with your changes. Sorry if the list is too long... Based on a patch by Konstantin Kozhevnikov ? Of course, that's bad for your coworker's patch statistics... Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH v6] media: platform: Renesas IMR driver
Hello! On 06/26/2017 10:49 PM, Rob Herring wrote: From: Konstantin KozhevnikovThe image renderer, or the distortion correction engine, is a drawing processor with a simple instruction system capable of referencing video capture data or data in an external memory as the 2D texture data and performing texture mapping and drawing with respect to any shape that is split into triangular objects. This V4L2 memory-to-memory device driver only supports image renderer light extended 4 (IMR-LX4) found in the R-Car gen3 SoCs; the R-Car gen2 support can be added later... [Sergei: merged 2 original patches, added the patch description, removed unrelated parts, added the binding document and the UAPI documentation, ported the driver to the modern kernel, renamed the UAPI header file and the guard macros to match the driver name, extended the copyrights, fixed up Kconfig prompt/depends/help, made use of the BIT/GENMASK() macros, sorted #include's, replaced 'imr_ctx::crop' array with the 'imr_ctx::rect' structure, replaced imr_{g|s}_crop() with imr_{g|s}_selection(), completely rewrote imr_queue_setup(), removed 'imr_format_info::name', moved the applicable code from imr_buf_queue() to imr_buf_prepare() and moved the rest of imr_buf_queue() after imr_buf_finish(), assigned 'src_vq->dev' and 'dst_vq->dev' in imr_queue_init(), removed imr_start_streaming(), assigned 'src_vq->dev' and 'dst_vq->dev' in imr_queue_init(), clarified the math in imt_tri_type_{a|b|c}_length(), clarified the pointer math and avoided casts to 'void *' in imr_tri_set_type_{a|b|c}(), replaced imr_{reqbufs|querybuf| dqbuf|expbuf|streamon|streamoff}() with the generic helpers, implemented vidioc_{create_bufs|prepare_buf}() methods, used ALIGN() macro and merged the matrix size checks and replaced kmalloc()/copy_from_user() calls with memdup_user() call in imr_ioctl_map(), moved setting device capabilities from imr_querycap() to imr_probe(), set the valid default queue format in imr_probe(), removed leading dots and fixed grammar in the comments, fixed up the indentation to use tabs where possible, renamed DLSR, CMRCR. DY1{0|2}, and ICR bits to match the manual, changed the prefixes of the CMRCR[2]/TRI{M|C}R bits/fields to match the manual, removed non-existent TRIMR.D{Y|U}D{X|V}M bits, added/used the IMR/{UV|CP}DPOR/SUSR bits/fields/ shifts, separated the register offset/bit #define's, sorted instruction macros by opcode, removed unsupported LINE instruction, masked the register address in WTL[2]/WTS instruction macros, moved the display list #define's after the register #define's, removing the redundant comment, avoided setting reserved bits when writing CMRCCR[2]/TRIMCR, used the SR bits instead of a bare number, removed *inline* from .c file, fixed lines over 80 columns, removed useless spaces, comments, parens, operators, casts, braces, variables, #include's, statements, and even 1 function, added useful local variable, uppercased and spelled out the abbreviations, made comment wording more consistent/correct, fixed the comment typos, reformatted some multiline comments, inserted empty line after declaration, removed extra empty lines, reordered some local variable desclarations, removed calls to 4l2_err() on kmalloc() failure, replaced '*' with 'x' in some format strings for v4l2_dbg(), fixed the error returned by imr_default(), avoided code duplication in the IRQ handler, used '__packed' for the UAPI structures, declared 'imr_map_desc::data' as '__u64' instead of 'void *', switched to '__u{16|32}' in the UAPI header, enclosed the macro parameters in parens, exchanged the values of IMR_MAP_AUTO{S|D}G macros.] TL;DR needed here IMO. Not sure I understand... stands for "too long; didn't read", right? Not sure anyone really cares every detail you changed in re-writing this. If they did, it should all be separate commits. AFAIK this is a way that's things are dealt with when you submit somebody else's work with your changes. Sorry if the list is too long... Signed-off-by: Konstantin Kozhevnikov Signed-off-by: Sergei Shtylyov I acked v5 and it doesn't seem the binding changed. Sorry, I realized that I'd missed to collect you ACK just after sending v6... I believe there'll be v7 yet, so I'll finally collect it. Rob MBR, Sergei
Re: [PATCH v6] media: platform: Renesas IMR driver
On Fri, Jun 23, 2017 at 11:34:44PM +0300, Sergei Shtylyov wrote: > From: Konstantin Kozhevnikov> > The image renderer, or the distortion correction engine, is a drawing > processor with a simple instruction system capable of referencing video > capture data or data in an external memory as the 2D texture data and > performing texture mapping and drawing with respect to any shape that is > split into triangular objects. > > This V4L2 memory-to-memory device driver only supports image renderer light > extended 4 (IMR-LX4) found in the R-Car gen3 SoCs; the R-Car gen2 support > can be added later... > > [Sergei: merged 2 original patches, added the patch description, removed > unrelated parts, added the binding document and the UAPI documentation, > ported the driver to the modern kernel, renamed the UAPI header file and > the guard macros to match the driver name, extended the copyrights, fixed > up Kconfig prompt/depends/help, made use of the BIT/GENMASK() macros, > sorted #include's, replaced 'imr_ctx::crop' array with the 'imr_ctx::rect' > structure, replaced imr_{g|s}_crop() with imr_{g|s}_selection(), completely > rewrote imr_queue_setup(), removed 'imr_format_info::name', moved the > applicable code from imr_buf_queue() to imr_buf_prepare() and moved the > rest of imr_buf_queue() after imr_buf_finish(), assigned 'src_vq->dev' and > 'dst_vq->dev' in imr_queue_init(), removed imr_start_streaming(), assigned > 'src_vq->dev' and 'dst_vq->dev' in imr_queue_init(), clarified the math in > imt_tri_type_{a|b|c}_length(), clarified the pointer math and avoided casts > to 'void *' in imr_tri_set_type_{a|b|c}(), replaced imr_{reqbufs|querybuf| > dqbuf|expbuf|streamon|streamoff}() with the generic helpers, implemented > vidioc_{create_bufs|prepare_buf}() methods, used ALIGN() macro and merged > the matrix size checks and replaced kmalloc()/copy_from_user() calls with > memdup_user() call in imr_ioctl_map(), moved setting device capabilities > from imr_querycap() to imr_probe(), set the valid default queue format in > imr_probe(), removed leading dots and fixed grammar in the comments, fixed > up the indentation to use tabs where possible, renamed DLSR, CMRCR. > DY1{0|2}, and ICR bits to match the manual, changed the prefixes of the > CMRCR[2]/TRI{M|C}R bits/fields to match the manual, removed non-existent > TRIMR.D{Y|U}D{X|V}M bits, added/used the IMR/{UV|CP}DPOR/SUSR bits/fields/ > shifts, separated the register offset/bit #define's, sorted instruction > macros by opcode, removed unsupported LINE instruction, masked the register > address in WTL[2]/WTS instruction macros, moved the display list #define's > after the register #define's, removing the redundant comment, avoided > setting reserved bits when writing CMRCCR[2]/TRIMCR, used the SR bits > instead of a bare number, removed *inline* from .c file, fixed lines over > 80 columns, removed useless spaces, comments, parens, operators, casts, > braces, variables, #include's, statements, and even 1 function, added > useful local variable, uppercased and spelled out the abbreviations, > made comment wording more consistent/correct, fixed the comment typos, > reformatted some multiline comments, inserted empty line after declaration, > removed extra empty lines, reordered some local variable desclarations, > removed calls to 4l2_err() on kmalloc() failure, replaced '*' with 'x' > in some format strings for v4l2_dbg(), fixed the error returned by > imr_default(), avoided code duplication in the IRQ handler, used '__packed' > for the UAPI structures, declared 'imr_map_desc::data' as '__u64' instead > of 'void *', switched to '__u{16|32}' in the UAPI header, enclosed the > macro parameters in parens, exchanged the values of IMR_MAP_AUTO{S|D}G > macros.] TL;DR needed here IMO. Not sure anyone really cares every detail you changed in re-writing this. If they did, it should all be separate commits. > Signed-off-by: Konstantin Kozhevnikov > > Signed-off-by: Sergei Shtylyov I acked v5 and it doesn't seem the binding changed. Rob
Re: [PATCH 1/2] drm: rcar-du: Restrict DPLL duty cycle workaround to H3 ES1.x
Hi Laurent, On Wed, Jun 21, 2017 at 11:04 AM, Laurent Pinchartwrote: > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > @@ -158,6 +157,11 @@ static void rcar_du_dpll_divider(struct rcar_du_crtc > *rcrtc, > best_diff); > } > > +static const struct soc_device_attribute rcar_du_r8a7795_es1[] = { > + { .soc_id = "r8a7795", .revision = "ES1.*" }, > + { /* sentinel */ } > +}; > + > static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) > { > const struct drm_display_mode *mode = > >crtc.state->adjusted_mode; > @@ -185,7 +189,20 @@ static void rcar_du_crtc_set_display_timing(struct > rcar_du_crtc *rcrtc) > > extclk = clk_get_rate(rcrtc->extclock); > if (rcdu->info->dpll_ch & (1 << rcrtc->index)) { > - rcar_du_dpll_divider(rcrtc, , extclk, > mode_clock); > + unsigned long target = mode_clock; > + > + /* > +* The H3 ES1.x exhibits dot clock duty cycle > stability > +* issues. We can work around them by configuring the > +* DPLL to twice the desired frequency, coupled with a > +* /2 post-divider. This isn't needed on other SoCs > and > +* breaks HDMI output on M3-W for a currently unknown > +* reason, so restrict the workaround to H3 ES1.x. > +*/ > + if (soc_device_match(rcar_du_r8a7795_es1)) Matching is done over and over again, on every display enable/resume. Can it be done at probe time? Or in rcar_du_crtc_create(), which has access to rcrtc? > + target *= 2; You can also store the multiplier in rcar_du_r8a7795_es1.data (store 1 in .data of the sentinel), removing the need for an if clause. > + > + rcar_du_dpll_divider(rcrtc, , extclk, target); > extclk = dpll.output; Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH] dt-bindings: media: Add r8a7796 DRIF bindings
On Fri, Jun 23, 2017 at 10:25:02AM +0100, Ramesh Shanmugasundaram wrote: > Add r8a7796 DRIF bindings. > > Signed-off-by: Ramesh Shanmugasundaram >> --- > Hi DT & Media maintainers, All, > >This patch adds DRIF bindings for R8A7796 SoC. >It is based on media_tree - commit 76724b30f222 > > Thanks, > Ramesh. > > Documentation/devicetree/bindings/media/renesas,drif.txt | 1 + > 1 file changed, 1 insertion(+) Acked-by: Rob Herring
[GIT PULL FOR renesas-drivers] R-Car H3 ES2.0 display support, v2
Hi Geert, The following changes implement display support for the R-Car H3 ES2.0. They have been split in two distinct branches: - tags/drm-h3-es2-dt-20170626 contains the DT changes and is based on top of arm64-dt-for-v4.14 The following changes since commit cee30e674b8e54d3bf27eab26907e706f3304757: arm64: renesas: salvator-common: sound clock-frequency needs descending order (2017-06-16 15:37:51 +0200) are available in the git repository at: git://linuxtv.org/pinchartl/media.git tags/drm-h3-es2-dt-20170626 for you to fetch changes up to bcde4206f75575e825446dcd3a271741b997a483: arm64: dts: r8a7795: Add support for the DU (2017-06-26 14:17:32 +0300) Laurent Pinchart (2): drm: rcar-du: Add a VSP channel index to the vsps DT property arm64: dts: r8a7795: Add support for the DU .../devicetree/bindings/display/renesas,du.txt | 51 +--- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi| 1 - arch/arm64/boot/dts/renesas/r8a7795.dtsi| 2 + 3 files changed, 32 insertions(+), 22 deletions(-) - tags/drm-h3-es2-vsp-du-20170626 contains the VSP changes and is based on top of the latest DRM -next branch The following changes since commit 047b8e21e3bfa9faa4ed9a0c337fe0c687710251: Merge tag 'drm-misc-next-2017-06-19_0' of git://anongit.freedesktop.org/git/drm-misc into drm-next (2017-06-21 08:57:34 +1000) are available in the git repository at: git://linuxtv.org/pinchartl/media.git tags/drm-h3-es2-vsp-du-20170626 for you to fetch changes up to 8d09cbf4a12a4c79619c0edf23f9e219e29f5749: drm: rcar-du: Configure DPAD0 routing through last group on Gen3 (2017-06-26 19:08:54 +0300) Laurent Pinchart (14): v4l: vsp1: Fill display list headers without holding dlm spinlock v4l: vsp1: Don't recycle active list at display start v4l: vsp1: Don't set WPF sink pointer v4l: vsp1: Store source and sink pointers as vsp1_entity v4l: vsp1: Don't create links for DRM pipeline v4l: vsp1: Add pipe index argument to the VSP-DU API v4l: vsp1: Add support for the BRS entity v4l: vsp1: Add support for new VSP2-BS, VSP2-DL and VSP2-D instances v4l: vsp1: Add support for multiple LIF instances v4l: vsp1: Add support for multiple DRM pipelines v4l: vsp1: Add support for header display lists in continuous mode drm: rcar-du: Support multiple sources from the same VSP drm: rcar-du: Restrict DPLL duty cycle workaround to H3 ES1.x drm: rcar-du: Configure DPAD0 routing through last group on Gen3 drivers/gpu/drm/rcar-du/rcar_du_crtc.c| 39 -- drivers/gpu/drm/rcar-du/rcar_du_crtc.h| 3 + drivers/gpu/drm/rcar-du/rcar_du_group.c | 21 ++- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 91 ++-- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 37 +++-- drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 10 +- drivers/media/platform/vsp1/vsp1.h| 7 +- drivers/media/platform/vsp1/vsp1_bru.c| 45 -- drivers/media/platform/vsp1/vsp1_bru.h| 4 +- drivers/media/platform/vsp1/vsp1_dl.c | 205 --- drivers/media/platform/vsp1/vsp1_dl.h | 1 - drivers/media/platform/vsp1/vsp1_drm.c| 283 ++--- drivers/media/platform/vsp1/vsp1_drm.h| 38 ++--- drivers/media/platform/vsp1/vsp1_drv.c| 115 +++- drivers/media/platform/vsp1/vsp1_entity.c | 40 -- drivers/media/platform/vsp1/vsp1_entity.h | 5 +- drivers/media/platform/vsp1/vsp1_lif.c| 5 +- drivers/media/platform/vsp1/vsp1_lif.h| 2 +- drivers/media/platform/vsp1/vsp1_pipe.c | 7 +- drivers/media/platform/vsp1/vsp1_regs.h | 46 +-- drivers/media/platform/vsp1/vsp1_video.c | 63 + drivers/media/platform/vsp1/vsp1_wpf.c| 4 +- include/media/vsp1.h | 10 +- 23 files changed, 676 insertions(+), 405 deletions(-) -- Regards, Laurent Pinchart
Re: [PATCH v2] pinctrl: generic: Add output-enable property
On Thu, Jun 22, 2017 at 12:00:58PM +0200, Jacopo Mondi wrote: > Add output-enable generic pin configuration property. > This properties allows enabling/disabling pin's output capabilities > without actually driving any value on the line. > > --- > v1->v2: > - Expand the property description as suggested by Laurent. I ended up >mentioning the in-famous output buffer :) > > One (more) question to GPIO people on: > + PCONFDUMP(PIN_CONFIG_OUTPUT_ENABLE, "output enabled", NULL, false), > > I copied this from INPUT_ENABLE where arguments 2 and 3 passed to PCONFDUMP > are > NULL and false even if the property has an argument, used to enable/disable > the input mode. Is this intended? Should that be turned instead to > - PCONFDUMP(PIN_CONFIG_INPUT_ENABLE, "input enabled", NULL, false), > + PCONFDUMP(PIN_CONFIG_INPUT_ENABLE, "input enabled", "enabled", true), > > Note that the same applies to most of the properties that have an > "enable"/"disable" argument. Just to make sure this is done on purpose. > > Thanks >j > .../devicetree/bindings/pinctrl/pinctrl-bindings.txt | 2 ++ Acked-by: Rob Herring> drivers/pinctrl/pinconf-generic.c | 3 +++ > include/linux/pinctrl/pinconf-generic.h | 15 > +++ > 3 files changed, 16 insertions(+), 4 deletions(-)
Re: [PATCH] clk: renesas: r8a7796: Add PWM clock
Hi Geert, On Monday 26 Jun 2017 19:38:58 Geert Uytterhoeven wrote: > On Mon, Jun 26, 2017 at 7:26 PM, Laurent Pinchart wrote: > > --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c > > +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c > > @@ -152,6 +152,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] > > __initconst = {> > > DEF_MOD("hscif1",519, R8A7796_CLK_S3D1), > > DEF_MOD("hscif0",520, R8A7796_CLK_S3D1), > > DEF_MOD("thermal", 522, R8A7796_CLK_CP), > > > > + DEF_MOD("pwm", 523, R8A7796_CLK_S0D12), > > Cfr. commit a0b381fafffaf07c ("clk: renesas: r8a7796: Add PWM clock") > in clk-next. Same mistake twice... I wonder why I failed to find that one :-/ Sorry about the noise. -- Regards, Laurent Pinchart
[PATCH v2 10/14] v4l: vsp1: Add support for multiple DRM pipelines
The R-Car H3 ES2.0 VSP-DL instance has two LIF entities and can drive two display pipelines at the same time. Refactor the VSP DRM code to support that by introducing a vsp_drm_pipeline object that models one display pipeline. Signed-off-by: Laurent Pinchart--- drivers/media/platform/vsp1/vsp1_drm.c | 200 - drivers/media/platform/vsp1/vsp1_drm.h | 35 +++--- 2 files changed, 141 insertions(+), 94 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 4e1b893e8f51..7791d7b5a743 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -34,10 +34,10 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe) { - struct vsp1_drm *drm = to_vsp1_drm(pipe); + struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe); - if (drm->du_complete) - drm->du_complete(drm->du_private); + if (drm_pipe->du_complete) + drm_pipe->du_complete(drm_pipe->du_private); } /* - @@ -80,15 +80,22 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, const struct vsp1_du_lif_config *cfg) { struct vsp1_device *vsp1 = dev_get_drvdata(dev); - struct vsp1_pipeline *pipe = >drm->pipe; - struct vsp1_bru *bru = vsp1->bru; + struct vsp1_drm_pipeline *drm_pipe; + struct vsp1_pipeline *pipe; + struct vsp1_bru *bru; struct v4l2_subdev_format format; + const char *bru_name; unsigned int i; int ret; - if (pipe_index > 0) + if (pipe_index >= vsp1->info->lif_count) return -EINVAL; + drm_pipe = >drm->pipe[pipe_index]; + pipe = _pipe->pipe; + bru = to_bru(>bru->subdev); + bru_name = pipe->bru->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"; + if (!cfg) { /* * NULL configuration means the CRTC is being disabled, stop @@ -100,14 +107,25 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, media_pipeline_stop(>output->entity.subdev.entity); - for (i = 0; i < bru->entity.source_pad; ++i) { - vsp1->drm->inputs[i].enabled = false; - bru->inputs[i].rpf = NULL; + for (i = 0; i < ARRAY_SIZE(pipe->inputs); ++i) { + struct vsp1_rwpf *rpf = pipe->inputs[i]; + + if (!rpf) + continue; + + /* +* Remove the RPF from the pipe and the list of BRU +* inputs. +*/ + WARN_ON(list_empty(>entity.list_pipe)); + list_del_init(>entity.list_pipe); pipe->inputs[i] = NULL; + + bru->inputs[rpf->bru_input].rpf = NULL; } + drm_pipe->du_complete = NULL; pipe->num_inputs = 0; - vsp1->drm->du_complete = NULL; vsp1_dlm_reset(pipe->output->dlm); vsp1_device_put(vsp1); @@ -117,8 +135,8 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, return 0; } - dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n", - __func__, cfg->width, cfg->height); + dev_dbg(vsp1->dev, "%s: configuring LIF%u with format %ux%u\n", + __func__, pipe_index, cfg->width, cfg->height); /* * Configure the format at the BRU sinks and propagate it through the @@ -127,7 +145,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, memset(, 0, sizeof(format)); format.which = V4L2_SUBDEV_FORMAT_ACTIVE; - for (i = 0; i < bru->entity.source_pad; ++i) { + for (i = 0; i < pipe->bru->source_pad; ++i) { format.pad = i; format.format.width = cfg->width; @@ -135,60 +153,60 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, format.format.code = MEDIA_BUS_FMT_ARGB_1X32; format.format.field = V4L2_FIELD_NONE; - ret = v4l2_subdev_call(>entity.subdev, pad, + ret = v4l2_subdev_call(>bru->subdev, pad, set_fmt, NULL, ); if (ret < 0) return ret; - dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n", + dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n", __func__, format.format.width, format.format.height, - format.format.code, i); + format.format.code, bru_name, i); } - format.pad
[PATCH v2 08/14] v4l: vsp1: Add support for new VSP2-BS, VSP2-DL and VSP2-D instances
New Gen3 SoCs come with two new VSP2 variants names VSP2-BS and VSP2-DL, as well as a new VSP2-D variant on V3M and V3H SoCs. Add new entries for them in the VSP device info table. Signed-off-by: Laurent Pinchart--- drivers/media/platform/vsp1/vsp1_drv.c | 24 drivers/media/platform/vsp1/vsp1_regs.h | 15 +-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 6a9aeb71aedf..c4f2ac61f7d2 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -710,6 +710,14 @@ static const struct vsp1_device_info vsp1_device_infos[] = { .num_bru_inputs = 5, .uapi = true, }, { + .version = VI6_IP_VERSION_MODEL_VSPBS_GEN3, + .model = "VSP2-BS", + .gen = 3, + .features = VSP1_HAS_BRS, + .rpf_count = 2, + .wpf_count = 1, + .uapi = true, + }, { .version = VI6_IP_VERSION_MODEL_VSPD_GEN3, .model = "VSP2-D", .gen = 3, @@ -717,6 +725,22 @@ static const struct vsp1_device_info vsp1_device_infos[] = { .rpf_count = 5, .wpf_count = 2, .num_bru_inputs = 5, + }, { + .version = VI6_IP_VERSION_MODEL_VSPD_V3, + .model = "VSP2-D", + .gen = 3, + .features = VSP1_HAS_BRS | VSP1_HAS_BRU | VSP1_HAS_LIF, + .rpf_count = 5, + .wpf_count = 1, + .num_bru_inputs = 5, + }, { + .version = VI6_IP_VERSION_MODEL_VSPDL_GEN3, + .model = "VSP2-DL", + .gen = 3, + .features = VSP1_HAS_BRS | VSP1_HAS_BRU | VSP1_HAS_LIF, + .rpf_count = 5, + .wpf_count = 2, + .num_bru_inputs = 5, }, }; diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h index 744217e020b9..ab439a60a100 100644 --- a/drivers/media/platform/vsp1/vsp1_regs.h +++ b/drivers/media/platform/vsp1/vsp1_regs.h @@ -699,9 +699,20 @@ #define VI6_IP_VERSION_MODEL_VSPBD_GEN3(0x15 << 8) #define VI6_IP_VERSION_MODEL_VSPBC_GEN3(0x16 << 8) #define VI6_IP_VERSION_MODEL_VSPD_GEN3 (0x17 << 8) +#define VI6_IP_VERSION_MODEL_VSPD_V3 (0x18 << 8) +#define VI6_IP_VERSION_MODEL_VSPDL_GEN3(0x19 << 8) +#define VI6_IP_VERSION_MODEL_VSPBS_GEN3(0x1a << 8) #define VI6_IP_VERSION_SOC_MASK(0xff << 0) -#define VI6_IP_VERSION_SOC_H (0x01 << 0) -#define VI6_IP_VERSION_SOC_M (0x02 << 0) +#define VI6_IP_VERSION_SOC_H2 (0x01 << 0) +#define VI6_IP_VERSION_SOC_V2H (0x01 << 0) +#define VI6_IP_VERSION_SOC_V3M (0x01 << 0) +#define VI6_IP_VERSION_SOC_M2 (0x02 << 0) +#define VI6_IP_VERSION_SOC_M3W (0x02 << 0) +#define VI6_IP_VERSION_SOC_V3H (0x02 << 0) +#define VI6_IP_VERSION_SOC_H3 (0x03 << 0) +#define VI6_IP_VERSION_SOC_D3 (0x04 << 0) +#define VI6_IP_VERSION_SOC_M3N (0x04 << 0) +#define VI6_IP_VERSION_SOC_E3 (0x04 << 0) /* - * RPF CLUT Registers -- Regards, Laurent Pinchart
[PATCH v2 01/14] v4l: vsp1: Fill display list headers without holding dlm spinlock
The display list headers are filled using information from the display list only. Lower the display list manager spinlock contention by filling the headers without holding the lock. Signed-off-by: Laurent Pinchart--- drivers/media/platform/vsp1/vsp1_dl.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index aaf17b13fd78..dc47e236c780 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -483,8 +483,6 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl) unsigned long flags; bool update; - spin_lock_irqsave(>lock, flags); - if (dl->dlm->mode == VSP1_DL_MODE_HEADER) { struct vsp1_dl_list *dl_child; @@ -501,7 +499,11 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl) vsp1_dl_list_fill_header(dl_child, last); } + } + spin_lock_irqsave(>lock, flags); + + if (dl->dlm->mode == VSP1_DL_MODE_HEADER) { /* * Commit the head display list to hardware. Chained headers * will auto-start. -- Regards, Laurent Pinchart
[PATCH v2 12/14] drm: rcar-du: Support multiple sources from the same VSP
On R-Car H3 ES2.0, DU channels 0 and 3 are served by two separate pipelines from the same VSP. Support this in the DU driver. Signed-off-by: Laurent Pinchart--- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 3 ++ drivers/gpu/drm/rcar-du/rcar_du_kms.c | 91 ++ drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 37 +++--- drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 10 +++- 5 files changed, 110 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 345eff72f581..8f942ebdd0c6 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -721,7 +721,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) rcrtc->index = index; if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) - primary = >vsp->planes[0].plane; + primary = >vsp->planes[rcrtc->vsp_pipe].plane; else primary = >planes[index % 2].plane; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index b199ed5adf36..0b6d26ecfc38 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h @@ -35,6 +35,8 @@ struct rcar_du_vsp; * @flip_wait: wait queue used to signal page flip completion * @outputs: bitmask of the outputs (enum rcar_du_output) driven by this CRTC * @group: CRTC group this CRTC belongs to + * @vsp: VSP feeding video to this CRTC + * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC */ struct rcar_du_crtc { struct drm_crtc crtc; @@ -52,6 +54,7 @@ struct rcar_du_crtc { struct rcar_du_group *group; struct rcar_du_vsp *vsp; + unsigned int vsp_pipe; }; #define to_rcar_crtc(c)container_of(c, struct rcar_du_crtc, crtc) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index f4125c8ca902..82b978a5dae6 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -432,6 +432,83 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu) return 0; } +static int rcar_du_vsps_init(struct rcar_du_device *rcdu) +{ + const struct device_node *np = rcdu->dev->of_node; + struct of_phandle_args args; + struct { + struct device_node *np; + unsigned int crtcs_mask; + } vsps[RCAR_DU_MAX_VSPS] = { { 0, }, }; + unsigned int vsps_count = 0; + unsigned int cells; + unsigned int i; + int ret; + + /* +* First parse the DT vsps property to populate the list of VSPs. Each +* entry contains a pointer to the VSP DT node and a bitmask of the +* connected DU CRTCs. +*/ + cells = of_property_count_u32_elems(np, "vsps") / rcdu->num_crtcs - 1; + if (cells > 1) + return -EINVAL; + + for (i = 0; i < rcdu->num_crtcs; ++i) { + unsigned int j; + + ret = of_parse_phandle_with_fixed_args(np, "vsps", cells, i, + ); + if (ret < 0) + goto error; + + /* +* Add the VSP to the list or update the corresponding existing +* entry if the VSP has already been added. +*/ + for (j = 0; j < vsps_count; ++j) { + if (vsps[j].np == args.np) + break; + } + + if (j < vsps_count) + of_node_put(args.np); + else + vsps[vsps_count++].np = args.np; + + vsps[j].crtcs_mask |= 1 << i; + + /* Store the VSP pointer and pipe index in the CRTC. */ + rcdu->crtcs[i].vsp = >vsps[j]; + rcdu->crtcs[i].vsp_pipe = cells >= 1 ? args.args[0] : 0; + } + + /* +* Then initialize all the VSPs from the node pointers and CRTCs bitmask +* computed previously. +*/ + for (i = 0; i < vsps_count; ++i) { + struct rcar_du_vsp *vsp = >vsps[i]; + + vsp->index = i; + vsp->dev = rcdu; + + ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask); + if (ret < 0) + goto error; + } + + return 0; + +error: + for (i = 0; i < ARRAY_SIZE(vsps); ++i) { + if (vsps[i].np) + of_node_put(vsps[i].np); + } + + return ret; +} + int rcar_du_modeset_init(struct rcar_du_device *rcdu) { static const unsigned int mmio_offsets[] = { @@ -499,17 +576,9 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) /* Initialize the compositors. */ if
[PATCH v2 05/14] v4l: vsp1: Don't create links for DRM pipeline
When the VSP1 is used in a DRM pipeline the driver doesn't register the media device. Links between entities are not exposed to userspace, but are still used internally for the sole purpose of setting up internal source to sink pointers through the link setup handler. Instead of going through this complex procedure, remove link creation and set the sink pointers directly. Signed-off-by: Laurent Pinchart--- drivers/media/platform/vsp1/vsp1_drm.c | 53 -- drivers/media/platform/vsp1/vsp1_drm.h | 1 - drivers/media/platform/vsp1/vsp1_drv.c | 16 -- 3 files changed, 12 insertions(+), 58 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 2d5a74e95e09..c72d021ff820 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -487,6 +487,7 @@ void vsp1_du_atomic_flush(struct device *dev) vsp1->bru->inputs[i].rpf = rpf; rpf->bru_input = i; + rpf->entity.sink = >bru->entity; rpf->entity.sink_pad = i; dev_dbg(vsp1->dev, "%s: connecting RPF.%u to BRU:%u\n", @@ -564,53 +565,6 @@ EXPORT_SYMBOL_GPL(vsp1_du_unmap_sg); * Initialization */ -int vsp1_drm_create_links(struct vsp1_device *vsp1) -{ - const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE; - unsigned int i; - int ret; - - /* -* VSPD instances require a BRU to perform composition and a LIF to -* output to the DU. -*/ - if (!vsp1->bru || !vsp1->lif) - return -ENXIO; - - for (i = 0; i < vsp1->info->rpf_count; ++i) { - struct vsp1_rwpf *rpf = vsp1->rpf[i]; - - ret = media_create_pad_link(>entity.subdev.entity, - RWPF_PAD_SOURCE, - >bru->entity.subdev.entity, - i, flags); - if (ret < 0) - return ret; - - rpf->entity.sink = >bru->entity; - rpf->entity.sink_pad = i; - } - - ret = media_create_pad_link(>bru->entity.subdev.entity, - vsp1->bru->entity.source_pad, - >wpf[0]->entity.subdev.entity, - RWPF_PAD_SINK, flags); - if (ret < 0) - return ret; - - vsp1->bru->entity.sink = >wpf[0]->entity; - vsp1->bru->entity.sink_pad = RWPF_PAD_SINK; - - ret = media_create_pad_link(>wpf[0]->entity.subdev.entity, - RWPF_PAD_SOURCE, - >lif->entity.subdev.entity, - LIF_PAD_SINK, flags); - if (ret < 0) - return ret; - - return 0; -} - int vsp1_drm_init(struct vsp1_device *vsp1) { struct vsp1_pipeline *pipe; @@ -631,6 +585,11 @@ int vsp1_drm_init(struct vsp1_device *vsp1) list_add_tail(>entity.list_pipe, >entities); } + vsp1->bru->entity.sink = >wpf[0]->entity; + vsp1->bru->entity.sink_pad = 0; + vsp1->wpf[0]->entity.sink = >lif->entity; + vsp1->wpf[0]->entity.sink_pad = 0; + list_add_tail(>bru->entity.list_pipe, >entities); list_add_tail(>wpf[0]->entity.list_pipe, >entities); list_add_tail(>lif->entity.list_pipe, >entities); diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h index cbdbb8a39883..67d6549edfad 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.h +++ b/drivers/media/platform/vsp1/vsp1_drm.h @@ -48,6 +48,5 @@ static inline struct vsp1_drm *to_vsp1_drm(struct vsp1_pipeline *pipe) int vsp1_drm_init(struct vsp1_device *vsp1); void vsp1_drm_cleanup(struct vsp1_device *vsp1); -int vsp1_drm_create_links(struct vsp1_device *vsp1); #endif /* __VSP1_DRM_H__ */ diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 9b3a0790f92a..5a467b118a1c 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -423,19 +423,15 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) goto done; } - /* Create links. */ - if (vsp1->info->uapi) - ret = vsp1_uapi_create_links(vsp1); - else - ret = vsp1_drm_create_links(vsp1); - if (ret < 0) - goto done; - /* -* Register subdev nodes if the userspace API is enabled or initialize -* the DRM pipeline otherwise. +* Create links and register subdev nodes if the userspace API is +* enabled or initialize the DRM pipeline otherwise. */ if (vsp1->info->uapi) { + ret = vsp1_uapi_create_links(vsp1); + if (ret < 0) +
[PATCH v2 14/14] drm: rcar-du: Configure DPAD0 routing through last group on Gen3
On Gen3 SoCs DPAD0 routing is configured through the last CRTC group, unlike on Gen2 where it is configured through the first CRTC group. Fix the driver accordingly. Fixes: 2427b3037710 ("drm: rcar-du: Add R8A7795 device support") Signed-off-by: Laurent Pinchart--- drivers/gpu/drm/rcar-du/rcar_du_group.c | 21 ++--- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c index 64738fca96d0..2abb2fdd143e 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c @@ -208,23 +208,30 @@ void rcar_du_group_restart(struct rcar_du_group *rgrp) int rcar_du_set_dpad0_vsp1_routing(struct rcar_du_device *rcdu) { + struct rcar_du_group *rgrp; + struct rcar_du_crtc *crtc; int ret; if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_EXT_CTRL_REGS)) return 0; - /* RGB output routing to DPAD0 and VSP1D routing to DU0/1/2 are -* configured in the DEFR8 register of the first group. As this function -* can be called with the DU0 and DU1 CRTCs disabled, we need to enable -* the first group clock before accessing the register. + /* +* RGB output routing to DPAD0 and VSP1D routing to DU0/1/2 are +* configured in the DEFR8 register of the first group on Gen2 and the +* last group on Gen3. As this function can be called with the DU +* channels of the corresponding CRTCs disabled, we need to enable the +* group clock before accessing the register. */ - ret = clk_prepare_enable(rcdu->crtcs[0].clock); + rgrp = >groups[DIV_ROUND_UP(rcdu->num_crtcs, 2) - 1]; + crtc = >crtcs[rgrp->index * 2]; + + ret = clk_prepare_enable(crtc->clock); if (ret < 0) return ret; - rcar_du_group_setup_defr8(>groups[0]); + rcar_du_group_setup_defr8(rgrp); - clk_disable_unprepare(rcdu->crtcs[0].clock); + clk_disable_unprepare(crtc->clock); return 0; } -- Regards, Laurent Pinchart
[PATCH v2 11/14] v4l: vsp1: Add support for header display lists in continuous mode
The VSP supports both header and headerless display lists. The latter is easier to use when the VSP feeds data directly to the DU in continuous mode, and the driver thus uses headerless display lists for DU operation and header display lists otherwise. Headerless display lists are only available on WPF.0. This has never been an issue so far, as only WPF.0 is connected to the DU. However, on H3 ES2.0, the VSP-DL instance has both WPF.0 and WPF.1 connected to the DU. We thus can't use headerless display lists unconditionally for DU operation. Implement support for continuous mode with header display lists, and use it for DU operation on WPF outputs that don't support headerless mode. Signed-off-by: Laurent Pinchart--- drivers/media/platform/vsp1/vsp1_dl.c | 195 +--- drivers/media/platform/vsp1/vsp1_regs.h | 1 + 2 files changed, 127 insertions(+), 69 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index bb92be4fe0f0..8b5cbb6b7a70 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -95,6 +95,7 @@ enum vsp1_dl_mode { * struct vsp1_dl_manager - Display List manager * @index: index of the related WPF * @mode: display list operation mode (header or headerless) + * @singleshot: execute the display list in single-shot mode * @vsp1: the VSP1 device * @lock: protects the free, active, queued, pending and gc_fragments lists * @free: array of all free display lists @@ -107,6 +108,7 @@ enum vsp1_dl_mode { struct vsp1_dl_manager { unsigned int index; enum vsp1_dl_mode mode; + bool singleshot; struct vsp1_device *vsp1; spinlock_t lock; @@ -437,6 +439,7 @@ int vsp1_dl_list_add_chain(struct vsp1_dl_list *head, static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last) { + struct vsp1_dl_manager *dlm = dl->dlm; struct vsp1_dl_header_list *hdr = dl->header->lists; struct vsp1_dl_body *dlb; unsigned int num_lists = 0; @@ -461,85 +464,145 @@ static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last) dl->header->num_lists = num_lists; - /* -* If this display list's chain is not empty, we are on a list, where -* the next item in the list is the display list entity which should be -* automatically queued by the hardware. -*/ if (!list_empty(>chain) && !is_last) { + /* +* If this display list's chain is not empty, we are on a list, +* and the next item is the display list that we must queue for +* automatic processing by the hardware. +*/ struct vsp1_dl_list *next = list_next_entry(dl, chain); dl->header->next_header = next->dma; dl->header->flags = VSP1_DLH_AUTO_START; + } else if (!dlm->singleshot) { + /* +* if the display list manager works in continuous mode, the VSP +* should loop over the display list continuously until +* instructed to do otherwise. +*/ + dl->header->next_header = dl->dma; + dl->header->flags = VSP1_DLH_INT_ENABLE | VSP1_DLH_AUTO_START; } else { + /* +* Otherwise, in mem-to-mem mode, we work in single-shot mode +* and the next display list must not be started automatically. +*/ dl->header->flags = VSP1_DLH_INT_ENABLE; } } -void vsp1_dl_list_commit(struct vsp1_dl_list *dl) +static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm) { - struct vsp1_dl_manager *dlm = dl->dlm; struct vsp1_device *vsp1 = dlm->vsp1; - unsigned long flags; - bool update; - - if (dl->dlm->mode == VSP1_DL_MODE_HEADER) { - struct vsp1_dl_list *dl_child; - - /* -* In header mode the caller guarantees that the hardware is -* idle at this point. -*/ - /* Fill the header for the head and chained display lists. */ - vsp1_dl_list_fill_header(dl, list_empty(>chain)); - - list_for_each_entry(dl_child, >chain, chain) { - bool last = list_is_last(_child->chain, >chain); + if (!dlm->queued) + return false; - vsp1_dl_list_fill_header(dl_child, last); - } - } + /* +* Check whether the VSP1 has taken the update. In headerless mode the +* hardware indicates this by clearing the UPD bit in the DL_BODY_SIZE +* register, and in header mode by clearing the UPDHDR bit in the CMD +* register. +*/ + if (dlm->mode == VSP1_DL_MODE_HEADERLESS) + return
[PATCH v2 07/14] v4l: vsp1: Add support for the BRS entity
The Blend/ROP Sub Unit (BRS) is a stripped-down version of the BRU found in several VSP2 instances. Compared to a regular BRU, it supports two inputs only, and thus has no ROP unit. Add support for the BRS by modeling it as a new entity type, but reuse the vsp1_bru object underneath. Chaining the BRU and BRS entities seems to be supported by the hardware but isn't implemented yet as it isn't the primary use case for the BRS. Signed-off-by: Laurent Pinchart--- drivers/media/platform/vsp1/vsp1.h| 2 + drivers/media/platform/vsp1/vsp1_bru.c| 45 ++ drivers/media/platform/vsp1/vsp1_bru.h| 4 +- drivers/media/platform/vsp1/vsp1_drv.c| 19 +- drivers/media/platform/vsp1/vsp1_entity.c | 13 ++- drivers/media/platform/vsp1/vsp1_entity.h | 1 + drivers/media/platform/vsp1/vsp1_pipe.c | 7 ++-- drivers/media/platform/vsp1/vsp1_regs.h | 26 + drivers/media/platform/vsp1/vsp1_video.c | 63 --- drivers/media/platform/vsp1/vsp1_wpf.c| 4 +- 10 files changed, 130 insertions(+), 54 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h index 847963b6e9eb..73858a0ed35c 100644 --- a/drivers/media/platform/vsp1/vsp1.h +++ b/drivers/media/platform/vsp1/vsp1.h @@ -54,6 +54,7 @@ struct vsp1_uds; #define VSP1_HAS_WPF_HFLIP (1 << 6) #define VSP1_HAS_HGO (1 << 7) #define VSP1_HAS_HGT (1 << 8) +#define VSP1_HAS_BRS (1 << 9) struct vsp1_device_info { u32 version; @@ -76,6 +77,7 @@ struct vsp1_device { struct rcar_fcp_device *fcp; struct device *bus_master; + struct vsp1_bru *brs; struct vsp1_bru *bru; struct vsp1_clu *clu; struct vsp1_hgo *hgo; diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c index 85362c5ef57a..e8fd2ae3b3eb 100644 --- a/drivers/media/platform/vsp1/vsp1_bru.c +++ b/drivers/media/platform/vsp1/vsp1_bru.c @@ -33,7 +33,7 @@ static inline void vsp1_bru_write(struct vsp1_bru *bru, struct vsp1_dl_list *dl, u32 reg, u32 data) { - vsp1_dl_list_write(dl, reg, data); + vsp1_dl_list_write(dl, bru->base + reg, data); } /* - @@ -332,11 +332,14 @@ static void bru_configure(struct vsp1_entity *entity, /* * Route BRU input 1 as SRC input to the ROP unit and configure the ROP * unit with a NOP operation to make BRU input 1 available as the -* Blend/ROP unit B SRC input. +* Blend/ROP unit B SRC input. Only needed for BRU, the BRS has no ROP +* unit. */ - vsp1_bru_write(bru, dl, VI6_BRU_ROP, VI6_BRU_ROP_DSTSEL_BRUIN(1) | - VI6_BRU_ROP_CROP(VI6_ROP_NOP) | - VI6_BRU_ROP_AROP(VI6_ROP_NOP)); + if (entity->type == VSP1_ENTITY_BRU) + vsp1_bru_write(bru, dl, VI6_BRU_ROP, + VI6_BRU_ROP_DSTSEL_BRUIN(1) | + VI6_BRU_ROP_CROP(VI6_ROP_NOP) | + VI6_BRU_ROP_AROP(VI6_ROP_NOP)); for (i = 0; i < bru->entity.source_pad; ++i) { bool premultiplied = false; @@ -366,12 +369,13 @@ static void bru_configure(struct vsp1_entity *entity, ctrl |= VI6_BRU_CTRL_DSTSEL_VRPF; /* -* Route BRU inputs 0 to 3 as SRC inputs to Blend/ROP units A to -* D in that order. The Blend/ROP unit B SRC is hardwired to the -* ROP unit output, the corresponding register bits must be set -* to 0. +* Route inputs 0 to 3 as SRC inputs to Blend/ROP units A to D +* in that order. In the BRU the Blend/ROP unit B SRC is +* hardwired to the ROP unit output, the corresponding register +* bits must be set to 0. The BRS has no ROP unit and doesn't +* need any special processing. */ - if (i != 1) + if (!(entity->type == VSP1_ENTITY_BRU && i == 1)) ctrl |= VI6_BRU_CTRL_SRCSEL_BRUIN(i); vsp1_bru_write(bru, dl, VI6_BRU_CTRL(i), ctrl); @@ -407,20 +411,31 @@ static const struct vsp1_entity_operations bru_entity_ops = { * Initialization and Cleanup */ -struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1) +struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1, +enum vsp1_entity_type type) { struct vsp1_bru *bru; + unsigned int num_pads; + const char *name; int ret; bru = devm_kzalloc(vsp1->dev, sizeof(*bru), GFP_KERNEL); if (bru == NULL) return ERR_PTR(-ENOMEM); + bru->base = type == VSP1_ENTITY_BRU ? VI6_BRU_BASE :
[PATCH v2 06/14] v4l: vsp1: Add pipe index argument to the VSP-DU API
In the H3 ES2.0 SoC the VSP2-DL instance has two connections to DU channels that need to be configured independently. Extend the VSP-DU API with a pipeline index to identify which pipeline the caller wants to operate on. Signed-off-by: Laurent Pinchart--- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 12 ++-- drivers/media/platform/vsp1/vsp1_drm.c | 32 ++-- include/media/vsp1.h | 10 ++ 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index f870445ebc8d..d46dce054442 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c @@ -81,22 +81,22 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc) */ crtc->group->need_restart = true; - vsp1_du_setup_lif(crtc->vsp->vsp, ); + vsp1_du_setup_lif(crtc->vsp->vsp, 0, ); } void rcar_du_vsp_disable(struct rcar_du_crtc *crtc) { - vsp1_du_setup_lif(crtc->vsp->vsp, NULL); + vsp1_du_setup_lif(crtc->vsp->vsp, 0, NULL); } void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc) { - vsp1_du_atomic_begin(crtc->vsp->vsp); + vsp1_du_atomic_begin(crtc->vsp->vsp, 0); } void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc) { - vsp1_du_atomic_flush(crtc->vsp->vsp); + vsp1_du_atomic_flush(crtc->vsp->vsp, 0); } /* Keep the two tables in sync. */ @@ -192,7 +192,7 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane) } } - vsp1_du_atomic_update(plane->vsp->vsp, plane->index, ); + vsp1_du_atomic_update(plane->vsp->vsp, 0, plane->index, ); } static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane, @@ -292,7 +292,7 @@ static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane, if (plane->state->crtc) rcar_du_vsp_plane_setup(rplane); else - vsp1_du_atomic_update(rplane->vsp->vsp, rplane->index, NULL); + vsp1_du_atomic_update(rplane->vsp->vsp, 0, rplane->index, NULL); } static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = { diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index c72d021ff820..daaafe7885fa 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -58,21 +58,26 @@ EXPORT_SYMBOL_GPL(vsp1_du_init); /** * vsp1_du_setup_lif - Setup the output part of the VSP pipeline * @dev: the VSP device + * @pipe_index: the DRM pipeline index * @cfg: the LIF configuration * * Configure the output part of VSP DRM pipeline for the given frame @cfg.width - * and @cfg.height. This sets up formats on the BRU source pad, the WPF0 sink - * and source pads, and the LIF sink pad. + * and @cfg.height. This sets up formats on the blend unit (BRU or BRS) source + * pad, the WPF sink and source pads, and the LIF sink pad. * - * As the media bus code on the BRU source pad is conditioned by the - * configuration of the BRU sink 0 pad, we also set up the formats on all BRU + * The @pipe_index argument selects which DRM pipeline to setup. The number of + * available pipelines depend on the VSP instance. + * + * As the media bus code on the blend unit source pad is conditioned by the + * configuration of its sink 0 pad, we also set up the formats on all blend unit * sinks, even if the configuration will be overwritten later by - * vsp1_du_setup_rpf(). This ensures that the BRU configuration is set to a well - * defined state. + * vsp1_du_setup_rpf(). This ensures that the blend unit configuration is set to + * a well defined state. * * Return 0 on success or a negative error code on failure. */ -int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg) +int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, + const struct vsp1_du_lif_config *cfg) { struct vsp1_device *vsp1 = dev_get_drvdata(dev); struct vsp1_pipeline *pipe = >drm->pipe; @@ -81,6 +86,9 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg) unsigned int i; int ret; + if (pipe_index > 0) + return -EINVAL; + if (!cfg) { /* * NULL configuration means the CRTC is being disabled, stop @@ -232,8 +240,9 @@ EXPORT_SYMBOL_GPL(vsp1_du_setup_lif); /** * vsp1_du_atomic_begin - Prepare for an atomic update * @dev: the VSP device + * @pipe_index: the DRM pipeline index */ -void vsp1_du_atomic_begin(struct device *dev) +void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index) { struct vsp1_device *vsp1 = dev_get_drvdata(dev); struct vsp1_pipeline *pipe = >drm->pipe; @@ -245,6 +254,7 @@ EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin); /** * vsp1_du_atomic_update -
[PATCH v2 03/14] v4l: vsp1: Don't set WPF sink pointer
The sink pointer is used to configure routing inside the VSP, and as such must point to the next VSP entity in the pipeline. The WPF being a pipeline terminal sink, its output route can't be configured. The routing configuration code already handles this correctly without referring to the sink pointer, which thus doesn't need to be set. Signed-off-by: Laurent Pinchart--- drivers/media/platform/vsp1/vsp1_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 6b35e043b554..35087d5573ce 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -412,7 +412,6 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) } list_add_tail(>list, >videos); - wpf->entity.sink = >video.entity; } } -- Regards, Laurent Pinchart
[PATCH v2 02/14] v4l: vsp1: Don't recycle active list at display start
When the display start interrupt occurs, we know that the hardware has finished loading the active display list. The driver then proceeds to recycle the list, assuming it won't be needed anymore. This assumption holds true for headerless display lists, as the VSP doesn't reload the list for the next frame if it hasn't changed. However, this isn't true anymore for header display lists, as they are loaded at every frame start regardless of whether they have been updated. To prepare for header display lists usage in display pipelines, we need to postpone recycling the list until it gets replaced by a new one through a page flip. The driver already does so in the frame end interrupt handler, so all we need is to skip list recycling in the display start interrupt handler. While the active list can be recycled at display start for headerless display lists, there's no real harm in postponing that to the frame end interrupt handler in all cases. This simplifies interrupt handling as we don't need to process the display start interrupt anymore. Signed-off-by: Laurent Pinchart--- drivers/media/platform/vsp1/vsp1_dl.c | 16 drivers/media/platform/vsp1/vsp1_dl.h | 1 - drivers/media/platform/vsp1/vsp1_drm.c | 12 drivers/media/platform/vsp1/vsp1_drm.h | 2 -- drivers/media/platform/vsp1/vsp1_drv.c | 8 5 files changed, 4 insertions(+), 35 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index dc47e236c780..bb92be4fe0f0 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -547,22 +547,6 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl) * Display List Manager */ -/* Interrupt Handling */ -void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm) -{ - spin_lock(>lock); - - /* -* The display start interrupt signals the end of the display list -* processing by the device. The active display list, if any, won't be -* accessed anymore and can be reused. -*/ - __vsp1_dl_list_put(dlm->active); - dlm->active = NULL; - - spin_unlock(>lock); -} - /** * vsp1_dlm_irq_frame_end - Display list handler for the frame end interrupt * @dlm: the display list manager diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h index 6ec1380a10af..ee3508172f0a 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.h +++ b/drivers/media/platform/vsp1/vsp1_dl.h @@ -27,7 +27,6 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1, unsigned int prealloc); void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm); void vsp1_dlm_reset(struct vsp1_dl_manager *dlm); -void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm); bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm); struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm); diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 9377aafa8996..bc3fd9bc7126 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -32,11 +32,6 @@ * Interrupt Handling */ -void vsp1_drm_display_start(struct vsp1_device *vsp1) -{ - vsp1_dlm_irq_display_start(vsp1->drm->pipe.output->dlm); -} - static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe) { struct vsp1_drm *drm = to_vsp1_drm(pipe); @@ -224,6 +219,10 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg) return ret; } + /* Disable the display interrupts. */ + vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0); + vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0); + dev_dbg(vsp1->dev, "%s: pipeline enabled\n", __func__); return 0; @@ -529,13 +528,10 @@ void vsp1_du_atomic_flush(struct device *dev) /* Start or stop the pipeline if needed. */ if (!vsp1->drm->num_inputs && pipe->num_inputs) { - vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0); - vsp1_write(vsp1, VI6_DISP_IRQ_ENB, VI6_DISP_IRQ_ENB_DSTE); spin_lock_irqsave(>irqlock, flags); vsp1_pipeline_run(pipe); spin_unlock_irqrestore(>irqlock, flags); } else if (vsp1->drm->num_inputs && !pipe->num_inputs) { - vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0); vsp1_pipeline_stop(pipe); } } diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h index e9f80727ff92..cbdbb8a39883 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.h +++ b/drivers/media/platform/vsp1/vsp1_drm.h @@ -50,6 +50,4 @@ int vsp1_drm_init(struct vsp1_device *vsp1); void vsp1_drm_cleanup(struct vsp1_device *vsp1); int vsp1_drm_create_links(struct vsp1_device *vsp1); -void vsp1_drm_display_start(struct vsp1_device *vsp1); - #endif /*
Re: [PATCH v2] gpio: rcar: Add R8A7743 (RZ/G1M) support
On Wed, Jun 21, 2017 at 03:27:09PM +0100, Biju Das wrote: > Renesas RZ/G1M (R8A7743) SoC GPIO blocks are identical to the R-Car Gen2 > family. Add support for its GPIO controllers. > > Signed-off-by: Biju Das> Reviewed-by: Chris Paterson > --- > v1->v2 > * Modified the text "RZ-G1M" to "RZ/G1M" > > Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt | 1 + > drivers/gpio/gpio-rcar.c | 4 > 2 files changed, 5 insertions(+) Acked-by: Rob Herring
Re: [PATCH v6 00/8] Renesas RZ/A1 pin and gpio controller
On Mon, Jun 26, 2017 at 10:45:22AM +0200, Geert Uytterhoeven wrote: > Hi Linus, > > On Thu, Jun 22, 2017 at 4:54 PM, Jacopo Mondi> wrote: > >this is 6th round of RZ/A1 pin controller patch series. > > > > Where did we stop: discussion from pin controller driver shifted toward two > > new generic pin configuration properties I added to the previous series > > (bi-directional and output-enable). > > > > After a really long discussion, we decided to go for handling internally all > > bi-directional use cases, making the generic property not a requirement for > > the > > series. Interestingly, we recently found out the number of pins actually > > requiring this flag is less (~half) than what reported by the processor > > manual, > > so we could have handled these internally from day one :( > > > > We also now manage internally pins requiring IO direction specified in > > software > > even when configured in alternate function mode (SWIO mode). Most of them > > are > > handled by the driver, some of them have to come from DTS as the user can > > freely > > select if they have to be inputs or outputs. For those pins, and after > > another > > discussion involving NXP developers, we decided to use input-enable and > > output-enable properties. I have just sent a patch to add output-enable to > > the > > generic pin configuration properties, but it is currently under discussion. > > > > However, none of the pins currently configured by mainline DTS require those > > properties to be specified, so I have dropped in this driver any dependency > > on > > output-enable property, and I'm using instead the already in place > > PIN_CONFIG_OUTPUT one. Once output-enable will eventually be accepted, we > > can > > update the driver to make use of it, but since there are no use cases for > > that > > at the moment, it makes not too much sense holding this series back for > > that. > > > > The total memory occupation we were so worried about of bi-directional and > > swio > > pin tables is now around 100 bytes, because of how the number of pins > > actually > > needing those flags has reduced and because of how we have arranged the > > tables using bitfield structures (credits to Geert here). > > > > Having cleared out dependencies on new pin configuration properties and > > having > > made configuration flags a driver specific issue, I hope this version can be > > accepted and land in forthcoming pull request for Renesas PFC updates from > > Geert, pending some feedback from the linux-gpio community. > > If this is OK for you, I'd like to include the first 3 patches (plus a small > fix I received offline from Chris Brandt[*]) in my final pull request of > sh-pfc for v4.13 (which I have been postponing in anticipation of this > driver). > > After v4.13-rc1, Simon can queue up the DTS patches in his tree for v4.14. Fine by me. I have marked the dts patches as Deferred. Jacopo, please repost or ping me once the driver changes have shown up in an rc release - v4.13-rc1 sounds likely.
Re: [PATCH v2] gpio: rcar: Add R8A7743 (RZ/G1M) support
On Mon, Jun 26, 2017 at 10:13:00AM +0200, Geert Uytterhoeven wrote: > On Wed, Jun 21, 2017 at 4:27 PM, Biju Daswrote: > > Renesas RZ/G1M (R8A7743) SoC GPIO blocks are identical to the R-Car Gen2 > > family. Add support for its GPIO controllers. > > > > Signed-off-by: Biju Das > > Reviewed-by: Chris Paterson > > Acked-by: Geert Uytterhoeven > > Although I think the time has come for family-specific compatible values > for R-Car Gen2 and Gen3. Yes, agreed.
Re: [PATCH] clk: renesas: r8a7796: Add PWM clock
On Mon, Jun 26, 2017 at 7:26 PM, Laurent Pinchartwrote: > --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c > +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c > @@ -152,6 +152,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] > __initconst = { > DEF_MOD("hscif1",519, R8A7796_CLK_S3D1), > DEF_MOD("hscif0",520, R8A7796_CLK_S3D1), > DEF_MOD("thermal", 522, R8A7796_CLK_CP), > + DEF_MOD("pwm", 523, R8A7796_CLK_S0D12), Cfr. commit a0b381fafffaf07c ("clk: renesas: r8a7796: Add PWM clock") in clk-next. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
[PATCH] clk: renesas: r8a7796: Add PWM clock
Signed-off-by: Laurent Pinchart--- drivers/clk/renesas/r8a7796-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index 1d8c5c2b6174..30583cdc1350 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -152,6 +152,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { DEF_MOD("hscif1",519, R8A7796_CLK_S3D1), DEF_MOD("hscif0",520, R8A7796_CLK_S3D1), DEF_MOD("thermal", 522, R8A7796_CLK_CP), + DEF_MOD("pwm", 523, R8A7796_CLK_S0D12), DEF_MOD("fcpvd2",601, R8A7796_CLK_S0D2), DEF_MOD("fcpvd1",602, R8A7796_CLK_S0D2), DEF_MOD("fcpvd0",603, R8A7796_CLK_S0D2), -- Regards, Laurent Pinchart
Re: [PATCH v2 1/2] drm: rcar-du: Add a VSP channel index to the vsps DT property
Hi Geert, On Monday 26 Jun 2017 18:36:14 Geert Uytterhoeven wrote: > On Mon, Jun 26, 2017 at 6:29 PM, Laurent Pinchart wrote: > > On some R-Car SoCs a single VSP can serve multiple DU channels through > > multiple LIF instances in the VSP. The current DT bindings don't support > > specifying that kind of SoC integration scheme. Extend them with a VSP > > channel index. > > > > Backward compatibility can be ensured in drivers by checking the length > > of the vsps property and setting the channel to 0 when the property > > doesn't contain channel indices. > > > > Signed-off-by: Laurent Pinchart > >> > Thanks for your patch! > > > --- a/Documentation/devicetree/bindings/display/renesas,du.txt > > +++ b/Documentation/devicetree/bindings/display/renesas,du.txt > > > > @@ -36,8 +36,10 @@ Required Properties: > >When supplied they must be named "dclkin.x" with "x" being the > >input > >clock numerical index. > > > > - - vsps: A list of phandles to the VSP nodes that handle the memory > > -interfaces for the DU channels. > > + - vsps: A list of phandle and channel index tuples to the VSPs that > > handle +the memory interfaces for the DU channels. The phandle > > identifies the VSP +instance that serves the DU channel, and the > > channel index identifies the +LIF instances in that VSP. > > instance > > > @@ -59,24 +61,24 @@ corresponding to each DU output. > > > > R8A7796 (M3-W)DPADHDMILVDS- > > > > -Example: R8A7790 (R-Car H2) DU > > +Example: R8A7795 (R-Car H3) ES2.0 DU > > > > - du: du@feb0 { > > - compatible = "renesas,du-r8a7790"; > > - reg = <0 0xfeb0 0 0x7>, > > - <0 0xfeb9 0 0x1c>, > > - <0 0xfeb94000 0 0x1c>; > > - reg-names = "du", "lvds.0", "lvds.1"; > > - interrupt-parent = <>; > > - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, > > -<0 268 IRQ_TYPE_LEVEL_HIGH>, > > -<0 269 IRQ_TYPE_LEVEL_HIGH>; > > - clocks = <_clks R8A7790_CLK_DU0>, > > -<_clks R8A7790_CLK_DU1>, > > -<_clks R8A7790_CLK_DU2>, > > -<_clks R8A7790_CLK_LVDS0>, > > -<_clks R8A7790_CLK_LVDS1>; > > - clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1"; > > + du: display@feb0 { > > + compatible = "renesas,du-r8a7795"; > > + reg = <0 0xfeb0 0 0x8>, > > + <0 0xfeb9 0 0x14>; > > + reg-names = "du", "lvds.0"; > > + interrupts = , > > +, > > +, > > +; > > + clocks = < CPG_MOD 724>, > > +< CPG_MOD 723>, > > +< CPG_MOD 722>, > > +< CPG_MOD 721>, > > +< CPG_MOD 727>; > > + clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0"; > > + vsps = < 0 0 0 1>; > > For increased readability, I suggest formatting this as: > > vsps = < 0>, < 0>, < 0>, < 1>; Good point. I'll address both comments in v3. -- Regards, Laurent Pinchart
Re: [PATCH v2 1/2] drm: rcar-du: Add a VSP channel index to the vsps DT property
Hi Laurent, On Mon, Jun 26, 2017 at 6:29 PM, Laurent Pinchartwrote: > On some R-Car SoCs a single VSP can serve multiple DU channels through > multiple LIF instances in the VSP. The current DT bindings don't support > specifying that kind of SoC integration scheme. Extend them with a VSP > channel index. > > Backward compatibility can be ensured in drivers by checking the length > of the vsps property and setting the channel to 0 when the property > doesn't contain channel indices. > > Signed-off-by: Laurent Pinchart Thanks for your patch! > --- a/Documentation/devicetree/bindings/display/renesas,du.txt > +++ b/Documentation/devicetree/bindings/display/renesas,du.txt > @@ -36,8 +36,10 @@ Required Properties: >When supplied they must be named "dclkin.x" with "x" being the input >clock numerical index. > > - - vsps: A list of phandles to the VSP nodes that handle the memory > -interfaces for the DU channels. > + - vsps: A list of phandle and channel index tuples to the VSPs that handle > +the memory interfaces for the DU channels. The phandle identifies the VSP > +instance that serves the DU channel, and the channel index identifies the > +LIF instances in that VSP. instance > @@ -59,24 +61,24 @@ corresponding to each DU output. > R8A7796 (M3-W)DPADHDMILVDS- > > > -Example: R8A7790 (R-Car H2) DU > +Example: R8A7795 (R-Car H3) ES2.0 DU > > - du: du@feb0 { > - compatible = "renesas,du-r8a7790"; > - reg = <0 0xfeb0 0 0x7>, > - <0 0xfeb9 0 0x1c>, > - <0 0xfeb94000 0 0x1c>; > - reg-names = "du", "lvds.0", "lvds.1"; > - interrupt-parent = <>; > - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, > -<0 268 IRQ_TYPE_LEVEL_HIGH>, > -<0 269 IRQ_TYPE_LEVEL_HIGH>; > - clocks = <_clks R8A7790_CLK_DU0>, > -<_clks R8A7790_CLK_DU1>, > -<_clks R8A7790_CLK_DU2>, > -<_clks R8A7790_CLK_LVDS0>, > -<_clks R8A7790_CLK_LVDS1>; > - clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1"; > + du: display@feb0 { > + compatible = "renesas,du-r8a7795"; > + reg = <0 0xfeb0 0 0x8>, > + <0 0xfeb9 0 0x14>; > + reg-names = "du", "lvds.0"; > + interrupts = , > +, > +, > +; > + clocks = < CPG_MOD 724>, > +< CPG_MOD 723>, > +< CPG_MOD 722>, > +< CPG_MOD 721>, > +< CPG_MOD 727>; > + clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0"; > + vsps = < 0 0 0 1>; For increased readability, I suggest formatting this as: vsps = < 0>, < 0>, < 0>, < 1>; Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
[PATCH v2 1/2] drm: rcar-du: Add a VSP channel index to the vsps DT property
On some R-Car SoCs a single VSP can serve multiple DU channels through multiple LIF instances in the VSP. The current DT bindings don't support specifying that kind of SoC integration scheme. Extend them with a VSP channel index. Backward compatibility can be ensured in drivers by checking the length of the vsps property and setting the channel to 0 when the property doesn't contain channel indices. Signed-off-by: Laurent Pinchart--- .../devicetree/bindings/display/renesas,du.txt | 51 +- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt index c6cb96a4fa93..89bbc7950654 100644 --- a/Documentation/devicetree/bindings/display/renesas,du.txt +++ b/Documentation/devicetree/bindings/display/renesas,du.txt @@ -36,8 +36,10 @@ Required Properties: When supplied they must be named "dclkin.x" with "x" being the input clock numerical index. - - vsps: A list of phandles to the VSP nodes that handle the memory -interfaces for the DU channels. + - vsps: A list of phandle and channel index tuples to the VSPs that handle +the memory interfaces for the DU channels. The phandle identifies the VSP +instance that serves the DU channel, and the channel index identifies the +LIF instances in that VSP. Required nodes: @@ -59,24 +61,24 @@ corresponding to each DU output. R8A7796 (M3-W)DPADHDMILVDS- -Example: R8A7790 (R-Car H2) DU +Example: R8A7795 (R-Car H3) ES2.0 DU - du: du@feb0 { - compatible = "renesas,du-r8a7790"; - reg = <0 0xfeb0 0 0x7>, - <0 0xfeb9 0 0x1c>, - <0 0xfeb94000 0 0x1c>; - reg-names = "du", "lvds.0", "lvds.1"; - interrupt-parent = <>; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, -<0 268 IRQ_TYPE_LEVEL_HIGH>, -<0 269 IRQ_TYPE_LEVEL_HIGH>; - clocks = <_clks R8A7790_CLK_DU0>, -<_clks R8A7790_CLK_DU1>, -<_clks R8A7790_CLK_DU2>, -<_clks R8A7790_CLK_LVDS0>, -<_clks R8A7790_CLK_LVDS1>; - clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1"; + du: display@feb0 { + compatible = "renesas,du-r8a7795"; + reg = <0 0xfeb0 0 0x8>, + <0 0xfeb9 0 0x14>; + reg-names = "du", "lvds.0"; + interrupts = , +, +, +; + clocks = < CPG_MOD 724>, +< CPG_MOD 723>, +< CPG_MOD 722>, +< CPG_MOD 721>, +< CPG_MOD 727>; + clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0"; + vsps = < 0 0 0 1>; ports { #address-cells = <1>; @@ -89,12 +91,19 @@ Example: R8A7790 (R-Car H2) DU }; port@1 { reg = <1>; - du_out_lvds0: endpoint { + du_out_hdmi0: endpoint { + remote-endpoint = <_hdmi0_in>; }; }; port@2 { reg = <2>; - du_out_lvds1: endpoint { + du_out_hdmi1: endpoint { + remote-endpoint = <_hdmi1_in>; + }; + }; + port@3 { + reg = <3>; + du_out_lvds0: endpoint { }; }; }; -- Regards, Laurent Pinchart
[PATCH v2 2/2] arm64: dts: r8a7795: Add support for the DU
Add a compatible string and VSP links to the DU node. The H3 ES1.x and H3 ES2.0 are compatible save for the links to the VSPs that are described explicitly in DT, so there's no need for a new ES2-specific compatible string. Signed-off-by: Laurent PinchartReviewed-by: Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 1 - arch/arm64/boot/dts/renesas/r8a7795.dtsi | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index a0ba7bd21ea3..f1646334899f 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -79,6 +79,5 @@ }; { - compatible = "renesas,du-r8a7795"; vsps = < >; }; diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index e31c1b660b3f..525dfedaba17 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -1755,6 +1755,7 @@ }; du: display@feb0 { + compatible = "renesas,du-r8a7795"; reg = <0 0xfeb0 0 0x8>, <0 0xfeb9 0 0x14>; reg-names = "du", "lvds.0"; @@ -1768,6 +1769,7 @@ < CPG_MOD 721>, < CPG_MOD 727>; clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0"; + vsps = < 0 0 0 1>; status = "disabled"; ports { -- Regards, Laurent Pinchart
[PATCH v2 0/2] R-Car H3 ES2.0 Salvator-X: Enable DU support in DT
Hello, This patch series enable DU support in DT for the R-Car H3 ES2.0 Salvator-X board. Patch 1/2 extends the DT bindings as needed, and patch 2/2 then enables DU in the SoC DT. The patches are based on top of Simon's arm64-dt-for-v4.14 branch. Compared to v1 - the VSP DT bindings have been extended in patch 1/2 - patch 2/2 has been updated accordingly - patch "arm64: dts: r8a7795: salvator-x: Unify DU node between ES1.x and ES2.0" has been dropped Laurent Pinchart (2): drm: rcar-du: Add a VSP channel index to the vsps DT property arm64: dts: r8a7795: Add support for the DU .../devicetree/bindings/display/renesas,du.txt | 51 +- arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 1 - arch/arm64/boot/dts/renesas/r8a7795.dtsi | 2 + 3 files changed, 32 insertions(+), 22 deletions(-) -- Regards, Laurent Pinchart
Re: [PATCH v4 1/2] media: i2c: adv748x: add adv748x driver
[snip] On Monday 26 Jun 2017 16:14:47 Kieran Bingham wrote: > >> +int adv748x_txa_power(struct adv748x_state *state, bool on) > >> +{ > >> +int val; > >> + > >> +val = txa_read(state, ADV748X_CSI_FS_AS_LS); > >> +if (val < 0) > >> +return val; > >> + > >> +/* > >> + * This test against BIT(6) is not documented by the datasheet, but > >> was + * specified in the downstream driver. > >> + * Track with a WARN_ONCE to determine if it is ever set by HW. > >> + */ > >> +WARN_ONCE((on && val & ADV748X_CSI_FS_AS_LS_UNKNOWN), > >> +"Enabling with unknown bit set"); > >> + > >> +if (on) > >> +return adv748x_write_regs(state, adv748x_power_up_txa_4lane); > >> +else > > > > 'else' isn't needed. > > That's a shame - I think the code is more elegant (/symmetrical) this way - > but no worries. > Adapted. (same for the others) For what it's worth, I would personally have kept the else here. I'm all for if (simple_case) { handle_simple_case(); return 0; } /* Complex case */ or similar constructs with s/simple_case/uncommon_case/ or s/simple_case/error_case/, but here the two branches are small and symmetric, so an else makes sense to me to highlight that symmetry. > >> +return adv748x_write_regs(state, adv748x_power_down_txa_4lane); > >> +} -- Regards, Laurent Pinchart
Re: [PATCH v2 1/7] dt-bindings: display: renesas: Add R-Car M3-W HDMI TX DT bindings
On Wed, Jun 21, 2017 at 12:31:27PM +0300, Laurent Pinchart wrote: > The M3-W HDMI TX controller seems to be compatible for the H3. No > extension to the DT bindings are needed, add an SoC-specific compatible > string in case differences between the IP versions are found later and > require model-specific handling. > > Signed-off-by: Laurent Pinchart> --- > Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt | 1 + > 1 file changed, 1 insertion(+) Acked-by: Rob Herring
Re: [PATCH v4 1/2] media: i2c: adv748x: add adv748x driver
On 26/06/17 17:14, Kieran Bingham wrote: > Hi Hans, > > Thankyou for your review, and apologies for the delay - I was OoO last week. > > > On 19/06/17 10:13, Hans Verkuil wrote: >> On 06/13/2017 02:35 AM, Kieran Bingham wrote: >>> From: Kieran Bingham>>> >>> Provide support for the ADV7481 and ADV7482. >>> >>> The driver is modelled with 4 subdevices to allow simultaneous streaming >>> from the AFE (Analog front end) and HDMI inputs though two CSI TX >>> entities. >>> >>> The HDMI entity is linked to the TXA CSI bus, whilst the AFE is linked >>> to the TXB CSI bus. >>> >>> The driver is based on a prototype by Koji Matsuoka in the Renesas BSP, >>> and an earlier rework by Niklas Söderlund. >>> >>> Signed-off-by: Kieran Bingham >>> >>> --- >>> >>> v2: >>> - Implement DT parsing >>> - adv748x: Add CSI2 entity >>> - adv748x: Rework pad allocations and fmts >>> - Give AFE 8 input pads and move pad defines >>> - Use the enums to ensure pads are referenced correctly. >>> - adv748x: Rename AFE/HDMI entities >>> Now they are 'just afe' and 'just hdmi' >>> - Reorder the entity enum and structures >>> - Added pad-format for the CSI2 entities >>> - CSI2 s_stream pass through >>> - CSI2 control pass through (with link following) >>> >>> v3: >>> - dt: Extend DT documentation to specify interrupt mappings >>> - simplify adv748x_parse_dt >>> - core: Add banner to header file describing ADV748x variants >>> - Use entity structure pointers rather than global state pointers where >>> possible >>> - afe: Reduce indent on afe_status >>> - hdmi: Add error checking to the bt->pixelclock values. >>> - Remove all unnecessary pad checks: handled by core >>> - Fix all probe cleanup paths >>> - adv748x_csi2_probe() now fails if it has no endpoint >>> - csi2: Fix small oneliners for is_txa and get_remote_sd() >>> - csi2: Fix checkpatch warnings >>> - csi2: Fix up s_stream pass-through >>> - csi2: Fix up Pixel Rate passthrough >>> - csi2: simplify adv748x_csi2_get_pad_format() >>> - Remove 'async notifiers' from AFE/HDMI >>> Using async notifiers was overkill, when we have access to the >>> subdevices internally and can register them directly. >>> - Use state lock in control handlers and clean up s_ctrls >>> - remove _interruptible mutex locks >>> >>> v4: >>> - all: Convert hex 0xXX to lowercase >>> - all: Use defines instead of hardcoded register values >>> - all: Use regmap >>> - afe, csi2, hdmi: _probe -> _init >>> - afe, csi2, hdmi: _remove -> _cleanup >>> - afe, hdmi: Convert pattern generator to a control >>> - afe, hdmi: get/set-fmt refactor >>> - afe, hdmi, csi2: Convert to internal calls for pixelrate >>> - afe: Allow the AFE to configure the Input Select from DT >>> - afe: Reduce indent on adv748x_afe_status switch >>> - afe: Remove ununsed macro definitions AIN0-7 >>> - afe: Remove extraneous control checks handled by core >>> - afe: Comment fixups >>> - afe: Rename error label >>> - afe: Correct control names on the SDP >>> - afe: Use AIN0-7 rather than AIN1-8 to match ports and MC pads >>> - core: adv748x_parse_dt references to nodes, and catch multiple >>> endpoints in a port. >>> - core: adv748x_dt_cleanup to simplify releasing DT nodes >>> - core: adv748x_print_info renamed to adv748x_identify_chip >>> - core: reorganise ordering of probe sequence >>> - core: No need for of_match_ptr >>> - core: Fix up i2c read/writes (regmap still on todo list) >>> - core: Set specific functions from the entities on subdev-init >>> - core: Use kzalloc for state instead of devm >>> - core: Improve probe error reporting >>> - core: Track unknown BIT(6) in tx{a,b}_power >>> - csi2: Improve adv748x_csi2_get_remote_sd as adv748x_csi2_get_source_sd >>> - csi2: -EPIPE instead of -ENODEV >>> - csi2: adv_dbg, instead of adv_info >>> - csi2: adv748x_csi2_set_format fix >>> - csi2: remove async notifier and sd member variables >>> - csi2: register links from the CSI2 >>> - csi2: create virtual channel helper function >>> - dt: Remove numbering from endpoints >>> - dt: describe ports and interrupts as optional >>> - dt: Re-tab >>> - hdmi: adv748x_hdmi_have_signal -> adv748x_hdmi_has_signal >>> - hdmi: fix adv748x_hdmi_read_pixelclock return checks >>> - hdmi: improve adv748x_hdmi_set_video_timings >>> - hdmi: Fix tmp variable as polarity >>> - hdmi: Improve adv748x_hdmi_s_stream >>> - hdmi: Clean up adv748x_hdmi_s_ctrl register definitions and usage >>> - hdmi: Fix up adv748x_hdmi_s_dv_timings with macro names for register >>> - hdmi: Add locking to adv748x_hdmi_g_dv_timings >>> writes and locking >>> - hdmi: adv748x_hdmi_set_de_timings function added to clarify DE writes >>> - hdmi: Use CP in control register naming to match component processor >>> - hdmi: clean up
Re: [PATCH v1 03/12] media: i2c: mt9m111: Skip chid identification
Hi Laurent, On Tue, Jun 20, 2017 at 10:48:21AM +0300, Laurent Pinchart wrote: > Hi Jacopo, > > Thank you for the patch. > > On Monday 19 Jun 2017 19:04:40 Jacopo Mondi wrote: > > Reads of chip identification code (both on registers 0x00 and 0xff) > > always return 0x00. > > This shouldn't be the case. It might mean that your I2C master controller > doesn't handle reads correctly. I don't think this patch is correct. Indeed this patch was not meant for inclusion (as it is part of an RFC series) but I still fail to read the chip identifier even when using a tool to sniff the bus or talk directly to the chip (I'm using bus pirate for this purpose). What puzzles me is that I get back reads from some registers that match the defaults reported by the data sheet, while other registers return meaningful values but different from what I have indicated as defaults in the sensor manual, while chip identifier reads always back as 0x00. I am pasting some examples down here of some interactions with the chip using bus pirate serial control console [1] I wonder if I am working with a different chip revision from the one the driver and the datasheet have as reference, but it really seems unlikely to me.. Thanks j [1] ** Read register 0x106: expected value 0x700E -> got it! I2C>[0x90+0xf0+0x00+0x1] I2C START BIT WRITE: 0x90 ACK WRITE: 0xF0 ACK WRITE: 0x00 ACK WRITE: 0x01 ACK I2C STOP BIT I2C>[0x90+0x06+[0x91+rr] I2C START BIT WRITE: 0x90 ACK WRITE: 0x06 ACK I2C START BIT WRITE: 0x91 ACK READ: 0x70 READ: ACK 0x0E NACK I2C STOP BIT ** Read register 0x108: expected value 0x0080 -> got 0xc800 I2C>[0x90+0xf0+0x00+0x1] I2C START BIT WRITE: 0x90 ACK WRITE: 0xF0 ACK WRITE: 0x00 ACK WRITE: 0x01 ACK I2C STOP BIT I2C>[0x90+0x08+[0x91+rr] I2C START BIT WRITE: 0x90 ACK WRITE: 0x08 ACK I2C START BIT WRITE: 0x91 ACK READ: 0xC8 READ: ACK 0x00 NACK I2C STOP BIT ** Read Chip ID: expected value 0x143a -> got 0x I2C>[0x90+0xf0+0x00+0x0] I2C START BIT WRITE: 0x90 ACK WRITE: 0xF0 ACK WRITE: 0x00 ACK WRITE: 0x00 ACK I2C STOP BIT I2C>[0x90+0x00+[0x91+rr] I2C START BIT WRITE: 0x90 ACK WRITE: 0x00 ACK I2C START BIT WRITE: 0x91 ACK READ: 0x00 READ: ACK 0x00 NACK I2C STOP BIT > > > Skip chip identification to have the device complete probing. > > > > Signed-off-by: Jacopo Mondi> > --- > > drivers/media/i2c/mt9m111.c | 19 --- > > 1 file changed, 19 deletions(-) > > > > diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c > > index 72e71b7..8e86d51 100644 > > --- a/drivers/media/i2c/mt9m111.c > > +++ b/drivers/media/i2c/mt9m111.c > > @@ -890,31 +890,12 @@ static struct v4l2_subdev_ops mt9m111_subdev_ops = { > > static int mt9m111_video_probe(struct i2c_client *client) > > { > > struct mt9m111 *mt9m111 = to_mt9m111(client); > > - s32 data; > > int ret; > > > > ret = mt9m111_s_power(>subdev, 1); > > if (ret < 0) > > return ret; > > > > - data = reg_read(CHIP_VERSION); > > - > > - switch (data) { > > - case 0x143a: /* MT9M111 or MT9M131 */ > > - dev_info(>dev, > > - "Detected a MT9M111/MT9M131 chip ID %x\n", data); > > - break; > > - case 0x148c: /* MT9M112 */ > > - dev_info(>dev, "Detected a MT9M112 chip ID %x\n", > data); > > - break; > > - default: > > - dev_err(>dev, > > - "No MT9M111/MT9M112/MT9M131 chip detected register > read %x\n", > > - data); > > - ret = -ENODEV; > > - goto done; > > - } > > - > > ret = mt9m111_init(mt9m111); > > if (ret) > > goto done; > > -- > Regards, > > Laurent Pinchart >
Re: [PATCH v2.1 4/7] arm64: dts: renesas: r8a7796: Add HDMI encoder instance
On Wed, Jun 21, 2017 at 2:17 PM, Laurent Pinchartwrote: > Add the HDMI encoder to the R8A7796 DT in disabled state. > > Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven (disclaimer: I'm no ports/endpoint expert). Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
[RFC PATCH] clk: renesas: cpg-mssr: Add interface for critical core clocks
With commit 72f5df2c2bbb6 ("clk: renesas: cpg-mssr: Migrate to CLK_IS_CRITICAL") we are able to handle critical module clocks. Introduce the same logic for critical core clocks. Signed-off-by: Dirk Behme--- Commit https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/clk/renesas?id=72f5df2c2bbb66d4a555cb51eb9f412abf1af77f is quite nice to avoid *module* clocks being disabled. Unfortunately, there are *core* clocks, too. E.g. using an other OS on the Cortex R7 core of the r8a7795, the 'canfd' is a quite popular core clock which shouldn't be disabled by Linux. Therefore, this patch is a proposal to use the same 'mark clocks as critical' logic implemented for the module clocks for the core clocks, too. Opinions? drivers/clk/renesas/clk-div6.c | 17 +++-- drivers/clk/renesas/clk-div6.h | 4 +++- drivers/clk/renesas/r8a7795-cpg-mssr.c | 7 +++ drivers/clk/renesas/renesas-cpg-mssr.c | 3 ++- drivers/clk/renesas/renesas-cpg-mssr.h | 8 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index 0627860..5917e05 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c @@ -18,6 +18,7 @@ #include #include +#include "renesas-cpg-mssr.h" #include "clk-div6.h" #define CPG_DIV6_CKSTP BIT(8) @@ -184,7 +185,9 @@ static const struct clk_ops cpg_div6_clock_ops = { struct clk * __init cpg_div6_register(const char *name, unsigned int num_parents, const char **parent_names, - void __iomem *reg) + void __iomem *reg, + const struct cpg_mssr_info *info, + unsigned int id) { unsigned int valid_parents; struct clk_init_data init; @@ -246,6 +249,15 @@ struct clk * __init cpg_div6_register(const char *name, init.name = name; init.ops = _div6_clock_ops; init.flags = CLK_IS_BASIC; + if (info) { + for (i = 0; i < info->num_crit_core_clks; i++) + if (id == info->crit_core_clks[i]) { + pr_devel("DIV6 %s setting CLK_IS_CRITICAL\n", +name); + init.flags |= CLK_IS_CRITICAL; + break; + } + } init.parent_names = parent_names; init.num_parents = valid_parents; @@ -298,7 +310,8 @@ static void __init cpg_div6_clock_init(struct device_node *np) for (i = 0; i < num_parents; i++) parent_names[i] = of_clk_get_parent_name(np, i); - clk = cpg_div6_register(clk_name, num_parents, parent_names, reg); + clk = cpg_div6_register(clk_name, num_parents, parent_names, reg, + NULL, 0); if (IS_ERR(clk)) { pr_err("%s: failed to register %s DIV6 clock (%ld)\n", __func__, np->name, PTR_ERR(clk)); diff --git a/drivers/clk/renesas/clk-div6.h b/drivers/clk/renesas/clk-div6.h index 567b31d..b619d6b4 100644 --- a/drivers/clk/renesas/clk-div6.h +++ b/drivers/clk/renesas/clk-div6.h @@ -2,6 +2,8 @@ #define __RENESAS_CLK_DIV6_H__ struct clk *cpg_div6_register(const char *name, unsigned int num_parents, - const char **parent_names, void __iomem *reg); + const char **parent_names, void __iomem *reg, + const struct cpg_mssr_info *info, + unsigned int id); #endif diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index eaa98b4..a54fed6 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -114,6 +114,9 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { DEF_BASE("r", R8A7795_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), }; +static const unsigned int r8a7795_crit_core_clks[] __initconst = { +}; + static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = { DEF_MOD("fdp1-2",117, R8A7795_CLK_S2D1), /* ES1.x */ DEF_MOD("fdp1-1",118, R8A7795_CLK_S0D1), @@ -441,6 +444,10 @@ const struct cpg_mssr_info r8a7795_cpg_mssr_info __initconst = { .last_dt_core_clk = LAST_DT_CORE_CLK, .num_total_core_clks = MOD_CLK_BASE, + /* Critical Core Clocks */ + .crit_core_clks = r8a7795_crit_core_clks, + .num_crit_core_clks = ARRAY_SIZE(r8a7795_crit_core_clks), + /* Module Clocks */ .mod_clks = r8a7795_mod_clks, .num_mod_clks = ARRAY_SIZE(r8a7795_mod_clks), diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index
Re: [PATCH v5 1/2] media: i2c: adv748x: add adv748x driver
Thanks Rob, Comments addressed, and a new version 6 to be posted soon. On 22/06/17 22:34, Rob Herring wrote: > On Wed, Jun 14, 2017 at 08:58:12PM +0100, Kieran Bingham wrote: >> From: Kieran Bingham>> >> Provide support for the ADV7481 and ADV7482. >> >> The driver is modelled with 4 subdevices to allow simultaneous streaming >> from the AFE (Analog front end) and HDMI inputs though two CSI TX >> entities. >> >> The HDMI entity is linked to the TXA CSI bus, whilst the AFE is linked >> to the TXB CSI bus. >> >> The driver is based on a prototype by Koji Matsuoka in the Renesas BSP, >> and an earlier rework by Niklas Söderlund. >> >> Signed-off-by: Kieran Bingham >> >> --- ... >> + >> +The digital output port nodes must contain at least one endpoint. >> + >> +Ports are optional if they are not connected to anything at the hardware >> level, >> +but the driver may not provide any support for ports which are not >> described. > > What the driver does is not relevant to the binding. Of course. (Fixed) > >> + >> +Example: >> + >> +video_receiver@70 { > > video-receiver@70 Aha, I didn't realise the distinction between using '-' in node names and properties vs '_' in labels. Hopefully updated in my mind map. And I'll try to get this one right in the future. :) -- Regards Kieran
Re: [GIT PULL for renesas-drivers] ADV748x v5 device-tree.
Hi Niklas, Kieran, On Mon, Jun 26, 2017 at 11:20 AM, Niklas Söderlundwrote: > On 2017-06-16 11:30:23 +0100, Kieran Bingham wrote: >> On 16/06/17 09:57, Geert Uytterhoeven wrote: > > On Wed, Jun 14, 2017 at 10:23 PM, Kieran Bingham > > wrote: >> >> Please consider this pull request for the next renesas-drivers release. >> >> >> >> This DT update is based on Simon's horms/next branch, but is also >> >> dependant >> >> upon Niklas' VIN driver DT nodes being integrated. >> > >> > That means "make dtbs" doesn't work in this branch? >> > I think you need to sync with Niklas, so you can build your branch on >> > top of his. >> >> Yes, that's why I tried to make that clear in the PR. sorry - as stupid as it >> was to send as is, - it is dependant upon Niklas' non-mainlined patches, and >> I >> had to post a pull request for my report for yesterday. >> >> Sorry for the red-tape induced noise :( >> >> Niklas has now made his updated DT branch available to me, so I expect to >> have >> sent an update before your next renesas-drivers anyway - Although Niklas, >> your >> rcar-vin-dt branch contains an unrelated [LOCAL] patch to defconfig. So I >> still >> can't base my dt patch on your dt-branch. > > I never intended the rcar-vin-dt branch to be submitted for > renesas-drivers (at lest not until the DT bindings where Acked). So I > intentionally left the [LOCAL] patch in that branch, but I agree the > naming is confusing in regard to that... > >> How should we handle this going forwards?. > > If we want to include the DT changes in renesas-driver I be happy to > remove the [LOCAL] patch and pay more attention to details for that > branch and include it in my for-renesas-branch. > > Geert what do you think? Do you think it's a good idea for me and Kieran > to start including the DT updates for VIN in our submissions for > renesas-drivers? If so I would like to request a quick sanity check of > my rcar-vin-dt as I'm not sure I fully got the hang of the new DT file > structure and I don't want to break things :-) If the consumers of renesas-drivers have a benefit due to including the DT changes, I think they should be included. How else can they use the new drivers and driver updates you're providing? >> I can't really base my DT branch on Niklas' as he is in concurrent active >> development. >> >> Should I pass my DT patch on to you Niklas and consider you 'upstream' for >> that >> patch? (at least in regards to renesas-drivers) > > If you like I have no problem to carry that patch in my rcar-vin-dt > branch. Let me know what you wish me to do. Either Niklas can include Kieran's patch, or Niklas can public his branch, and Kieran can base his on top of Niklas'. Which is most convenient for you is up to you. I expect the DT additions won't change once the DT bindings have been agreed upon? Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [GIT PULL for renesas-drivers] ADV748x v5 device-tree.
Hi Kieran and Geert, On 2017-06-16 11:30:23 +0100, Kieran Bingham wrote: > Hi Geert, Niklas, > > On 16/06/17 09:57, Geert Uytterhoeven wrote: > > Hi Kieran, > > > > On Wed, Jun 14, 2017 at 10:23 PM, Kieran Bingham> > wrote: > >> Please consider this pull request for the next renesas-drivers release. > >> > >> This DT update is based on Simon's horms/next branch, but is also dependant > >> upon Niklas' VIN driver DT nodes being integrated. > > > > That means "make dtbs" doesn't work in this branch? > > I think you need to sync with Niklas, so you can build your branch on > > top of his. > > Yes, that's why I tried to make that clear in the PR. sorry - as stupid as it > was to send as is, - it is dependant upon Niklas' non-mainlined patches, and I > had to post a pull request for my report for yesterday. > > Sorry for the red-tape induced noise :( > > Niklas has now made his updated DT branch available to me, so I expect to have > sent an update before your next renesas-drivers anyway - Although Niklas, your > rcar-vin-dt branch contains an unrelated [LOCAL] patch to defconfig. So I > still > can't base my dt patch on your dt-branch. I never intended the rcar-vin-dt branch to be submitted for renesas-drivers (at lest not until the DT bindings where Acked). So I intentionally left the [LOCAL] patch in that branch, but I agree the naming is confusing in regard to that... > > How should we handle this going forwards?. If we want to include the DT changes in renesas-driver I be happy to remove the [LOCAL] patch and pay more attention to details for that branch and include it in my for-renesas-branch. Geert what do you think? Do you think it's a good idea for me and Kieran to start including the DT updates for VIN in our submissions for renesas-drivers? If so I would like to request a quick sanity check of my rcar-vin-dt as I'm not sure I fully got the hang of the new DT file structure and I don't want to break things :-) > > I can't really base my DT branch on Niklas' as he is in concurrent active > development. > > Should I pass my DT patch on to you Niklas and consider you 'upstream' for > that > patch? (at least in regards to renesas-drivers) If you like I have no problem to carry that patch in my rcar-vin-dt branch. Let me know what you wish me to do. > > Then we can keep those related changes in one branch. If and when updates > happen > on my patch I can just submit them to you to update on your branch. Then we > have > a single unified place for the inherently co-dependant DT patches for VIN and > ADV748x. > > If the VIN patches make it upstream before ADV748x bindings are reviewed and > accepted, then I can take this patch back, as at that point I can base on your > upstreamed versions. > > -- > Kieran > > > > > > >> The following changes since commit > >> ab4321dedd764fb6d8fad3463a93b491aabe669d: > >> > >> Merge branches 'arm64-dt-for-v4.13', 'drivers-for-v4.13' and > >> 'soc-for-v4.13' into next (2017-06-14 11:05:24 +0200) > >> > >> are available in the git repository at: > >> > >> git://git.kernel.org/pub/scm/linux/kernel/git/kbingham/rcar.git > >> adv748x/dt > >> > >> for you to fetch changes up to eb130d9433e9cd5b6b0f33715df18697460012ee: > >> > >> arm64: dts: renesas: salvator-x: Add ADV7482 support (2017-06-14 > >> 15:46:42 +0100) > > > > Gr{oetje,eeting}s, > > > > Geert > > > > -- > > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- > > ge...@linux-m68k.org > > > > In personal conversations with technical people, I call myself a hacker. But > > when I'm talking to journalists I just say "programmer" or something like > > that. > > -- Linus Torvalds > > -- Regards, Niklas Söderlund
[RFC 8/x v2] ASoC: replace platform to component on soc-generic-dmaengine-pcm
Now platform can be replaced to component, let's do it. Signed-off-by: Kuninori Morimoto--- include/sound/dmaengine_pcm.h | 2 ++ sound/soc/soc-generic-dmaengine-pcm.c | 54 +-- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index 67be244..c2ac20f 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -19,6 +19,8 @@ #include #include +#define SND_DMAENGINE_NAME "snd_dmaengine_pcm" + /** * snd_pcm_substream_to_dma_direction - Get dma_transfer_direction for a PCM * substream diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index d537864..dcd1c7a 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -33,13 +33,13 @@ struct dmaengine_pcm { struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1]; const struct snd_dmaengine_pcm_config *config; - struct snd_soc_platform platform; + struct snd_soc_component component; unsigned int flags; }; -static struct dmaengine_pcm *soc_platform_to_pcm(struct snd_soc_platform *p) +static struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p) { - return container_of(p, struct dmaengine_pcm, platform); + return container_of(p, struct dmaengine_pcm, component); } static struct device *dmaengine_dma_dev(struct dmaengine_pcm *pcm, @@ -88,7 +88,9 @@ static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, + SND_DMAENGINE_NAME); + struct dmaengine_pcm *pcm = soc_component_to_pcm(component); struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); int (*prepare_slave_config)(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, @@ -119,7 +121,9 @@ static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream, static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, + SND_DMAENGINE_NAME); + struct dmaengine_pcm *pcm = soc_component_to_pcm(component); struct device *dma_dev = dmaengine_dma_dev(pcm, substream); struct dma_chan *chan = pcm->chan[substream->stream]; struct snd_dmaengine_dai_dma_data *dma_data; @@ -206,7 +210,9 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea static int dmaengine_pcm_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, + SND_DMAENGINE_NAME); + struct dmaengine_pcm *pcm = soc_component_to_pcm(component); struct dma_chan *chan = pcm->chan[substream->stream]; int ret; @@ -221,7 +227,9 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel( struct snd_soc_pcm_runtime *rtd, struct snd_pcm_substream *substream) { - struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, + SND_DMAENGINE_NAME); + struct dmaengine_pcm *pcm = soc_component_to_pcm(component); struct snd_dmaengine_dai_dma_data *dma_data; dma_filter_fn fn = NULL; @@ -260,9 +268,11 @@ static bool dmaengine_pcm_can_report_residue(struct device *dev, static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) { - struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, + SND_DMAENGINE_NAME); + struct dmaengine_pcm *pcm = soc_component_to_pcm(component); const struct snd_dmaengine_pcm_config *config = pcm->config; - struct device *dev = rtd->platform->dev; + struct device *dev = component->dev; struct snd_dmaengine_dai_dma_data *dma_data; struct snd_pcm_substream *substream; size_t prealloc_buffer_size; @@ -296,7 +306,7 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) } if (!pcm->chan[i]) { -
[RFC x/x v2] ASoC: remove platform related things
Now, all platform are replaced to component. This patch removes all platform code. platform_list_read_file() is replaced to component_list_read_file() Signed-off-by: Kuninori Morimoto--- include/sound/soc.h | 101 - sound/soc/soc-compress.c | 123 -- sound/soc/soc-core.c | 224 ++- sound/soc/soc-devres.c | 35 sound/soc/soc-io.c | 21 - sound/soc/soc-pcm.c | 80 + 6 files changed, 12 insertions(+), 572 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index d953912..bf0e90d 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -401,9 +401,7 @@ enum snd_soc_bias_level { struct snd_soc_pcm_runtime; struct snd_soc_dai; struct snd_soc_dai_driver; -struct snd_soc_platform; struct snd_soc_dai_link; -struct snd_soc_platform_driver; struct snd_soc_codec; struct snd_soc_codec_driver; struct snd_soc_component; @@ -455,15 +453,6 @@ static inline int snd_soc_resume(struct device *dev) } #endif int snd_soc_poweroff(struct device *dev); -int snd_soc_register_platform(struct device *dev, - const struct snd_soc_platform_driver *platform_drv); -int devm_snd_soc_register_platform(struct device *dev, - const struct snd_soc_platform_driver *platform_drv); -void snd_soc_unregister_platform(struct device *dev); -int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, - const struct snd_soc_platform_driver *platform_drv); -void snd_soc_remove_platform(struct snd_soc_platform *platform); -struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev); int snd_soc_register_codec(struct device *dev, const struct snd_soc_codec_driver *codec_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); @@ -482,11 +471,6 @@ struct snd_soc_component *snd_soc_lookup_component(struct device *dev, const char *driver_name); int snd_soc_cache_init(struct snd_soc_codec *codec); int snd_soc_cache_exit(struct snd_soc_codec *codec); - -int snd_soc_platform_read(struct snd_soc_platform *platform, - unsigned int reg); -int snd_soc_platform_write(struct snd_soc_platform *platform, - unsigned int reg, unsigned int val); int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num); #ifdef CONFIG_SND_SOC_COMPRESS int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num); @@ -617,8 +601,6 @@ int snd_soc_add_component_controls(struct snd_soc_component *component, const struct snd_kcontrol_new *controls, unsigned int num_controls); int snd_soc_add_codec_controls(struct snd_soc_codec *codec, const struct snd_kcontrol_new *controls, unsigned int num_controls); -int snd_soc_add_platform_controls(struct snd_soc_platform *platform, - const struct snd_kcontrol_new *controls, unsigned int num_controls); int snd_soc_add_card_controls(struct snd_soc_card *soc_card, const struct snd_kcontrol_new *controls, int num_controls); int snd_soc_add_dai_controls(struct snd_soc_dai *dai, @@ -800,7 +782,6 @@ struct snd_soc_component_driver { int (*suspend)(struct snd_soc_component *); int (*resume)(struct snd_soc_component *); - /* pcm creation and destruction */ int (*pcm_new)(struct snd_soc_pcm_runtime *); void (*pcm_free)(struct snd_pcm *); @@ -882,8 +863,6 @@ struct snd_soc_component { void (*remove)(struct snd_soc_component *); int (*suspend)(struct snd_soc_component *); int (*resume)(struct snd_soc_component *); - int (*pcm_new)(struct snd_soc_pcm_runtime *); - void (*pcm_free)(struct snd_pcm *); /* machine specific init */ int (*init)(struct snd_soc_component *component); @@ -969,39 +948,12 @@ struct snd_soc_codec_driver { bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */ }; -/* SoC platform interface */ -struct snd_soc_platform_driver { - - int (*probe)(struct snd_soc_platform *); - int (*remove)(struct snd_soc_platform *); - struct snd_soc_component_driver component_driver; - - /* pcm creation and destruction */ - int (*pcm_new)(struct snd_soc_pcm_runtime *); - void (*pcm_free)(struct snd_pcm *); - - /* platform stream pcm ops */ - const struct snd_pcm_ops *ops; - - /* platform stream compress ops */ - const struct snd_compr_ops *compr_ops; -}; - struct snd_soc_dai_link_component { const char *name; struct device_node *of_node; const char *dai_name; }; -struct snd_soc_platform { - struct device *dev; - const struct snd_soc_platform_driver *driver; - - struct list_head list; - - struct snd_soc_component component; -}; - struct snd_soc_dai_link { /* config - must be
[RFC 3/x v2] ASoC: soc-core: add snd_soc_rtdcom_xxx()
Current snd_soc_pcm_runtime has platform / codec pointers, and we could use these specific pointer. But these will be replaced to more generic "component" soon, and will need more generic method to get each connected component pointer from rtd. This patch adds new snd_soc_rtdcom_xxx() to connect/disconnect component to rtd. It means same as previous "platform" / "codec" pointer style, but more generic. We can find necessary component pointer from rtd by using component driver name on snd_soc_rtdcom_lookup(). Here, the reason why it uses "driver name" is that "component name" was created by fmt_single_name() and difficult to use it from driver. Driver of course knows its "driver name", thus, using it is more easy. This patch connect "platform" component to rtd as 1st step. "codec" component will be connected in the future. Signed-off-by: Kuninori Morimoto--- include/sound/soc.h | 13 + sound/soc/soc-core.c | 42 ++ 2 files changed, 55 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index 8b2b30f..ed613a7 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -891,6 +891,18 @@ struct snd_soc_component { #endif }; +struct snd_soc_rtdcom_list { + struct snd_soc_component *component; + struct list_head list; /* rtd::component_list */ +}; +struct snd_soc_component* +snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd, + const char *driver_name); +#define for_each_rtdcom(rtd, rtdcom) \ + list_for_each_entry(rtdcom, &(rtd)->component_list, list) +#define for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) \ + list_for_each_entry_safe(rtdcom1, rtdcom2, &(rtd)->component_list, list) + /* SoC Audio Codec device */ struct snd_soc_codec { struct device *dev; @@ -1250,6 +1262,7 @@ struct snd_soc_pcm_runtime { unsigned int num; /* 0-based and monotonic increasing */ struct list_head list; /* rtd list of the soc card */ + struct list_head component_list; /* list of connected components */ /* bit field */ unsigned int dev_registered:1; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4d66c47..287dec3 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -536,6 +536,46 @@ static inline void snd_soc_debugfs_exit(void) #endif +static int snd_soc_rtdcom_add(struct snd_soc_pcm_runtime *rtd, + struct snd_soc_component *component) +{ + struct snd_soc_rtdcom_list *new_rtdcom; + + new_rtdcom = kmalloc(sizeof(*new_rtdcom), GFP_KERNEL); + if (!new_rtdcom) + return -ENOMEM; + + new_rtdcom->component = component; + INIT_LIST_HEAD(_rtdcom->list); + + list_add(_rtdcom->list, >component_list); + + return 0; +} + +static void snd_soc_rtdcom_del_all(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_rtdcom_list *rtdcom1, *rtdcom2; + + for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) + kfree(rtdcom1); + + INIT_LIST_HEAD(>component_list); +} + +struct snd_soc_component* snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd, + const char *driver_name) +{ + struct snd_soc_rtdcom_list *rtdcom; + + for_each_rtdcom(rtd, rtdcom) { + if (rtdcom->component->driver->name == driver_name) + return rtdcom->component; + } + + return NULL; +} + struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, const char *dai_link, int stream) { @@ -560,6 +600,7 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( if (!rtd) return NULL; + INIT_LIST_HEAD(>component_list); rtd->card = card; rtd->dai_link = dai_link; rtd->codec_dais = kzalloc(sizeof(struct snd_soc_dai *) * @@ -577,6 +618,7 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) { if (rtd && rtd->codec_dais) kfree(rtd->codec_dais); + snd_soc_rtdcom_del_all(rtd); kfree(rtd); } -- 1.9.1
[RFC 5/x v2] ASoC: snd_soc_component_driver has snd_compr_ops
snd_soc_platform_driver has snd_compr_ops, and it will be replaced into snd_soc_component_driver in the future. To prepare it, component driver has it. After this patch, rtd->platform is no longer mandatory Signed-off-by: Kuninori Morimoto--- include/sound/soc.h | 1 + sound/soc/soc-compress.c | 366 ++- 2 files changed, 329 insertions(+), 38 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index f26897c..d953912 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -815,6 +815,7 @@ struct snd_soc_component_driver { int (*stream_event)(struct snd_soc_component *, int event); const struct snd_pcm_ops *ops; + const struct snd_compr_ops *compr_ops; /* probe ordering - for components with runtime dependencies */ int probe_order; diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index bfd71b8..a75dc5f 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -30,8 +30,10 @@ static int soc_compr_open(struct snd_compr_stream *cstream) { struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct snd_soc_platform *platform = rtd->platform; + struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; + int ret = 0, __ret; mutex_lock_nested(>pcm_mutex, rtd->pcm_subclass); @@ -44,7 +46,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream) } } - if (platform->driver->compr_ops && platform->driver->compr_ops->open) { + if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) { ret = platform->driver->compr_ops->open(cstream); if (ret < 0) { pr_err("compress asoc: can't open platform %s\n", @@ -53,6 +55,23 @@ static int soc_compr_open(struct snd_compr_stream *cstream) } } + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; + + if (!component->driver->compr_ops || + !component->driver->compr_ops->open) + continue; + + __ret = component->driver->compr_ops->open(cstream); + if (__ret < 0) { + pr_err("compress asoc: can't open platform %s\n", + component->name); + ret = __ret; + } + } + if (ret < 0) + goto machine_err; + if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) { ret = rtd->dai_link->compr_ops->startup(cstream); if (ret < 0) { @@ -68,7 +87,15 @@ static int soc_compr_open(struct snd_compr_stream *cstream) return 0; machine_err: - if (platform->driver->compr_ops && platform->driver->compr_ops->free) + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; + + if (component->driver->compr_ops && + component->driver->compr_ops->free) + component->driver->compr_ops->free(cstream); + } + + if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free) platform->driver->compr_ops->free(cstream); plat_err: if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown) @@ -83,11 +110,13 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) struct snd_soc_pcm_runtime *fe = cstream->private_data; struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream; struct snd_soc_platform *platform = fe->platform; + struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; struct snd_soc_dai *cpu_dai = fe->cpu_dai; struct snd_soc_dpcm *dpcm; struct snd_soc_dapm_widget_list *list; int stream; - int ret = 0; + int ret = 0, __ret; if (cstream->direction == SND_COMPRESS_PLAYBACK) stream = SNDRV_PCM_STREAM_PLAYBACK; @@ -106,7 +135,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) } - if (platform->driver->compr_ops && platform->driver->compr_ops->open) { + if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) { ret = platform->driver->compr_ops->open(cstream); if (ret < 0) { pr_err("compress asoc: can't open platform %s\n", @@ -115,6 +144,23 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) } } + for_each_rtdcom(fe, rtdcom) { + component = rtdcom->component; + + if (!component->driver->compr_ops || + !component->driver->compr_ops->open) +
[RFC 4/x v2] ASoC: snd_soc_component_driver has snd_pcm_ops
snd_soc_platform_driver has snd_pcm_ops, and it will be replaced into snd_soc_component_driver in the future. To prepare it, component driver has it. After this patch, rtd->platfrom is no longer mandatory Signed-off-by: Kuninori Morimoto--- include/sound/soc.h | 4 +- sound/soc/soc-core.c | 43 ++- sound/soc/soc-pcm.c | 314 --- 3 files changed, 337 insertions(+), 24 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index ed613a7..f26897c 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -814,6 +814,8 @@ struct snd_soc_component_driver { int subseq); int (*stream_event)(struct snd_soc_component *, int event); + const struct snd_pcm_ops *ops; + /* probe ordering - for components with runtime dependencies */ int probe_order; int remove_order; @@ -1247,7 +1249,7 @@ struct snd_soc_pcm_runtime { struct snd_pcm *pcm; struct snd_compr *compr; struct snd_soc_codec *codec; - struct snd_soc_platform *platform; + struct snd_soc_platform *platform; /* will be removed */ struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 287dec3..cdde8f7 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1079,6 +1079,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, struct snd_soc_dai_link_component cpu_dai_component; struct snd_soc_dai **codec_dais; struct snd_soc_platform *platform; + struct snd_soc_component *component; struct device_node *platform_of_node; const char *platform_name; int i; @@ -1128,6 +1129,22 @@ static int soc_bind_dai_link(struct snd_soc_card *card, platform_name = "snd-soc-dummy"; /* find one from the set of registered platforms */ + list_for_each_entry(component, _list, list) { + platform_of_node = component->dev->of_node; + if (!platform_of_node && component->dev->parent->of_node) + platform_of_node = component->dev->parent->of_node; + + if (dai_link->platform_of_node) { + if (platform_of_node != dai_link->platform_of_node) + continue; + } else { + if (strcmp(component->name, platform_name)) + continue; + } + + snd_soc_rtdcom_add(rtd, component); + } + list_for_each_entry(platform, _list, list) { platform_of_node = platform->dev->of_node; if (!platform_of_node && platform->dev->parent->of_node) @@ -1143,11 +1160,6 @@ static int soc_bind_dai_link(struct snd_soc_card *card, rtd->platform = platform; } - if (!rtd->platform) { - dev_err(card->dev, "ASoC: platform %s not registered\n", - dai_link->platform_name); - goto _err_defer; - } soc_add_pcm_runtime(card, rtd); return 0; @@ -1215,12 +1227,20 @@ static void soc_remove_link_components(struct snd_soc_card *card, struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_platform *platform = rtd->platform; struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; int i; /* remove the platform */ if (platform && platform->component.driver->remove_order == order) soc_remove_component(>component); + /* remove the component */ + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; + if (component->driver->remove_order == order) + soc_remove_component(component); + } + /* remove the CODEC-side CODEC */ for (i = 0; i < rtd->num_codecs; i++) { component = rtd->codec_dais[i]->component; @@ -1586,6 +1606,7 @@ static int soc_probe_link_components(struct snd_soc_card *card, { struct snd_soc_platform *platform = rtd->platform; struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; int i, ret; /* probe the CPU-side component, if it is a CODEC */ @@ -1607,12 +1628,22 @@ static int soc_probe_link_components(struct snd_soc_card *card, } /* probe the platform */ - if (platform->component.driver->probe_order == order) { + if (platform && platform->component.driver->probe_order == order) { ret = soc_probe_component(card, >component); if (ret < 0) return ret; } + /* probe the component */ + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; + if (component->driver->probe_order == order) { +
[RFC 2/x v2] ASoC: soc-devres: use expanded unregister on devm register component
Now, we have snd_soc_unregister_component_exp() which can check registered device and driver. Let's use it on devm_component_release() Signed-off-by: Kuninori Morimoto--- sound/soc/soc-devres.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c index a57921e..9194696 100644 --- a/sound/soc/soc-devres.c +++ b/sound/soc/soc-devres.c @@ -16,7 +16,7 @@ static void devm_component_release(struct device *dev, void *res) { - snd_soc_unregister_component(*(struct device **)res); + snd_soc_unregister_component_exp(dev, *(const char **)res); } /** @@ -33,7 +33,7 @@ int devm_snd_soc_register_component(struct device *dev, const struct snd_soc_component_driver *cmpnt_drv, struct snd_soc_dai_driver *dai_drv, int num_dai) { - struct device **ptr; + const char **ptr; int ret; ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL); @@ -42,7 +42,7 @@ int devm_snd_soc_register_component(struct device *dev, ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai); if (ret == 0) { - *ptr = dev; + *ptr = cmpnt_drv->name; devres_add(dev, ptr); } else { devres_free(ptr); -- 1.9.1
[RFC 1/x v2] ASoC: soc-core: add component remove/unregister_exp/lookup functions
ALSA SoC platform/codec will be replaced to component soon. This means 1 device might have multiple components. But current unregister component function only checks "dev" to find it. This means, unexpected component might be unregistered by current function. But, it is no problem if driver registered only 1 component. To avoid this issue, this patch adds new component unregister_exp/lookup/remove functions. "lookup" function finds component by "dev" and "driver name", and "remove" function removes it. "unregister_exp" will use these functions. Here, the reason why it uses "driver name" is that "component name" was created by fmt_single_name() and difficult to use it from driver. Driver of course knows its "driver name", thus, using it is more easy. Current normal unregister function is replaced to "unregister_exp" with driver_name = NULL macro. Signed-off-by: Kuninori Morimoto--- include/sound/soc.h | 7 ++- sound/soc/soc-core.c | 54 +++- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 9c94b97..8b2b30f 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -474,7 +474,12 @@ int snd_soc_register_component(struct device *dev, int devm_snd_soc_register_component(struct device *dev, const struct snd_soc_component_driver *cmpnt_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); -void snd_soc_unregister_component(struct device *dev); +#define snd_soc_unregister_component(dev) snd_soc_unregister_component_exp(dev, NULL) +void snd_soc_unregister_component_exp(struct device *dev, + const char *driver_name); +void snd_soc_remove_component(struct snd_soc_component *component); +struct snd_soc_component *snd_soc_lookup_component(struct device *dev, + const char *driver_name); int snd_soc_cache_init(struct snd_soc_codec *codec); int snd_soc_cache_exit(struct snd_soc_codec *codec); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index cfa9cf1..4d66c47 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3294,26 +3294,54 @@ int snd_soc_register_component(struct device *dev, * * @dev: The device to unregister */ -void snd_soc_unregister_component(struct device *dev) +void snd_soc_unregister_component_exp(struct device *dev, + const char *driver_name) { - struct snd_soc_component *cmpnt; + struct snd_soc_component *component; + + component = snd_soc_lookup_component(dev, driver_name); + if (!component || !component->registered_as_component) + return; + snd_soc_remove_component(component); +} +EXPORT_SYMBOL_GPL(snd_soc_unregister_component_exp); + +void snd_soc_remove_component(struct snd_soc_component *component) +{ mutex_lock(_mutex); - list_for_each_entry(cmpnt, _list, list) { - if (dev == cmpnt->dev && cmpnt->registered_as_component) - goto found; - } + snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); + snd_soc_component_del_unlocked(component); mutex_unlock(_mutex); - return; -found: - snd_soc_tplg_component_remove(cmpnt, SND_SOC_TPLG_INDEX_ALL); - snd_soc_component_del_unlocked(cmpnt); + snd_soc_component_cleanup(component); + kfree(component); +} +EXPORT_SYMBOL_GPL(snd_soc_remove_component); + +struct snd_soc_component *snd_soc_lookup_component(struct device *dev, + const char *driver_name) +{ + struct snd_soc_component *component; + struct snd_soc_component *ret; + + ret = NULL; + mutex_lock(_mutex); + list_for_each_entry(component, _list, list) { + if (dev != component->dev) + continue; + + if (driver_name && (driver_name != component->driver->name)) + continue; + + ret = component; + break; + } mutex_unlock(_mutex); - snd_soc_component_cleanup(cmpnt); - kfree(cmpnt); + + return ret; } -EXPORT_SYMBOL_GPL(snd_soc_unregister_component); +EXPORT_SYMBOL_GPL(snd_soc_lookup_component); static int snd_soc_platform_drv_probe(struct snd_soc_component *component) { -- 1.9.1
[RFC 0/x v2] ASoC: replace platform to component
Hi Mark, Lars-Peter These are v2 of platform replace patch-set. Big difference is that from version, rtd can have component list. As you know, current rtd has platform, codec, and this patch replace rtd->platform into component list. We can replace codec in same style in the future. This patch-set adds new snd_soc_rtdcom_lookup(). So, current struct snd_soc_platform *platform = rtd->platform; will be replaced into struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRIVER_NAME); 1 rtd doesn't detect same component multiple times, I guess. Thus, lookup by driver name should be OK. Current framework is listing component to card (it was originally codec) by component_dev_list. And it is used in soc-pcm.c list_for_each_entry(component, >card->component_dev_list, card_list) { ... } But it is not correct I think. card can have multiple runtimes, and runtime can have multiple components. Thus, I think we can do below case ? Card -+-> runtime1 -> component1 + component2 +-> runtime2 -> component1 + component2 +-> runtime3 -> component1 + component3 Current list_for_each_entry() will call component1/2/3, but runtime1 needs component1/2 only, for example. It is connecting all components to card by component_dev_list. OTOH, all runtimes are listed to card by rtd_list. This patch lists component to runtime. I think we can replace component_dev_list into for_each_rtdcom(rtd, rtdcom) { component = rtdcom->component; ... } 1) - 5) : prepare to replace 6) - 8) : sample of platform -> component replace 9) : remove platform Kuninori Morimoto (9): 1) ASoC: soc-core: add component remove/unregister_exp/lookup functions 2) ASoC: soc-devres: use expanded unregister on devm register component 3) ASoC: soc-core: add snd_soc_rtdcom_xxx() 4) ASoC: snd_soc_component_driver has snd_pcm_ops 5) ASoC: snd_soc_component_driver has snd_compr_ops 6) ASoC: replace platform to component on rsnd 7) ASoC: replace platform to component on soc-utils 8) ASoC: replace platform to component on soc-generic-dmaengine-pcm 9) ASoC: remove platform related things Best regards --- Kuninori Morimoto
Re: [PATCH v6 00/8] Renesas RZ/A1 pin and gpio controller
Hi Linus, On Thu, Jun 22, 2017 at 4:54 PM, Jacopo Mondiwrote: >this is 6th round of RZ/A1 pin controller patch series. > > Where did we stop: discussion from pin controller driver shifted toward two > new generic pin configuration properties I added to the previous series > (bi-directional and output-enable). > > After a really long discussion, we decided to go for handling internally all > bi-directional use cases, making the generic property not a requirement for > the > series. Interestingly, we recently found out the number of pins actually > requiring this flag is less (~half) than what reported by the processor > manual, > so we could have handled these internally from day one :( > > We also now manage internally pins requiring IO direction specified in > software > even when configured in alternate function mode (SWIO mode). Most of them are > handled by the driver, some of them have to come from DTS as the user can > freely > select if they have to be inputs or outputs. For those pins, and after another > discussion involving NXP developers, we decided to use input-enable and > output-enable properties. I have just sent a patch to add output-enable to the > generic pin configuration properties, but it is currently under discussion. > > However, none of the pins currently configured by mainline DTS require those > properties to be specified, so I have dropped in this driver any dependency on > output-enable property, and I'm using instead the already in place > PIN_CONFIG_OUTPUT one. Once output-enable will eventually be accepted, we can > update the driver to make use of it, but since there are no use cases for that > at the moment, it makes not too much sense holding this series back for that. > > The total memory occupation we were so worried about of bi-directional and > swio > pin tables is now around 100 bytes, because of how the number of pins actually > needing those flags has reduced and because of how we have arranged the > tables using bitfield structures (credits to Geert here). > > Having cleared out dependencies on new pin configuration properties and having > made configuration flags a driver specific issue, I hope this version can be > accepted and land in forthcoming pull request for Renesas PFC updates from > Geert, pending some feedback from the linux-gpio community. If this is OK for you, I'd like to include the first 3 patches (plus a small fix I received offline from Chris Brandt[*]) in my final pull request of sh-pfc for v4.13 (which I have been postponing in anticipation of this driver). After v4.13-rc1, Simon can queue up the DTS patches in his tree for v4.14. Thanks! [*] --- a/drivers/pinctrl/pinctrl-rza1.c +++ b/drivers/pinctrl/pinctrl-rza1.c @@ -617,11 +617,13 @@ static int rza1_pin_mux_single(struct rza1_pinctrl *rza1_pctl, * to I/O direction specified by pin configuration -after- PMC has been * set to one. */ - if (!(mux_flags & (MUX_FLAGS_SWIO_INPUT | MUX_FLAGS_SWIO_OUTPUT))) + if (mux_flags & (MUX_FLAGS_SWIO_INPUT | MUX_FLAGS_SWIO_OUTPUT)) + rza1_set_bit(port, RZA1_PM_REG, pin, +mux_flags & MUX_FLAGS_SWIO_INPUT); + else rza1_set_bit(port, RZA1_PIPC_REG, pin, 1); rza1_set_bit(port, RZA1_PMC_REG, pin, 1); - rza1_set_bit(port, RZA1_PM_REG, pin, mux_flags & MUX_FLAGS_SWIO_INPUT); return 0; } > v1 -> v2: > - change pin configuration flags as suggested by Chris > - gpio set direction function fixed as suggested by Chris > - add some more example on pin configuration flag usage to dt-binding doc > - fix gpio-controller names to remove unit address as suggested by Geert > - some comments chopped here and there to make the driver less verbose > > v2 -> v3: > - fix grammar and syntax in comment and documentation > - fix code style (reverse xmas tree ordering in variable declaration) > - use irqsave/irqrestore in spinlock lock/unlock > - use devm_ version of kasprintf (memory returned was not properly free) > - use bitops.h operation ffs and fls to make sure a single bit is set in pmx > mask > - Add Geert's reviewed-by to DTS patches > > v3 -> v4: > - use "pinmux" property in pmx sub-nodes in place of "renesas,pins" > - use pinconf standard properties to set pin mux additional flags > - add "bi-directional" and "output-enable" to pinconf generic properties > - perform pmx function parsing at dt_node_to_map() time > - change DT bindings to use GENERIC_PINCONF > - change DT bindings to allow sub-nodes to have "pinmux" property specified > - several renames (register names, DT parse functions, set_mux() function) > > v4 -> v5: > - use pinctrl_enable() function in pin controller registration function > - update bindings documentation to incorporate Geert's comments > - add generic properties unpack macros > > v5 -> v6: > - add tables in driver to manage bi-directional and swio flags > - drop dependecies on
Re: [PATCH] pinctrl: sh-pfc: r8a7795: Add PWM support
On Sat, Jun 24, 2017 at 12:18 PM, Laurent Pinchartwrote: > Add pinctrl support for the PWM[0-6] pins. > > Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven i.e. queuing in sh-pfc-for-v4.13. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH] dt-bindings: media: Add r8a7796 DRIF bindings
On Fri, Jun 23, 2017 at 11:25 AM, Ramesh Shanmugasundaramwrote: > Add r8a7796 DRIF bindings. > > Signed-off-by: Ramesh Shanmugasundaram > Acked-by: Geert Uytterhoeven Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
RE: [PATCH/RFC] phy: renesas: rcar-gen3-usb2-clksel: Add R-Car Gen3 USB 2.0 clock selector PHY
Hi, > -Original Message- > From: Rob Herring > Sent: Saturday, June 24, 2017 3:21 AM > > On Thu, Jun 15, 2017 at 08:34:22PM +0900, Yoshihiro Shimoda wrote: > > USB 2.0 PHY of R-Car Gen3 can change the clock source from an oscillator > > to an external clock via a register. So, this patch adds support > > the clock source selector as a generic PHY driver. > > > > Signed-off-by: Yoshihiro Shimoda> > --- > > This patch is based on the latest linux-phy.git / next branch > > (commit id = 787f24543c4a599e5d9d311a3fce839ce87bbff0) > > > > I'm not sure this driver ss OK or not as a generic phy driver. > > So, I send this patch as RFC. > > > > .../bindings/phy/rcar-gen3-phy-usb2-clksel.txt | 58 + > > drivers/phy/renesas/Kconfig| 8 ++ > > drivers/phy/renesas/Makefile | 1 + > > drivers/phy/renesas/phy-rcar-gen3-usb2-clksel.c| 129 > > + > > 4 files changed, 196 insertions(+) > > create mode 100644 > > Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2-clksel.txt > > create mode 100644 drivers/phy/renesas/phy-rcar-gen3-usb2-clksel.c > > > > diff --git > > a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2-clksel.txt > b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2-clksel.txt > > new file mode 100644 > > index 000..71b2f1b > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2-clksel.txt > > @@ -0,0 +1,58 @@ > > +* Renesas R-Car generation 3 USB 2.0 clock selector PHY > > + > > +This file provides information on what the device node for the R-Car > > generation > > +3 USB 2.0 clock selector PHY contains. > > Is this a phy or just a clock selector and nothing else? It sounds more > like the latter and you should use the clock binding. Whether this is a > phy driver in the kernel is a separate question really. Thank you for the comment. This is just a clock selector. So, I will try to make a clock driver for this. Best regards, Yoshihiro Shimoda > > + > > +If you connect an external clock to the USB_EXTAL pin, you can use the > > +"renesas,usb_extal_only" property for it. > > +If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this > > module > > +is not needed because this is default setting. > > + > > +Case 1: An external clock connects to R-Car SoC > > + +--+ +--- R-Car -+ > > + |External |---|USB_EXTAL ---> all usb channels| > > + |clock | |USB_XTAL | > > + +--+ +---+ > > +In this case, we need this driver with "usb-extal-only" property. > > + > > +Case 2: An oscillator connects to R-Car SoC > > + +--+ +--- R-Car -+ > > + |Oscillator|---|USB_EXTAL -+-> all usb channels| > > + | |---|USB_XTAL --+ | > > + +--+ +---+ > > +In this case, we don't need this selector.