[PATCH 1/2] v4l: vsp1: Add support for colorkey alpha blending
The vsp2 hw supports changing of the alpha of pixels that match a color key, this patch adds support for this feature in order to be used by the rcar-du driver. The colorkey is interpreted different depending of the pixel format: * RGB - all color components have to match. * YCbCr - only the Y component has to match. Signed-off-by: agheorghe --- drivers/media/platform/vsp1/vsp1_drm.c | 3 +++ drivers/media/platform/vsp1/vsp1_rpf.c | 10 -- drivers/media/platform/vsp1/vsp1_rwpf.h | 3 +++ include/media/vsp1.h| 3 +++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 3627f08..a4d0aee 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -393,6 +393,9 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index, else rpf->format.plane_fmt[1].bytesperline = cfg->pitch; rpf->alpha = cfg->alpha; + rpf->colorkey = cfg->colorkey; + rpf->colorkey_en = cfg->colorkey_en; + rpf->colorkey_alpha = cfg->colorkey_alpha; rpf->interlaced = cfg->interlaced; if (soc_device_match(r8a7795es1) && rpf->interlaced) { diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index a12d6f9..91f2a9f 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -356,8 +356,14 @@ static void rpf_configure(struct vsp1_entity *entity, } vsp1_rpf_write(rpf, dl, VI6_RPF_MSK_CTRL, 0); - vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_CTRL, 0); - + if (rpf->colorkey_en) { + vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_SET0, + (rpf->colorkey_alpha << 24) | rpf->colorkey); + vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_CTRL, + VI6_RPF_CKEY_CTRL_SAPE0); + } else { + vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_CTRL, 0); + } } static const struct vsp1_entity_operations rpf_entity_ops = { diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h index fbe6aa6..2d7f4b9 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.h +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h @@ -51,6 +51,9 @@ struct vsp1_rwpf { unsigned int brs_input; unsigned int alpha; + u32 colorkey; + bool colorkey_en; + u32 colorkey_alpha; u32 mult_alpha; u32 outfmt; diff --git a/include/media/vsp1.h b/include/media/vsp1.h index 97265f7..879f464 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -32,6 +32,9 @@ struct vsp1_du_atomic_config { struct v4l2_rect dst; unsigned int alpha; unsigned int zpos; + u32 colorkey; + bool colorkey_en; + u32 colorkey_alpha; bool interlaced; }; -- 1.9.1
[PATCH 0/2] rcar-du, vsp1: rcar-gen3: Add support for colorkey alpha blending
Currently, rcar-du supports colorkeying only for rcar-gen2 and it uses some hw capability of the display unit(DU) which is not available on gen3. In order to implement colorkeying for gen3 we need to use the colorkey capability of the VSPD, hence the need to change both drivers rcar-du and vsp1. This patchset had been developed and tested on top of v4.9/rcar-3.5.1 from git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas-bsp.git agheorghe (2): v4l: vsp1: Add support for colorkey alpha blending drm: rcar-du: Add support for colorkey alpha blending drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 8 drivers/gpu/drm/rcar-du/rcar_du_plane.c | 3 --- drivers/gpu/drm/rcar-du/rcar_du_plane.h | 6 ++ drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 22 ++ drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 5 + drivers/media/platform/vsp1/vsp1_drm.c | 3 +++ drivers/media/platform/vsp1/vsp1_rpf.c | 10 -- drivers/media/platform/vsp1/vsp1_rwpf.h | 3 +++ include/media/vsp1.h| 3 +++ 10 files changed, 59 insertions(+), 5 deletions(-) -- 1.9.1
[PATCH 2/2] drm: rcar-du: Add support for colorkey alpha blending
Add two new plane properties colorkey and colorkey_alpha for rcar gen3. * colorkey: - used for specifying the color on which the filtering is done. - bits 0 to 23 are interpreted as RGB888 format, in case we are dealing with an YCbCr format, only the Y componenet is compared and it is represented by the G bits from RGB888 format. - bit 24 tells if it is enabled or not. * colorkey_alpha: - the alpha to be set for matching pixels, in case it is missing the pixels will be made transparent Signed-off-by: agheorghe --- drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 8 drivers/gpu/drm/rcar-du/rcar_du_plane.c | 3 --- drivers/gpu/drm/rcar-du/rcar_du_plane.h | 6 ++ drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 22 ++ drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 5 + 6 files changed, 42 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index 91e8fc5..1cb92e3 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h @@ -98,6 +98,7 @@ struct rcar_du_device { struct { struct drm_property *alpha; struct drm_property *colorkey; + struct drm_property *colorkey_alpha; } props; unsigned int dpad0_source; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 1cc88ed..a733fa2 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -630,6 +630,14 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu) if (rcdu->props.colorkey == NULL) return -ENOMEM; + if (rcdu->info->gen == 3) { + rcdu->props.colorkey_alpha = + drm_property_create_range(rcdu->ddev, 0, + "colorkey_alpha", 0, 255); + if (!rcdu->props.colorkey_alpha) + return -ENOMEM; + } + return 0; } diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index e408aa3..df689c4 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c @@ -307,9 +307,6 @@ int rcar_du_atomic_check_planes(struct drm_device *dev, * Plane Setup */ -#define RCAR_DU_COLORKEY_NONE (0 << 24) -#define RCAR_DU_COLORKEY_SOURCE(1 << 24) -#define RCAR_DU_COLORKEY_MASK (1 << 24) static void rcar_du_plane_write(struct rcar_du_group *rgrp, unsigned int index, u32 reg, u32 data) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h index c1de338..9e7c3b6 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h @@ -49,6 +49,12 @@ static inline struct rcar_du_plane *to_rcar_plane(struct drm_plane *plane) return container_of(plane, struct rcar_du_plane, plane); } +#define RCAR_DU_COLORKEY_NONE (0 << 24) +#define RCAR_DU_COLORKEY_MASK BIT(24) +#define RCAR_DU_COLORKEY_EN_MASK RCAR_DU_COLORKEY_MASK +#define RCAR_DU_COLORKEY_COLOR_MASK0xFF +#define RCAR_DU_COLORKEY_ALPHA_MASK0xFF + /** * struct rcar_du_plane_state - Driver-specific plane state * @state: base DRM plane state diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index 4b460d4..b223be1 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c @@ -180,6 +180,11 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane) .pitch = fb->pitches[0], .alpha = state->alpha, .zpos = state->state.zpos, + .colorkey = state->colorkey & RCAR_DU_COLORKEY_COLOR_MASK, + .colorkey_en = + ((state->colorkey & RCAR_DU_COLORKEY_EN_MASK) != 0), + .colorkey_alpha = + (state->colorkey_alpha & RCAR_DU_COLORKEY_ALPHA_MASK), }; unsigned int i; @@ -379,6 +384,8 @@ static void rcar_du_vsp_plane_reset(struct drm_plane *plane) return; state->alpha = 255; + state->colorkey = RCAR_DU_COLORKEY_NONE; + state->colorkey_alpha = 0; state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1; plane->state = &state->state; @@ -394,6 +401,10 @@ static int rcar_du_vsp_plane_atomic_set_property(struct drm_plane *plane, if (property == rcdu->props.alpha) rstate->alpha = val; + else if (property == rcdu->props.colorkey) + rstate->colorkey = val; + else if (property == rcdu->props.colorkey_alpha) + rstate->colorkey_alpha = val; else r
Re: [PATCH 1/2] v4l: vsp1: Add support for colorkey alpha blending
On 05/04/2017 01:53 PM, agheorghe wrote: The vsp2 hw supports changing of the alpha of pixels that match a color key, this patch adds support for this feature in order to be used by the rcar-du driver. The colorkey is interpreted different depending of the pixel format: * RGB - all color components have to match. * YCbCr - only the Y component has to match. Signed-off-by: agheorghe Your full name is absolutely necessary here. MBR, Sergei
Re: [PATCH 1/2] v4l: vsp1: Add support for colorkey alpha blending
On Thu, May 4, 2017 at 12:53 PM, agheorghe wrote: > --- a/include/media/vsp1.h > +++ b/include/media/vsp1.h > @@ -32,6 +32,9 @@ struct vsp1_du_atomic_config { > struct v4l2_rect dst; > unsigned int alpha; > unsigned int zpos; > + u32 colorkey; > + bool colorkey_en; Please move this bool down, together with the other bool, to reduce object size due to alignment. > + u32 colorkey_alpha; > bool interlaced; > }; 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: [RFC v2 1/2] media: platform: Add SH CEU camera interface driver
Hi Jacopo, On Wednesday, May 03, 2017, jmondi wrote: > I have a proposal here, as the original driver only supported "image fetch > mode" (ie. It accepts data in YUYV with components ordering arbitrary > swapped) as a first step we may want to replicate this, ignoring data > synch fetch mode (Chris, you have a driver for this you are already using > in your BSP so I guess it's less urgent to support it, right?). My "driver" (if you can call it that) is basically 20 lines of code that sets up the registers either "image capture" mode or "data fetch". The main reason for the code was that the current CEU driver only supported "image capture" which resulted in separate Y and CbCr output buffers output, and then the app would have to merge them back together which was a waste of time (and memory). My customers simply wanted the packed format that came out of the camera. So, I created the 20 lines of code and we abandoned the CEU driver in the kernel. Also, the LCD controller (VDC5) can display a YCbCr frame buffer directly if it's packed...but not if it's a separate Y/CbCr buffers. Not to mention, if you just have a black and white camera (Y only), the Y/CbCr spilt function is totally useless and cuts your B&W image in half for no reason. My point: You can do the "image capture" mode (CAMCR:JPG=0) first, but no one will actually use the driver until the "data fetch" mode (CAMCR:JPG=1) is implemented. Chris
Re: [PATCH 2/2] drm: rcar-du: Add support for colorkey alpha blending
Hi Alexandru, On Thursday 04 May 2017 13:53:33 agheorghe wrote: > Add two new plane properties colorkey and colorkey_alpha for rcar gen3. > * colorkey: > - used for specifying the color on which the filtering is done. > - bits 0 to 23 are interpreted as RGB888 format, in case we are > dealing with an YCbCr format, only the Y componenet is > compared and it is represented by the G bits from RGB888 > format. > - bit 24 tells if it is enabled or not. > * colorkey_alpha: > - the alpha to be set for matching pixels, in case it is > missing the pixels will be made transparent Colour keying is a feature found in most display engines, and would thus benefit from standardizing the properties. Instead of adding another colorkey property specific to rcar-du, could you make a proposal to standardize it ? > Signed-off-by: agheorghe > --- > drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 + > drivers/gpu/drm/rcar-du/rcar_du_kms.c | 8 > drivers/gpu/drm/rcar-du/rcar_du_plane.c | 3 --- > drivers/gpu/drm/rcar-du/rcar_du_plane.h | 6 ++ > drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 22 ++ > drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 5 + > 6 files changed, 42 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h > b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index 91e8fc5..1cb92e3 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h > +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h > @@ -98,6 +98,7 @@ struct rcar_du_device { > struct { > struct drm_property *alpha; > struct drm_property *colorkey; > + struct drm_property *colorkey_alpha; > } props; > > unsigned int dpad0_source; > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c > b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 1cc88ed..a733fa2 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c > @@ -630,6 +630,14 @@ static int rcar_du_properties_init(struct > rcar_du_device *rcdu) if (rcdu->props.colorkey == NULL) > return -ENOMEM; > > + if (rcdu->info->gen == 3) { > + rcdu->props.colorkey_alpha = > + drm_property_create_range(rcdu->ddev, 0, > + "colorkey_alpha", 0, 255); > + if (!rcdu->props.colorkey_alpha) > + return -ENOMEM; > + } > + > return 0; > } > > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c > b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index e408aa3..df689c4 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c > @@ -307,9 +307,6 @@ int rcar_du_atomic_check_planes(struct drm_device *dev, > * Plane Setup > */ > > -#define RCAR_DU_COLORKEY_NONE(0 << 24) > -#define RCAR_DU_COLORKEY_SOURCE (1 << 24) > -#define RCAR_DU_COLORKEY_MASK(1 << 24) > > static void rcar_du_plane_write(struct rcar_du_group *rgrp, > unsigned int index, u32 reg, u32 data) > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h > b/drivers/gpu/drm/rcar-du/rcar_du_plane.h index c1de338..9e7c3b6 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h > +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h > @@ -49,6 +49,12 @@ static inline struct rcar_du_plane *to_rcar_plane(struct > drm_plane *plane) return container_of(plane, struct rcar_du_plane, plane); > } > > +#define RCAR_DU_COLORKEY_NONE(0 << 24) > +#define RCAR_DU_COLORKEY_MASKBIT(24) > +#define RCAR_DU_COLORKEY_EN_MASK RCAR_DU_COLORKEY_MASK > +#define RCAR_DU_COLORKEY_COLOR_MASK 0xFF > +#define RCAR_DU_COLORKEY_ALPHA_MASK 0xFF > + > /** > * struct rcar_du_plane_state - Driver-specific plane state > * @state: base DRM plane state > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c > b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index 4b460d4..b223be1 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c > @@ -180,6 +180,11 @@ static void rcar_du_vsp_plane_setup(struct > rcar_du_vsp_plane *plane) .pitch = fb->pitches[0], > .alpha = state->alpha, > .zpos = state->state.zpos, > + .colorkey = state->colorkey & RCAR_DU_COLORKEY_COLOR_MASK, > + .colorkey_en = > + ((state->colorkey & RCAR_DU_COLORKEY_EN_MASK) != 0), > + .colorkey_alpha = > + (state->colorkey_alpha & RCAR_DU_COLORKEY_ALPHA_MASK), > }; > unsigned int i; > > @@ -379,6 +384,8 @@ static void rcar_du_vsp_plane_reset(struct drm_plane > *plane) return; > > state->alpha = 255; > + state->colorkey = RCAR_DU_COLORKEY_NONE; > + state->colorkey_alpha = 0; > state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1; > > plane->state = &state->state; > @@ -394,6 +401
Re: [RFC v2 1/2] media: platform: Add SH CEU camera interface driver
Hi Chris, On Thursday 04 May 2017 12:23:32 Chris Brandt wrote: > On Wednesday, May 03, 2017, jmondi wrote: > > I have a proposal here, as the original driver only supported "image > > fetch mode" (ie. It accepts data in YUYV with components ordering > > arbitrary swapped) as a first step we may want to replicate this, ignoring > > data synch fetch mode (Chris, you have a driver for this you are already > > using in your BSP so I guess it's less urgent to support it, right?). > > > My "driver" (if you can call it that) is basically 20 lines of code that > sets up the registers either "image capture" mode or "data fetch". The > main reason for the code was that the current CEU driver only supported > "image capture" which resulted in separate Y and CbCr output buffers > output, and then the app would have to merge them back together which was a > waste of time (and memory). > > My customers simply wanted the packed format > that came out of the camera. So, I created the 20 lines of code and we > abandoned the CEU driver in the kernel. > > Also, the LCD controller (VDC5) can display a YCbCr frame buffer directly if > it's packed...but not if it's a separate Y/CbCr buffers. > > Not to mention, if you just have a black and white camera (Y only), the > Y/CbCr spilt function is totally useless and cuts your B&W image in half > for no reason. > > My point: You can do the "image capture" mode (CAMCR:JPG=0) first, but no > one will actually use the driver until the "data fetch" mode (CAMCR:JPG=1) > is implemented. Thanks for the feedback. I think that, given a YUV sensor, implementing support for both image capture and data fetch modes won't be difficult. Jacopo, are you OK with that ? If you implement image capture mode first, data fetch mode should be just a small additional patch. -- Regards, Laurent Pinchart
Re: [PATCH v6 2/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver
Hi Niklas, On Fri, Apr 28, 2017 at 12:36:58AM +0200, Niklas Söderlund wrote: > A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver > supports the rcar-vin driver on R-Car Gen3 SoCs where separate CSI-2 > hardware blocks are connected between the video sources and the video > grabbers (VIN). > > Driver is based on a prototype by Koji Matsuoka in the Renesas BSP. > > Signed-off-by: Niklas Söderlund > --- > drivers/media/platform/rcar-vin/Kconfig | 11 + > drivers/media/platform/rcar-vin/Makefile| 1 + > drivers/media/platform/rcar-vin/rcar-csi2.c | 872 > > 3 files changed, 884 insertions(+) > create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c > > diff --git a/drivers/media/platform/rcar-vin/Kconfig > b/drivers/media/platform/rcar-vin/Kconfig > index 111d2a151f6a4d44..f1df85d526e96a74 100644 > --- a/drivers/media/platform/rcar-vin/Kconfig > +++ b/drivers/media/platform/rcar-vin/Kconfig > @@ -1,3 +1,14 @@ > +config VIDEO_RCAR_CSI2 > + tristate "R-Car MIPI CSI-2 Receiver" > + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF > + depends on ARCH_RENESAS || COMPILE_TEST > + ---help--- > + Support for Renesas R-Car MIPI CSI-2 receiver. > + Supports R-Car Gen3 SoCs. > + > + To compile this driver as a module, choose M here: the > + module will be called rcar-csi2. > + > config VIDEO_RCAR_VIN > tristate "R-Car Video Input (VIN) Driver" > depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && > MEDIA_CONTROLLER > diff --git a/drivers/media/platform/rcar-vin/Makefile > b/drivers/media/platform/rcar-vin/Makefile > index 48c5632c21dc060b..5ab803d3e7c1aa57 100644 > --- a/drivers/media/platform/rcar-vin/Makefile > +++ b/drivers/media/platform/rcar-vin/Makefile > @@ -1,3 +1,4 @@ > rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o > > +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o > obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o > diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c > b/drivers/media/platform/rcar-vin/rcar-csi2.c > new file mode 100644 > index ..53601e171aa179b7 > --- /dev/null > +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c > @@ -0,0 +1,872 @@ > +/* > + * Driver for Renesas R-Car MIPI CSI-2 Receiver > + * > + * Copyright (C) 2017 Renesas Electronics Corp. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License as published by the > + * Free Software Foundation; either version 2 of the License, or (at your > + * option) any later version. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include Could you rebase also this on the V4L2 fwnode patchset? https://git.linuxtv.org/sailus/media_tree.git/log/?h=v4l2-acpi> > +#include > + > +/* Register offsets and bits */ > + > +/* Control Timing Select */ > +#define TREF_REG 0x00 > +#define TREF_TREF(1 << 0) > + > +/* Software Reset */ > +#define SRST_REG 0x04 > +#define SRST_SRST(1 << 0) > + > +/* PHY Operation Control */ > +#define PHYCNT_REG 0x08 > +#define PHYCNT_SHUTDOWNZ (1 << 17) > +#define PHYCNT_RSTZ (1 << 16) > +#define PHYCNT_ENABLECLK (1 << 4) > +#define PHYCNT_ENABLE_3 (1 << 3) > +#define PHYCNT_ENABLE_2 (1 << 2) > +#define PHYCNT_ENABLE_1 (1 << 1) > +#define PHYCNT_ENABLE_0 (1 << 0) > + > +/* Checksum Control */ > +#define CHKSUM_REG 0x0c > +#define CHKSUM_ECC_EN(1 << 1) > +#define CHKSUM_CRC_EN(1 << 0) > + > +/* > + * Channel Data Type Select > + * VCDT[0-15]: Channel 1 VCDT[16-31]: Channel 2 > + * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4 > + */ > +#define VCDT_REG 0x10 > +#define VCDT2_REG0x14 > +#define VCDT_VCDTN_EN(1 << 15) > +#define VCDT_SEL_VC(n) (((n) & 0x3) << 8) > +#define VCDT_SEL_DTN_ON (1 << 6) > +#define VCDT_SEL_DT(n) (((n) & 0x1f) << 0) > + > +/* Frame Data Type Select */ > +#define FRDT_REG 0x18 > + > +/* Field Detection Control */ > +#define FLD_REG 0x1c > +#define FLD_FLD_NUM(n) (((n) & 0xff) << 16) > +#define FLD_FLD_EN4 (1 << 3) > +#define FLD_FLD_EN3 (1 << 2) > +#define FLD_FLD_EN2 (1 << 1) > +#define FLD_FLD_EN (1 << 0) > + > +/* Automatic Standby Control */ > +#define ASTBY_REG0x20 > + > +/* Long Data Type Setting 0 */ > +#define LNGDT0_REG 0x28 > + > +/* Long Data Type Setting
Re: [PATCH v4 12/27] rcar-vin: read subdevice format for crop only when needed
Hi Niklas, On Fri, Apr 28, 2017 at 12:41:48AM +0200, Niklas Söderlund wrote: > Instead of caching the subdevice format each time the video device > format is set read it directly when its needed. As it turns out the > format is only needed when figuring out the max rectangle for cropping. > > This simplify the code and makes it clearer what the source format is > used for. > > Signed-off-by: Niklas Söderlund > --- > drivers/media/platform/rcar-vin/rcar-v4l2.c | 76 > - > drivers/media/platform/rcar-vin/rcar-vin.h | 12 - > 2 files changed, 42 insertions(+), 46 deletions(-) > > diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c > b/drivers/media/platform/rcar-vin/rcar-v4l2.c > index 919040e40aec60f6..80421421625e6f6f 100644 > --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c > +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c > @@ -90,6 +90,24 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format > *pix) > * V4L2 > */ > > +static int rvin_get_sd_format(struct rvin_dev *vin, struct v4l2_pix_format > *pix) > +{ > + struct v4l2_subdev_format fmt = { > + .which = V4L2_SUBDEV_FORMAT_ACTIVE, > + }; > + int ret; > + > + fmt.pad = vin->digital.source_pad; You can assign .pad in declaration, too. > + > + ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt); > + if (ret) > + return ret; > + > + v4l2_fill_pix_format(pix, &fmt.format); > + > + return 0; > +} -- Regards, Sakari Ailus e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk
Re: [PATCH v4 16/27] rcar-vin: add functions to manipulate Gen3 CHSEL value
Hi Niklas, On Fri, Apr 28, 2017 at 12:41:52AM +0200, Niklas Söderlund wrote: > On Gen3 the CSI-2 routing is controlled by the VnCSI_IFMD register. One > feature of this register is that it's only present in the VIN0 and VIN4 > instances. The register in VIN0 controls the routing for VIN0-3 and the > register in VIN4 controls routing for VIN4-7. > > To be able to control routing from a media device these functions need > to control runtime PM for the subgroup master (VIN0 and VIN4). The > subgroup master must be switched on before the register is manipulated, > once the operation is complete it's safe to switch the master off and > the new routing will still be in effect. > > Signed-off-by: Niklas Söderlund > --- > drivers/media/platform/rcar-vin/rcar-dma.c | 43 > ++ > drivers/media/platform/rcar-vin/rcar-vin.h | 3 +++ > 2 files changed, 46 insertions(+) > > diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c > b/drivers/media/platform/rcar-vin/rcar-dma.c > index 7fecb616b6c45a32..fef31aac0ed40979 100644 > --- a/drivers/media/platform/rcar-vin/rcar-dma.c > +++ b/drivers/media/platform/rcar-vin/rcar-dma.c > @@ -16,6 +16,7 @@ > > #include > #include > +#include > > #include > > @@ -1240,3 +1241,45 @@ int rvin_dma_probe(struct rvin_dev *vin, int irq) > > return ret; > } > + > +/* > - > + * Gen3 CHSEL manipulation > + */ > + > +int rvin_set_chsel(struct rvin_dev *vin, u8 chsel) > +{ > + u32 ifmd; > + > + pm_runtime_get_sync(vin->dev); Can this fail? Just wondering. > + > + /* > + * Undocumented feature: Writing to VNCSI_IFMD_REG will go > + * through and on read back look correct but won't have > + * any effect if VNMC_REG is not first set to 0. > + */ > + rvin_write(vin, 0, VNMC_REG); > + > + ifmd = VNCSI_IFMD_DES2 | VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 | > + VNCSI_IFMD_CSI_CHSEL(chsel); > + > + rvin_write(vin, ifmd, VNCSI_IFMD_REG); > + > + vin_dbg(vin, "Set IFMD 0x%x\n", ifmd); > + > + pm_runtime_put(vin->dev); > + > + return 0; If you always return zero, how about void instead? > +} > + > +int rvin_get_chsel(struct rvin_dev *vin) > +{ > + int chsel; > + > + pm_runtime_get_sync(vin->dev); Same here. > + > + chsel = rvin_read(vin, VNCSI_IFMD_REG) & VNCSI_IFMD_CSI_CHSEL_MASK; > + > + pm_runtime_put(vin->dev); > + > + return chsel; > +} > diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h > b/drivers/media/platform/rcar-vin/rcar-vin.h > index 09fc70e192699f35..b1cd0abba9ca9c94 100644 > --- a/drivers/media/platform/rcar-vin/rcar-vin.h > +++ b/drivers/media/platform/rcar-vin/rcar-vin.h > @@ -163,4 +163,7 @@ void rvin_v4l2_remove(struct rvin_dev *vin); > > const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat); > > +int rvin_set_chsel(struct rvin_dev *vin, u8 chsel); > +int rvin_get_chsel(struct rvin_dev *vin); > + > #endif -- Kind regards, Sakari Ailus e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk
Re: [PATCH v4 20/27] rcar-vin: register a media pad if running in media controller mode
On Fri, Apr 28, 2017 at 12:41:56AM +0200, Niklas Söderlund wrote: > When running in media controller mode a media pad is needed, register > one. > > Signed-off-by: Niklas Söderlund > --- > drivers/media/platform/rcar-vin/rcar-core.c | 9 + > drivers/media/platform/rcar-vin/rcar-vin.h | 4 > 2 files changed, 13 insertions(+) > > diff --git a/drivers/media/platform/rcar-vin/rcar-core.c > b/drivers/media/platform/rcar-vin/rcar-core.c > index 7aaa01dee014d64b..f560d27449b84882 100644 > --- a/drivers/media/platform/rcar-vin/rcar-core.c > +++ b/drivers/media/platform/rcar-vin/rcar-core.c > @@ -267,7 +267,16 @@ static int rvin_group_init(struct rvin_dev *vin) > if (ret) > return ret; > > + vin->pad.flags = MEDIA_PAD_FL_SINK; > + ret = media_entity_pads_init(&vin->vdev->entity, 1, &vin->pad); > + if (ret) > + goto error_v4l2; > + > return 0; This would benefit from an extra newline. > +error_v4l2: > + rvin_v4l2_mc_remove(vin); > + > + return ret; > } > > /* > - > diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h > b/drivers/media/platform/rcar-vin/rcar-vin.h > index 6f2b1e28381678a9..06934313950253f4 100644 > --- a/drivers/media/platform/rcar-vin/rcar-vin.h > +++ b/drivers/media/platform/rcar-vin/rcar-vin.h > @@ -103,6 +103,8 @@ struct rvin_info { > * @notifier:V4L2 asynchronous subdevs notifier > * @digital: entity in the DT for local digital subdevice > * > + * @pad: pad for media controller > + * > * @lock:protects @queue > * @queue: vb2 buffers queue > * > @@ -132,6 +134,8 @@ struct rvin_dev { > struct v4l2_async_notifier notifier; > struct rvin_graph_entity digital; > > + struct media_pad pad; > + > struct mutex lock; > struct vb2_queue queue; > -- Sakari Ailus e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk
Re: [PATCH v4 19/27] rcar-vin: use different v4l2 operations in media controller mode
Hi Niklas, On Fri, Apr 28, 2017 at 12:41:55AM +0200, Niklas Söderlund wrote: > When the driver runs in media controller mode it should not directly > control the subdevice instead userspace will be responsible for > configuring the pipeline. To be able to run in this mode a different set > of v4l2 operations needs to be used. > > Add a new set of v4l2 operations to support the running without directly > interacting with the source subdevice. > > Signed-off-by: Niklas Söderlund > --- > drivers/media/platform/rcar-vin/rcar-core.c | 25 ++- > drivers/media/platform/rcar-vin/rcar-dma.c | 3 +- > drivers/media/platform/rcar-vin/rcar-v4l2.c | 239 > > drivers/media/platform/rcar-vin/rcar-vin.h | 3 + > 4 files changed, 268 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/platform/rcar-vin/rcar-core.c > b/drivers/media/platform/rcar-vin/rcar-core.c > index 8b30d8d3ec7d9c04..7aaa01dee014d64b 100644 > --- a/drivers/media/platform/rcar-vin/rcar-core.c > +++ b/drivers/media/platform/rcar-vin/rcar-core.c > @@ -256,6 +256,21 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) > } > > /* > - > + * Group async notifier > + */ > + > +static int rvin_group_init(struct rvin_dev *vin) > +{ > + int ret; > + > + ret = rvin_v4l2_mc_probe(vin); > + if (ret) > + return ret; > + > + return 0; > +} > + > +/* > - > * Platform Device Driver > */ > > @@ -347,7 +362,10 @@ static int rcar_vin_probe(struct platform_device *pdev) > if (ret) > return ret; > > - ret = rvin_digital_graph_init(vin); > + if (vin->info->use_mc) > + ret = rvin_group_init(vin); > + else > + ret = rvin_digital_graph_init(vin); > if (ret < 0) > goto error; > > @@ -371,6 +389,11 @@ static int rcar_vin_remove(struct platform_device *pdev) > > v4l2_async_notifier_unregister(&vin->notifier); > > + if (vin->info->use_mc) > + rvin_v4l2_mc_remove(vin); > + else > + rvin_v4l2_remove(vin); > + > rvin_dma_remove(vin); > > return 0; > diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c > b/drivers/media/platform/rcar-vin/rcar-dma.c > index fef31aac0ed40979..34f01f32bab7bd32 100644 > --- a/drivers/media/platform/rcar-vin/rcar-dma.c > +++ b/drivers/media/platform/rcar-vin/rcar-dma.c > @@ -628,7 +628,8 @@ static int rvin_setup(struct rvin_dev *vin) > /* Default to TB */ > vnmc = VNMC_IM_FULL; > /* Use BT if video standard can be read and is 60 Hz format */ > - if (!v4l2_subdev_call(vin_to_source(vin), video, g_std, &std)) { > + if (!vin->info->use_mc && > + !v4l2_subdev_call(vin_to_source(vin), video, g_std, &std)) { > if (std & V4L2_STD_525_60) > vnmc = VNMC_IM_FULL | VNMC_FOC; > } > diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c > b/drivers/media/platform/rcar-vin/rcar-v4l2.c > index 1ee9dcb621350f77..ae6910ac87ec7f6a 100644 > --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c > +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c > @@ -23,6 +23,9 @@ > #include "rcar-vin.h" > > #define RVIN_DEFAULT_FORMAT V4L2_PIX_FMT_YUYV > +#define RVIN_DEFAULT_WIDTH 800 > +#define RVIN_DEFAULT_HEIGHT 600 > +#define RVIN_DEFAULT_COLORSPACE V4L2_COLORSPACE_SRGB > > /* > - > * Format Conversions > @@ -694,6 +697,126 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = { > }; > > /* > - > + * V4L2 Media Controller > + */ > + > +static int __rvin_mc_try_format(struct rvin_dev *vin, > + struct v4l2_pix_format *pix) > +{ > + const struct rvin_video_format *info; > + u32 walign; > + > + /* Keep current field if no specific one is asked for */ > + if (pix->field == V4L2_FIELD_ANY) > + pix->field = vin->format.field; > + > + switch (pix->field) { > + case V4L2_FIELD_TOP: > + case V4L2_FIELD_BOTTOM: > + case V4L2_FIELD_ALTERNATE: > + case V4L2_FIELD_NONE: > + case V4L2_FIELD_INTERLACED_TB: > + case V4L2_FIELD_INTERLACED_BT: > + case V4L2_FIELD_INTERLACED: > + break; > + default: > + pix->field = V4L2_FIELD_NONE; > + break; > + } > + > + /* Check that colorspace is resonable, if not keep current */ > + if (!pix->colorspace || pix->colorspace >= 0xff) > + pix->colorspace = vin->format.colorspace; > + > + info = rvin_format_from_pixel(pix->pixelformat); > + if (!info) { > + vin_dbg(vin, "Format %x not found, keeping %x\
[renesas-drivers:topic/renesas-overlays 1/89] drivers/of/configfs.c:48:2: error: implicit declaration of function 'of_fdt_unflatten_tree'
tree: https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git topic/renesas-overlays head: 85464a2def291406ca925e116563279dcfbc39ad commit: 80ff838084a7bff831cf17bd939dc736b48d6a12 [1/89] OF: DT-Overlay configfs interface (v7) config: sparc64-allmodconfig (attached as .config) compiler: sparc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout 80ff838084a7bff831cf17bd939dc736b48d6a12 # save the attached .config to linux build tree make.cross ARCH=sparc64 All errors (new ones prefixed by >>): drivers/of/configfs.c: In function 'create_overlay': >> drivers/of/configfs.c:48:2: error: implicit declaration of function >> 'of_fdt_unflatten_tree' [-Werror=implicit-function-declaration] of_fdt_unflatten_tree(blob, NULL, &overlay->overlay); ^ In file included from include/linux/kernel.h:13:0, from include/linux/list.h:8, from include/linux/kobject.h:20, from include/linux/device.h:17, from include/linux/node.h:17, from include/linux/cpu.h:16, from drivers/of/configfs.c:12: drivers/of/configfs.c: In function 'cfs_overlay_item_dtbo_read': drivers/of/configfs.c:153:11: warning: format '%u' expects argument of type 'unsigned int', but argument 5 has type 'size_t {aka long unsigned int}' [-Wformat=] pr_debug("%s: buf=%p max_count=%u\n", __func__, ^ include/linux/printk.h:285:21: note: in definition of macro 'pr_fmt' #define pr_fmt(fmt) fmt ^~~ include/linux/printk.h:333:2: note: in expansion of macro 'dynamic_pr_debug' dynamic_pr_debug(fmt, ##__VA_ARGS__) ^~~~ drivers/of/configfs.c:153:2: note: in expansion of macro 'pr_debug' pr_debug("%s: buf=%p max_count=%u\n", __func__, ^~~~ cc1: some warnings being treated as errors vim +/of_fdt_unflatten_tree +48 drivers/of/configfs.c 42 43 static int create_overlay(struct cfs_overlay_item *overlay, void *blob) 44 { 45 int err; 46 47 /* unflatten the tree */ > 48 of_fdt_unflatten_tree(blob, NULL, &overlay->overlay); 49 if (overlay->overlay == NULL) { 50 pr_err("%s: failed to unflatten tree\n", __func__); 51 err = -EINVAL; --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v4 21/27] rcar-vin: add group allocator functions
Hi Niklas, On Fri, Apr 28, 2017 at 12:41:57AM +0200, Niklas Söderlund wrote: > In media controller mode all VIN instances needs to be part of the same > media graph. There is also a need to each VIN instance to know and in > some cases be able to communicate with other VIN instances. > > Add a allocator framework where the first VIN instance to be probed > creates a shared data structure and creates a media device. > > Signed-off-by: Niklas Söderlund > --- > drivers/media/platform/rcar-vin/rcar-core.c | 112 > +++- > drivers/media/platform/rcar-vin/rcar-vin.h | 38 ++ > 2 files changed, 147 insertions(+), 3 deletions(-) > > diff --git a/drivers/media/platform/rcar-vin/rcar-core.c > b/drivers/media/platform/rcar-vin/rcar-core.c > index f560d27449b84882..c10770d5ec37816c 100644 > --- a/drivers/media/platform/rcar-vin/rcar-core.c > +++ b/drivers/media/platform/rcar-vin/rcar-core.c > @@ -20,12 +20,110 @@ > #include > #include > #include > +#include > > #include > > #include "rcar-vin.h" > > /* > - > + * Gen3 CSI2 Group Allocator > + */ > + > +static DEFINE_MUTEX(rvin_group_lock); > +static struct rvin_group *rvin_group_data; Uh-oh. It'd be nice to find a way for managing the group of devices without a global list for the group. Do all the callers operating on a group have some kind of identifying information, e.g. OF node or struct device? Could it be used to obtain the group? I'm not sure if this would be a real problem though as long as you have only a single group in a system. > + > +static void rvin_group_release(struct kref *kref) > +{ > + struct rvin_group *group = > + container_of(kref, struct rvin_group, refcount); > + > + mutex_lock(&rvin_group_lock); > + > + media_device_unregister(&group->mdev); > + media_device_cleanup(&group->mdev); > + > + rvin_group_data = NULL; > + > + mutex_unlock(&rvin_group_lock); > + > + kfree(group); > +} > + > +static struct rvin_group *__rvin_group_allocate(struct rvin_dev *vin) > +{ > + struct rvin_group *group; > + > + if (rvin_group_data) { > + group = rvin_group_data; > + kref_get(&group->refcount); > + vin_dbg(vin, "%s: get group=%p\n", __func__, group); > + return group; > + } > + > + group = kzalloc(sizeof(*group), GFP_KERNEL); > + if (!group) > + return NULL; > + > + kref_init(&group->refcount); > + rvin_group_data = group; > + > + vin_dbg(vin, "%s: alloc group=%p\n", __func__, group); > + return group; > +} > + > +static struct rvin_group *rvin_group_allocate(struct rvin_dev *vin) > +{ > + struct rvin_group *group; > + struct media_device *mdev; > + int ret; > + > + mutex_lock(&rvin_group_lock); > + > + group = __rvin_group_allocate(vin); > + if (!group) { > + mutex_unlock(&rvin_group_lock); > + return ERR_PTR(-ENOMEM); > + } > + > + /* Init group data if its not already initialized */ > + mdev = &group->mdev; > + if (!mdev->dev) { > + mutex_init(&group->lock); > + mdev->dev = vin->dev; > + > + strlcpy(mdev->driver_name, "Renesas VIN", > + sizeof(mdev->driver_name)); > + strlcpy(mdev->model, vin->dev->of_node->name, > + sizeof(mdev->model)); > + strlcpy(mdev->bus_info, of_node_full_name(vin->dev->of_node), > + sizeof(mdev->bus_info)); > + mdev->driver_version = LINUX_VERSION_CODE; > + media_device_init(mdev); > + > + ret = media_device_register(mdev); > + if (ret) { > + vin_err(vin, "Failed to register media device\n"); > + kref_put(&group->refcount, rvin_group_release); > + mutex_unlock(&rvin_group_lock); > + return ERR_PTR(ret); > + } > + } > + > + vin->v4l2_dev.mdev = mdev; > + > + mutex_unlock(&rvin_group_lock); > + > + return group; > +} > + > +static void rvin_group_delete(struct rvin_dev *vin) > +{ > + vin_dbg(vin, "%s: group=%p\n", __func__, &vin->group); > + kref_put(&vin->group->refcount, rvin_group_release); > +} > + > +/* > - > * Async notifier > */ > > @@ -263,9 +361,13 @@ static int rvin_group_init(struct rvin_dev *vin) > { > int ret; > > + vin->group = rvin_group_allocate(vin); > + if (IS_ERR(vin->group)) > + return PTR_ERR(vin->group); > + > ret = rvin_v4l2_mc_probe(vin); > if (ret) > - return ret; > + goto error_group; > > vin->pad.flags = MEDIA_PAD_FL_SINK; > ret = media_entity_pads_init(&vin->vdev->entity, 1, &vin->pad); > @@ -275,6 +377,8 @@ static int rvin_group_init(st
Re: [PATCH v4 16/27] rcar-vin: add functions to manipulate Gen3 CHSEL value
Hi Sakari, On Thu, May 4, 2017 at 4:45 PM, Sakari Ailus wrote: >> --- a/drivers/media/platform/rcar-vin/rcar-dma.c >> +++ b/drivers/media/platform/rcar-vin/rcar-dma.c >> @@ -16,6 +16,7 @@ >> >> #include >> #include >> +#include >> >> #include >> >> @@ -1240,3 +1241,45 @@ int rvin_dma_probe(struct rvin_dev *vin, int irq) >> >> return ret; >> } >> + >> +/* >> - >> + * Gen3 CHSEL manipulation >> + */ >> + >> +int rvin_set_chsel(struct rvin_dev *vin, u8 chsel) >> +{ >> + u32 ifmd; >> + >> + pm_runtime_get_sync(vin->dev); > > Can this fail? Just wondering. In theory, yes. In practice, no, unless the system is completely broken. 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 v3 3/6] spi: Document SPI slave controller support
Signed-off-by: Geert Uytterhoeven --- v3: - No changes, v2: - New. --- Documentation/spi/spi-summary | 27 --- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary index d1824b399b2d1d79..1721c1b570c32466 100644 --- a/Documentation/spi/spi-summary +++ b/Documentation/spi/spi-summary @@ -62,8 +62,8 @@ chips described as using "three wire" signaling: SCK, data, nCSx. (That data line is sometimes called MOMI or SISO.) Microcontrollers often support both master and slave sides of the SPI -protocol. This document (and Linux) currently only supports the master -side of SPI interactions. +protocol. This document (and Linux) supports both the master and slave +sides of SPI interactions. Who uses it? On what kinds of systems? @@ -154,9 +154,8 @@ control audio interfaces, present touchscreen sensors as input interfaces, or monitor temperature and voltage levels during industrial processing. And those might all be sharing the same controller driver. -A "struct spi_device" encapsulates the master-side interface between -those two types of driver. At this writing, Linux has no slave side -programming interface. +A "struct spi_device" encapsulates the controller-side interface between +those two types of drivers. There is a minimal core of SPI programming interfaces, focussing on using the driver model to connect controller and protocol drivers using @@ -177,10 +176,24 @@ shows up in sysfs in several locations: /sys/bus/spi/drivers/D ... driver for one or more spi*.* devices /sys/class/spi_master/spiB ... symlink (or actual device node) to - a logical node which could hold class related state for the - controller managing bus "B". All spiB.* devices share one + a logical node which could hold class related state for the SPI + master controller managing bus "B". All spiB.* devices share one physical SPI bus segment, with SCLK, MOSI, and MISO. + /sys/devices/.../CTLR/slave ... virtual file for (un)registering the + slave device for an SPI slave controller. + Writing the driver name of an SPI slave handler to this file + registers the slave device; writing "(null)" unregisters the slave + device. + Reading from this file shows the name of the slave device ("(null)" + if not registered). + + /sys/class/spi_slave/spiB ... symlink (or actual device node) to + a logical node which could hold class related state for the SPI + slave controller on bus "B". When registered, a single spiB.* + device is present here, possible sharing the physical SPI bus + segment with other SPI slave devices. + Note that the actual location of the controller's class state depends on whether you enabled CONFIG_SYSFS_DEPRECATED or not. At this time, the only class-specific state is the bus number ("B" in "spiB"), so -- 2.7.4
[PATCH v3 6/6] spi: slave: Add SPI slave handler controlling system state
Add an example SPI slave handler to allow remote control of system reboot, power off, halt, and suspend. Signed-off-by: Geert Uytterhoeven --- v3: - No changes, v2: - Use spi_async() instead of spi_read(), - Submit the next transfer from the previous transfer's completion callback, removing the need for a thread, - Let .remove() call spi_slave_abort() to cancel the current ongoing transfer, and wait for the completion to terminate, - Remove FIXME about hanging kthread_stop(), - Fix copy-and-pasted module description. --- drivers/spi/Kconfig| 6 ++ drivers/spi/Makefile | 1 + drivers/spi/spi-slave-system-control.c | 154 + 3 files changed, 161 insertions(+) create mode 100644 drivers/spi/spi-slave-system-control.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ade542c5bfd87e37..e6d9e329a3801d6d 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -802,6 +802,12 @@ config SPI_SLAVE_TIME SPI slave handler responding with the time of reception of the last SPI message. +config SPI_SLAVE_SYSTEM_CONTROL + tristate "SPI slave handler controlling system state" + help + SPI slave handler to allow remote control of system reboot, power + off, halt, and suspend. + endif # SPI_SLAVE endif # SPI diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index fb078693dbe40da4..1d7923e8c63bc22b 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -108,3 +108,4 @@ obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o # SPI slave protocol handlers obj-$(CONFIG_SPI_SLAVE_TIME) += spi-slave-time.o +obj-$(CONFIG_SPI_SLAVE_SYSTEM_CONTROL) += spi-slave-system-control.o diff --git a/drivers/spi/spi-slave-system-control.c b/drivers/spi/spi-slave-system-control.c new file mode 100644 index ..736dd59928cb3bc3 --- /dev/null +++ b/drivers/spi/spi-slave-system-control.c @@ -0,0 +1,154 @@ +/* + * SPI slave handler controlling system state + * + * This SPI slave handler allows remote control of system reboot, power off, + * halt, and suspend. + * + * Copyright (C) 2016 Glider bvba + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include + +/* + * The numbers are chosen to display something human-readable on two 7-segment + * displays connected to two 74HC595 shift registers + */ +#define CMD_REBOOT 0x507c /* rb */ +#define CMD_POWEROFF 0x3f71 /* OF */ +#define CMD_HALT 0x7638 /* HL */ +#define CMD_SUSPEND0x1b1b /* ZZ */ + +struct spi_slave_system_control_priv { + struct spi_device *spi; + struct completion finished; + struct spi_transfer xfer; + struct spi_message msg; + __le16 cmd; +}; + +static +int spi_slave_system_control_submit(struct spi_slave_system_control_priv *priv); + +static void spi_slave_system_control_complete(void *arg) +{ + struct spi_slave_system_control_priv *priv = arg; + u16 cmd; + int ret; + + if (priv->msg.status) + goto terminate; + + cmd = le16_to_cpu(priv->cmd); + switch (cmd) { + case CMD_REBOOT: + pr_info("Rebooting system...\n"); + kernel_restart(NULL); + + case CMD_POWEROFF: + pr_info("Powering off system...\n"); + kernel_power_off(); + break; + + case CMD_HALT: + pr_info("Halting system...\n"); + kernel_halt(); + break; + + case CMD_SUSPEND: + pr_info("Suspending system...\n"); + pm_suspend(PM_SUSPEND_MEM); + break; + + default: + pr_warn("%s: Unknown command 0x%x\n", __func__, cmd); + break; + } + + ret = spi_slave_system_control_submit(priv); + if (ret) + goto terminate; + + return; + +terminate: + pr_info("%s: Terminating\n", __func__); + complete(&priv->finished); +} + +static +int spi_slave_system_control_submit(struct spi_slave_system_control_priv *priv) +{ + int ret; + + spi_message_init_with_transfers(&priv->msg, &priv->xfer, 1); + + priv->msg.complete = spi_slave_system_control_complete; + priv->msg.context = priv; + + ret = spi_async(priv->spi, &priv->msg); + if (ret) + pr_err("%s: spi_async() failed %d\n", __func__, ret); + + return ret; +} + +static int spi_slave_system_control_probe(struct spi_device *spi) +{ + struct spi_slave_system_control_priv *priv; + int ret; + + /* +* bits_per_word cannot be configured in platform data +*/ + spi->bits_per_word = 8; + + ret = spi_setup(spi); + if (ret < 0) + return ret; +
[PATCH v3 2/6] spi: core: Add support for registering SPI slave controllers
Add support for registering SPI slave controllers using the existing SPI master framework: - SPI slave controllers must use spi_alloc_slave() instead of spi_alloc_master(), and should provide an additional callback "slave_abort" to abort an ongoing SPI transfer request, - SPI slave controllers are added to a new "spi_slave" device class, - SPI slave handlers can be bound to the SPI slave device represented by an SPI slave controller using a DT child node named "slave", - Alternatively, (un)binding an SPI slave handler to the SPI slave device represented by an SPI slave controller can be done by (un)registering the slave device through a sysfs virtual file named "slave". >From the point of view of an SPI slave protocol handler, an SPI slave controller looks almost like an ordinary SPI master controller. The only exception is that a transfer request will block on the remote SPI master, and may be cancelled using spi_slave_abort(). Signed-off-by: Geert Uytterhoeven --- v3: - Introduce a separate spi_alloc_slave() function, which sets up the spi_slave_class instead of the spi_master class, to avoid the WARN() in device_release(), - Wrap spi_alloc_{master,slave}() around __spi_alloc_controller(), - Replace the SPI_CONTROLLER_IS_SLAVE flag in spi_master.flags (set by the SPI controller driver) by a bool in spi_master (set by __spi_alloc_controller()), - Revert parsing of slave-specific mode properties in the SPI slave controller DT node for the (single) slave device, - Register again children from DT or ACPI for SPI slave controllers; the single optional slave child node must be called "slave", - Let {acpi,of}_spi_notify() also search spi_slave_class devices, - Use octal instead of symbolic permissions, - s/hander/handler/, v2: - Attach SPI slave controllers to a new "spi_slave" device class, - Don't call of_spi_register_master() instead of letting it return early for SPI slave controllers, - Skip registration of children from DT or ACPI for SPI slave controllers, - Use a "slave" virtual file in sysfs to (un)register the (single) slave device for an SPI slave controller, incl. specifying the slave protocol handler, - Parse slave-specific mode properties in the SPI slave controller DT node for the (single) slave device using of_spi_parse_dt(), - Add cancellation support using spi_master.slave_abort() and spi_slave_abort(), - Rename flag SPI_MASTER_IS_SLAVE to SPI_CONTROLLER_IS_SLAVE, - Introduce helper function spi_controller_is_slave(), making it easy to leave out SPI slave support where appropriate. --- drivers/spi/Kconfig | 14 +++- drivers/spi/Makefile| 2 + drivers/spi/spi.c | 179 +--- include/linux/spi/spi.h | 33 +++-- 4 files changed, 199 insertions(+), 29 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 1761c9004fc1149e..df8ddec24b5d7e88 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -784,6 +784,18 @@ config SPI_TLE62X0 endif # SPI_MASTER -# (slave support would go here) +# +# SLAVE side ... listening to other SPI masters +# + +config SPI_SLAVE + bool "SPI slave protocol handlers" + help + If your system has a slave-capable SPI controller, you can enable + slave protocol handlers. + +if SPI_SLAVE + +endif # SPI_SLAVE endif # SPI diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index b375a7a892160b76..e50852c6fcb87d8b 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -105,3 +105,5 @@ obj-$(CONFIG_SPI_XILINX)+= spi-xilinx.o obj-$(CONFIG_SPI_XLP) += spi-xlp.o obj-$(CONFIG_SPI_XTENSA_XTFPGA)+= spi-xtensa-xtfpga.o obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o + +# SPI slave protocol handlers diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 6f87fec409b5f6fd..c3f6b524b3ceb6c1 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1535,15 +1535,6 @@ static int of_spi_parse_dt(struct spi_master *master, struct spi_device *spi, u32 value; int rc; - /* Device address */ - rc = of_property_read_u32(nc, "reg", &value); - if (rc) { - dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", - nc->full_name, rc); - return rc; - } - spi->chip_select = value; - /* Mode (clock phase/polarity/etc.) */ if (of_find_property(nc, "spi-cpha", NULL)) spi->mode |= SPI_CPHA; @@ -1593,6 +1584,24 @@ static int of_spi_parse_dt(struct spi_master *master, struct spi_device *spi, } } + if (spi_controller_is_slave(master)) { + if (strcmp(nc->name, "slave")) { + dev_err(&master->dev, "%s is not called 'slave'\n", + nc->full_name); +
[PATCH v3 0/6] spi: Add slave mode support
Hi all, This patch series adds support for SPI slave controllers to the Linux SPI subsystem, including: - DT binding updates for SPI slave support, - Core support for SPI slave controllers, - SPI slave support for the Renesas MSIOF device driver (thanks to Nakamura-san for the initial implementation in the R-Car BSP!), - Sample SPI slave handlers. Due to the nature of SPI slave (simultaneous transmit and receive, while everything runs at the pace of the master), it has hard real-time requirements: once an SPI transfer is started by the SPI master, a software SPI slave must have prepared all data to be sent back to the SPI master. Hence without additional hardware support, an SPI slave response can never be a reply to a command being simultaneously transmitted, and SPI slave replies must be received by the SPI master in a subsequent SPI transfer. Examples of possible use cases: - Receiving streams of data in fixed-size messages (e.g. from a tuner), - Receiving and transmitting fixed-size messages of data (e.g. network frames), - Sending commands, and querying for responses, - ... Binding an SPI slave handler to the SPI slave device represented by an SPI slave controller can either be done from DT, or through sysfs. The latter, which also allows unregistering, is done through a sysfs virtual file named "slave", cfr. Documentation/spi/spi-summary. Originally I wanted to implement a simple SPI slave handler that could interface with an existing Linux SPI slave driver, cfr. Wolfram Sang's I2C slave mode EEPROM simulator for the i2c subsystem. Unfortunately I couldn't find any existing driver using an SPI slave protocol that fulfills the above requirements. The Nordic Semiconductor nRF8001 BLE controller seems to use a suitable protocol, but I couldn't find a Linux driver for it. Hence I created two sample SPI slave protocols and drivers myself: 1. "spi-slave-time" responds with the system uptime at the time of reception of the last SPI message, which can be used by an external microcontroller as a dead man's switch. 2. "spi-slave-system-control" allows remote control of system reboot, power off, halt, and suspend. For some use cases, using spidev from user space may be a more appropriate solution than an in-kernel SPI protocol handler, and this is fully supported. >From the point of view of an SPI slave protocol handler, an SPI slave controller looks almost like an ordinary SPI master controller. The only exception is that a transfer request will block on the remote SPI master, and may be cancelled using spi_slave_abort(). Hence "struct spi_master" has become a misnomer. I'll send an RFC follow-up patch to fix that. For now, the MSIOF SPI slave driver only supports the transmission of messages with a size that is known in advance (the hardware can provide an interrupt when CS is deasserted before, though). I.e. when the SPI master sends a shorter message, the slave won't receive it. When the SPI master sends a longer message, the slave will receive the first part, and the rest will remain in the FIFO. Handshaking (5-pin SPI, RDY-signal) is optional, and not yet implemented. An RDY-signal may be used for one or both of: 1. The SPI slave asserts RDY when it has data available, and wants to be queried by the SPI master. -> This can be handled on top, in the SPI slave protocol handler, using a GPIO. 2. After the SPI master has asserted CS, the SPI slave asserts RDY when it is ready to accept the transfer. -> This may need hardware support in the SPI slave controller, or dynamic GPIO vs. CS pinmuxing. Changes compared to v2 (highlights only, see individual patches for more details): - In SPI slave mode, represent the (single) slave device again as a child of the controller node, which is now optional, and must be named "slave" if present, - Introduce a separate spi_alloc_slave() function, - Replace the SPI_CONTROLLER_IS_SLAVE flag in spi_master.flags by a bool in spi_master, - Fix cancellation in the spi-sh-msiof driver, - Drop "spi: core: Extract of_spi_parse_dt()", which was applied, Changes compared to v1 (highlights only, see individual patches for more details): - Do not create a child node in SPI slave mode. Instead, add an "spi-slave" property, and put the mode properties in the controller node. - Attach SPI slave controllers to a new "spi_slave" device class, - Use a "slave" virtual file in sysfs to (un)register the (single) slave device for an SPI slave controller, incl. specifying the slave protocol handler, - Add cancellation support using spi_master.slave_abort() and spi_slave_abort(), - Please see the individual patches for more detailed changelog information. Dependencies: - Today's spi/for-next, - "[PATCH] spi: core: Fix devm_spi_register_master() function name in kerneldoc", - "[PATCH] spi: core: Replace S_IRUGO permi
[PATCH v3 5/6] spi: slave: Add SPI slave handler reporting uptime at previous message
Add an example SPI slave handler responding with the uptime at the time of reception of the last SPI message. This can be used by an external microcontroller as a dead man's switch. Signed-off-by: Geert Uytterhoeven --- v3: - Add #include , v2: - Resolve semantic differences in patch description, file header, and module description, - Use spi_async() instead of spi_read(), - Submit the next transfer from the previous transfer's completion callback, removing the need for a thread, - Let .remove() call spi_slave_abort() to cancel the current ongoing transfer, and wait for the completion to terminate, - Remove FIXME about hanging kthread_stop(). --- drivers/spi/Kconfig | 6 ++ drivers/spi/Makefile | 1 + drivers/spi/spi-slave-time.c | 127 +++ 3 files changed, 134 insertions(+) create mode 100644 drivers/spi/spi-slave-time.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index df8ddec24b5d7e88..ade542c5bfd87e37 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -796,6 +796,12 @@ config SPI_SLAVE if SPI_SLAVE +config SPI_SLAVE_TIME + tristate "SPI slave handler reporting boot up time" + help + SPI slave handler responding with the time of reception of the last + SPI message. + endif # SPI_SLAVE endif # SPI diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index e50852c6fcb87d8b..fb078693dbe40da4 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -107,3 +107,4 @@ obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o # SPI slave protocol handlers +obj-$(CONFIG_SPI_SLAVE_TIME) += spi-slave-time.o diff --git a/drivers/spi/spi-slave-time.c b/drivers/spi/spi-slave-time.c new file mode 100644 index ..c2940f3f18ecd22e --- /dev/null +++ b/drivers/spi/spi-slave-time.c @@ -0,0 +1,127 @@ +/* + * SPI slave handler reporting uptime at reception of previous SPI message + * + * This SPI slave handler sends the time of reception of the last SPI message + * as two 32-bit unsigned integers in binary format and in network byte order, + * representing the number of seconds and fractional seconds (in microseconds) + * since boot up. + * + * Copyright (C) 2016 Glider bvba + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include + + +struct spi_slave_time_priv { + struct spi_device *spi; + struct completion finished; + struct spi_transfer xfer; + struct spi_message msg; + __be32 buf[2]; +}; + +static int spi_slave_time_submit(struct spi_slave_time_priv *priv); + +static void spi_slave_time_complete(void *arg) +{ + struct spi_slave_time_priv *priv = arg; + int ret; + + ret = priv->msg.status; + if (ret) + goto terminate; + + ret = spi_slave_time_submit(priv); + if (ret) + goto terminate; + + return; + +terminate: + pr_info("%s: Terminating\n", __func__); + complete(&priv->finished); +} + +static int spi_slave_time_submit(struct spi_slave_time_priv *priv) +{ + u32 rem_ns; + int ret; + u64 ts; + + ts = local_clock(); + rem_ns = do_div(ts, 10) / 1000; + + priv->buf[0] = cpu_to_be32(ts); + priv->buf[1] = cpu_to_be32(rem_ns); + + spi_message_init_with_transfers(&priv->msg, &priv->xfer, 1); + + priv->msg.complete = spi_slave_time_complete; + priv->msg.context = priv; + + ret = spi_async(priv->spi, &priv->msg); + if (ret) + pr_err("%s: spi_async() failed %d\n", __func__, ret); + + return ret; +} + +static int spi_slave_time_probe(struct spi_device *spi) +{ + struct spi_slave_time_priv *priv; + int ret; + + /* +* bits_per_word cannot be configured in platform data +*/ + spi->bits_per_word = 8; + + ret = spi_setup(spi); + if (ret < 0) + return ret; + + priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->spi = spi; + init_completion(&priv->finished); + priv->xfer.tx_buf = priv->buf; + priv->xfer.len = sizeof(priv->buf); + + ret = spi_slave_time_submit(priv); + if (ret) + return ret; + + spi_set_drvdata(spi, priv); + return 0; +} + +static int spi_slave_time_remove(struct spi_device *spi) +{ + struct spi_slave_time_priv *priv = spi_get_drvdata(spi); + + spi_slave_abort(spi); + wait_for_completion(&priv->finished); + return 0; +} + +static struct spi_driver spi_slave_time_driver = { + .driver = { + .name = "spi-slave-time", + }, + .probe
[PATCH v3 4/6] spi: sh-msiof: Add slave mode support
From: Hisashi Nakamura Add slave mode support to the MSIOF driver, in both PIO and DMA mode. For now this only supports the transmission of messages with a size that is known in advance. Signed-off-by: Hisashi Nakamura Signed-off-by: Hiromitsu Yamasaki [geert: Timeout handling cleanup, spi core integration, cancellation, rewording] Signed-off-by: Geert Uytterhoeven --- v3: - Clear TIF_SIGPENDING when interrupted to fix cancellation, - Extract sh_msiof_wait_for_completion(), - Add #include , - Convert to use spi_alloc_slave(), v2: - Document "spi-slave" property in DT bindings, - Use spi_controller_is_slave() helper, - Check for "spi-slave" property instead of "slave" child node, - Replace SPI_MASTER_IS_SLAVE by SPI_CONTROLLER_IS_SLAVE, - Implement cancellation. --- Documentation/devicetree/bindings/spi/sh-msiof.txt | 2 + drivers/spi/spi-sh-msiof.c | 121 +++-- include/linux/spi/sh_msiof.h | 6 + 3 files changed, 96 insertions(+), 33 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt index dc975064fa273c36..64ee489571c42f88 100644 --- a/Documentation/devicetree/bindings/spi/sh-msiof.txt +++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt @@ -38,6 +38,8 @@ Optional properties: specifiers, one for transmission, and one for reception. - dma-names: Must contain a list of two DMA names, "tx" and "rx". +- spi-slave: Empty property indicating the SPI controller is used +in slave mode. - renesas,dtdl : delay sync signal (setup) in transmit mode. Must contain one of the following values: 0 (no bit delay) diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 2ce15ca977828668..7c4e8c4f3a9bddfd 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -2,7 +2,8 @@ * SuperH MSIOF SPI Master Interface * * Copyright (c) 2009 Magnus Damm - * Copyright (C) 2014 Glider bvba + * Copyright (C) 2014 Renesas Electronics Corporation + * Copyright (C) 2014-2017 Glider bvba * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -26,6 +27,7 @@ #include #include #include +#include #include #include @@ -33,7 +35,6 @@ #include - struct sh_msiof_chipdata { u16 tx_fifo_size; u16 rx_fifo_size; @@ -337,7 +338,10 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, tmp |= !cs_high << MDR1_SYNCAC_SHIFT; tmp |= lsb_first << MDR1_BITLSB_SHIFT; tmp |= sh_msiof_spi_get_dtdl_and_syncdl(p); - sh_msiof_write(p, TMDR1, tmp | MDR1_TRMD | TMDR1_PCON); + if (spi_controller_is_slave(p->master)) + sh_msiof_write(p, TMDR1, tmp | TMDR1_PCON); + else + sh_msiof_write(p, TMDR1, tmp | MDR1_TRMD | TMDR1_PCON); if (p->master->flags & SPI_MASTER_MUST_TX) { /* These bits are reserved if RX needs TX */ tmp &= ~0x; @@ -564,17 +568,19 @@ static int sh_msiof_prepare_message(struct spi_master *master, static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf) { - int ret; + bool slave = spi_controller_is_slave(p->master); + int ret = 0; /* setup clock and rx/tx signals */ - ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TSCKE); + if (!slave) + ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TSCKE); if (rx_buf && !ret) ret = sh_msiof_modify_ctr_wait(p, 0, CTR_RXE); if (!ret) ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TXE); /* start by setting frame bit */ - if (!ret) + if (!ret && !slave) ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE); return ret; @@ -582,20 +588,61 @@ static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf) static int sh_msiof_spi_stop(struct sh_msiof_spi_priv *p, void *rx_buf) { - int ret; + bool slave = spi_controller_is_slave(p->master); + int ret = 0; /* shut down frame, rx/tx and clock signals */ - ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0); + if (!slave) + ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0); if (!ret) ret = sh_msiof_modify_ctr_wait(p, CTR_TXE, 0); if (rx_buf && !ret) ret = sh_msiof_modify_ctr_wait(p, CTR_RXE, 0); - if (!ret) + if (!ret && !slave) ret = sh_msiof_modify_ctr_wait(p, CTR_TSCKE, 0); return ret; } +static int sh_msiof_slave_abort(struct spi_master *master) +{ + struct sh_msiof_spi_priv *p = spi_master_get_devdata(master); + unsigned long flags; + +
[PATCH v3 1/6] spi: Document DT bindings for SPI controllers in slave mode
Signed-off-by: Geert Uytterhoeven --- v3: - In SPI slave mode, represent the (single) slave device again as a child of the controller node, which is now optional, and must be named "slave" if present, - Split slave node properties in master mode, slave mode, and common properties, v2: - Do not create a child node in SPI slave mode. Instead, add an "spi-slave" property, and put the mode properties in the controller node. --- Documentation/devicetree/bindings/spi/spi-bus.txt | 76 ++- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt index 4b1d6e74c744fe96..1f6e86f787efd229 100644 --- a/Documentation/devicetree/bindings/spi/spi-bus.txt +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt @@ -1,17 +1,23 @@ SPI (Serial Peripheral Interface) busses -SPI busses can be described with a node for the SPI master device -and a set of child nodes for each SPI slave on the bus. For this -discussion, it is assumed that the system's SPI controller is in -SPI master mode. This binding does not describe SPI controllers -in slave mode. +SPI busses can be described with a node for the SPI controller device +and a set of child nodes for each SPI slave on the bus. The system's SPI +controller may be described for use in SPI master mode or in SPI slave mode, +but not for both at the same time. -The SPI master node requires the following properties: +The SPI controller node requires the following properties: +- compatible - Name of SPI bus controller following generic names + recommended practice. + +In master mode, the SPI controller node requires the following additional +properties: - #address-cells - number of cells required to define a chip select address on the SPI bus. - #size-cells - should be zero. -- compatible - name of SPI bus controller following generic names - recommended practice. + +In slave mode, the SPI controller node requires one additional property: +- spi-slave - Empty property. + No other properties are required in the SPI bus node. It is assumed that a driver for an SPI bus device will understand that it is an SPI bus. However, the binding does not attempt to define the specific method for @@ -21,7 +27,7 @@ assumption that board specific platform code will be used to manage chip selects. Individual drivers can define additional properties to support describing the chip select layout. -Optional properties: +Optional properties (master mode only): - cs-gpios - gpios chip select. - num-cs - total number of chipselects. @@ -41,28 +47,36 @@ cs1 : native cs2 : &gpio1 1 0 cs3 : &gpio1 2 0 -SPI slave nodes must be children of the SPI master node and can -contain the following properties. -- reg - (required) chip select address of device. -- compatible - (required) name of SPI device following generic names - recommended practice. -- spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz. -- spi-cpol- (optional) Empty property indicating device requires - inverse clock polarity (CPOL) mode. -- spi-cpha- (optional) Empty property indicating device requires - shifted clock phase (CPHA) mode. -- spi-cs-high - (optional) Empty property indicating device requires - chip select active high. -- spi-3wire - (optional) Empty property indicating device requires - 3-wire mode. -- spi-lsb-first - (optional) Empty property indicating device requires - LSB first mode. -- spi-tx-bus-width - (optional) The bus width (number of data wires) that is - used for MOSI. Defaults to 1 if not present. -- spi-rx-bus-width - (optional) The bus width (number of data wires) that is - used for MISO. Defaults to 1 if not present. -- spi-rx-delay-us - (optional) Microsecond delay after a read transfer. -- spi-tx-delay-us - (optional) Microsecond delay after a write transfer. + +SPI slave nodes must be children of the SPI controller node. + +In master mode, one or more slave nodes (up to the number of chip selects) can +be present. Required properties are: +- compatible - Name of SPI device following generic names recommended + practice. +- reg - Chip select address of device. +- spi-max-frequency - Maximum SPI clocking speed of device in Hz. + +In slave mode, the (single) slave node is optional. +If present, it must be called "slave". Required properties are: +- compatible - Name of SPI device following generic names recommended + practice. + +All slave nodes can contain the following optional properties: +- spi-cpol- Empty property indicating device requires inverse clock + polarity (CPOL) mode.
[renesas-drivers:topic/spi-slave-v3-integration 4/10] htmldocs: include/linux/spi/spi.h:578: warning: No description found for parameter 'slave'
tree: https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git topic/spi-slave-v3-integration head: fa7cc511d594456e5e10890ab059a026b6d8f8ca commit: 2ad35b53babd55932362c5d46e51c6a9ed529ba5 [4/10] spi: core: Add support for registering SPI slave controllers reproduce: make htmldocs All warnings (new ones prefixed by >>): include/linux/init.h:1: warning: no structured comments found kernel/sched/core.c:2085: warning: No description found for parameter 'rf' kernel/sched/core.c:2085: warning: Excess function parameter 'cookie' description in 'try_to_wake_up_local' include/linux/kthread.h:26: warning: Excess function parameter '...' description in 'kthread_create' kernel/sys.c:1: warning: no structured comments found include/linux/device.h:969: warning: No description found for parameter 'dma_ops' drivers/dma-buf/seqno-fence.c:1: warning: no structured comments found include/linux/iio/iio.h:597: warning: No description found for parameter 'trig_readonly' include/linux/iio/trigger.h:151: warning: No description found for parameter 'indio_dev' include/linux/iio/trigger.h:151: warning: No description found for parameter 'trig' include/linux/device.h:970: warning: No description found for parameter 'dma_ops' drivers/regulator/core.c:1467: warning: Excess function parameter 'ret' description in 'regulator_dev_lookup' >> include/linux/spi/spi.h:578: warning: No description found for parameter >> 'slave' include/drm/drm_drv.h:438: warning: No description found for parameter 'open' include/drm/drm_drv.h:438: warning: No description found for parameter 'preclose' include/drm/drm_drv.h:438: warning: No description found for parameter 'postclose' include/drm/drm_drv.h:438: warning: No description found for parameter 'lastclose' include/drm/drm_drv.h:438: warning: No description found for parameter 'set_busid' include/drm/drm_drv.h:438: warning: No description found for parameter 'irq_handler' include/drm/drm_drv.h:438: warning: No description found for parameter 'irq_preinstall' include/drm/drm_drv.h:438: warning: No description found for parameter 'irq_postinstall' include/drm/drm_drv.h:438: warning: No description found for parameter 'irq_uninstall' include/drm/drm_drv.h:438: warning: No description found for parameter 'debugfs_init' include/drm/drm_drv.h:438: warning: No description found for parameter 'debugfs_cleanup' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_open_object' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_close_object' include/drm/drm_drv.h:438: warning: No description found for parameter 'prime_handle_to_fd' include/drm/drm_drv.h:438: warning: No description found for parameter 'prime_fd_to_handle' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_prime_export' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_prime_import' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_prime_pin' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_prime_unpin' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_prime_res_obj' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_prime_get_sg_table' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_prime_import_sg_table' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_prime_vmap' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_prime_vunmap' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_prime_mmap' include/drm/drm_drv.h:438: warning: No description found for parameter 'gem_vm_ops' include/drm/drm_drv.h:438: warning: No description found for parameter 'major' include/drm/drm_drv.h:438: warning: No description found for parameter 'minor' include/drm/drm_drv.h:438: warning: No description found for parameter 'patchlevel' include/drm/drm_drv.h:438: warning: No description found for parameter 'name' include/drm/drm_drv.h:438: warning: No description found for parameter 'desc' include/drm/drm_drv.h:438: warning: No description found for parameter 'date' include/drm/drm_drv.h:438: warning: No description found for parameter 'driver_features' include/drm/drm_drv.h:438: warning: No description found for parameter 'ioctls' include/drm/drm_drv.h:438: warning: No description found for parameter 'num_ioctls' include/drm/drm_drv.h:438: warning: No description found for parameter 'fops' include/drm/drm_color_mgmt.h:1: warning: no structured comments found drivers/gpu/drm/drm_fb_cma_helper.c:557: warning: Excess function parameter 'num_crtc' description in 'drm_fbdev_cma_init' drivers/gpu/drm/drm_fb_cma_helper.c:558: warning: Excess function paramete
[renesas-drivers:topic/spi-slave-v3-integration 6/10] ERROR: "signal_wake_up_state" [drivers/spi/spi-sh-msiof.ko] undefined!
tree: https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git topic/spi-slave-v3-integration head: fa7cc511d594456e5e10890ab059a026b6d8f8ca commit: 57b3e64f8211aba57ad17ad1a172ac35593e2c72 [6/10] spi: sh-msiof: Add slave mode support config: i386-allmodconfig (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: git checkout 57b3e64f8211aba57ad17ad1a172ac35593e2c72 # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): >> ERROR: "signal_wake_up_state" [drivers/spi/spi-sh-msiof.ko] undefined! --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v6 2/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver
Hi Sakari, Thanks for your feedback. On 2017-05-04 16:35:26 +0300, Sakari Ailus wrote: > Hi Niklas, > > On Fri, Apr 28, 2017 at 12:36:58AM +0200, Niklas Söderlund wrote: > > A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver > > supports the rcar-vin driver on R-Car Gen3 SoCs where separate CSI-2 > > hardware blocks are connected between the video sources and the video > > grabbers (VIN). > > > > Driver is based on a prototype by Koji Matsuoka in the Renesas BSP. > > > > Signed-off-by: Niklas Söderlund > > --- > > drivers/media/platform/rcar-vin/Kconfig | 11 + > > drivers/media/platform/rcar-vin/Makefile| 1 + > > drivers/media/platform/rcar-vin/rcar-csi2.c | 872 > > > > 3 files changed, 884 insertions(+) > > create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c > > > > diff --git a/drivers/media/platform/rcar-vin/Kconfig > > b/drivers/media/platform/rcar-vin/Kconfig > > index 111d2a151f6a4d44..f1df85d526e96a74 100644 > > --- a/drivers/media/platform/rcar-vin/Kconfig > > +++ b/drivers/media/platform/rcar-vin/Kconfig > > @@ -1,3 +1,14 @@ > > +config VIDEO_RCAR_CSI2 > > + tristate "R-Car MIPI CSI-2 Receiver" > > + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF > > + depends on ARCH_RENESAS || COMPILE_TEST > > + ---help--- > > + Support for Renesas R-Car MIPI CSI-2 receiver. > > + Supports R-Car Gen3 SoCs. > > + > > + To compile this driver as a module, choose M here: the > > + module will be called rcar-csi2. > > + > > config VIDEO_RCAR_VIN > > tristate "R-Car Video Input (VIN) Driver" > > depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && > > MEDIA_CONTROLLER > > diff --git a/drivers/media/platform/rcar-vin/Makefile > > b/drivers/media/platform/rcar-vin/Makefile > > index 48c5632c21dc060b..5ab803d3e7c1aa57 100644 > > --- a/drivers/media/platform/rcar-vin/Makefile > > +++ b/drivers/media/platform/rcar-vin/Makefile > > @@ -1,3 +1,4 @@ > > rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o > > > > +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o > > obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o > > diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c > > b/drivers/media/platform/rcar-vin/rcar-csi2.c > > new file mode 100644 > > index ..53601e171aa179b7 > > --- /dev/null > > +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c > > @@ -0,0 +1,872 @@ > > +/* > > + * Driver for Renesas R-Car MIPI CSI-2 Receiver > > + * > > + * Copyright (C) 2017 Renesas Electronics Corp. > > + * > > + * This program is free software; you can redistribute it and/or modify it > > + * under the terms of the GNU General Public License as published by the > > + * Free Software Foundation; either version 2 of the License, or (at your > > + * option) any later version. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > +#include > > +#include > > Could you rebase also this on the V4L2 fwnode patchset? > > https://git.linuxtv.org/sailus/media_tree.git/log/?h=v4l2-acpi> Yes, I rebased the series on top of v4l2-acpi-merge. I like the fwnode patches, nice work! > > > +#include > > + > > +/* Register offsets and bits */ > > + > > +/* Control Timing Select */ > > +#define TREF_REG 0x00 > > +#define TREF_TREF (1 << 0) > > + > > +/* Software Reset */ > > +#define SRST_REG 0x04 > > +#define SRST_SRST (1 << 0) > > + > > +/* PHY Operation Control */ > > +#define PHYCNT_REG 0x08 > > +#define PHYCNT_SHUTDOWNZ (1 << 17) > > +#define PHYCNT_RSTZ(1 << 16) > > +#define PHYCNT_ENABLECLK (1 << 4) > > +#define PHYCNT_ENABLE_3(1 << 3) > > +#define PHYCNT_ENABLE_2(1 << 2) > > +#define PHYCNT_ENABLE_1(1 << 1) > > +#define PHYCNT_ENABLE_0(1 << 0) > > + > > +/* Checksum Control */ > > +#define CHKSUM_REG 0x0c > > +#define CHKSUM_ECC_EN (1 << 1) > > +#define CHKSUM_CRC_EN (1 << 0) > > + > > +/* > > + * Channel Data Type Select > > + * VCDT[0-15]: Channel 1 VCDT[16-31]: Channel 2 > > + * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4 > > + */ > > +#define VCDT_REG 0x10 > > +#define VCDT2_REG 0x14 > > +#define VCDT_VCDTN_EN (1 << 15) > > +#define VCDT_SEL_VC(n) (((n) & 0x3) << 8) > > +#define VCDT_SEL_DTN_ON(1 << 6) > > +#define VCDT_SEL_DT(n) (((n) & 0x1f) << 0) > > + > > +/* Frame Data Type Select */ > > +#define FRDT_REG 0x18 > > + > > +/* Field Detection Control */ > > +#define FLD_REG0x1c > > +#define FLD_FLD_NUM(n) (((n) & 0xff) << 16) > > +#define
Re: [PATCH v6 2/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver
Hi Niklas, On Thu, May 04, 2017 at 11:30:19PM +0200, Niklas Söderlund wrote: > Hi Sakari, > > Thanks for your feedback. You're welcome! > On 2017-05-04 16:35:26 +0300, Sakari Ailus wrote: > > Hi Niklas, > > > > On Fri, Apr 28, 2017 at 12:36:58AM +0200, Niklas Söderlund wrote: > > > A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver > > > supports the rcar-vin driver on R-Car Gen3 SoCs where separate CSI-2 > > > hardware blocks are connected between the video sources and the video > > > grabbers (VIN). > > > > > > Driver is based on a prototype by Koji Matsuoka in the Renesas BSP. > > > > > > Signed-off-by: Niklas Söderlund > > > --- > > > drivers/media/platform/rcar-vin/Kconfig | 11 + > > > drivers/media/platform/rcar-vin/Makefile| 1 + > > > drivers/media/platform/rcar-vin/rcar-csi2.c | 872 > > > > > > 3 files changed, 884 insertions(+) > > > create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c > > > > > > diff --git a/drivers/media/platform/rcar-vin/Kconfig > > > b/drivers/media/platform/rcar-vin/Kconfig > > > index 111d2a151f6a4d44..f1df85d526e96a74 100644 > > > --- a/drivers/media/platform/rcar-vin/Kconfig > > > +++ b/drivers/media/platform/rcar-vin/Kconfig > > > @@ -1,3 +1,14 @@ > > > +config VIDEO_RCAR_CSI2 > > > + tristate "R-Car MIPI CSI-2 Receiver" > > > + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF > > > + depends on ARCH_RENESAS || COMPILE_TEST > > > + ---help--- > > > + Support for Renesas R-Car MIPI CSI-2 receiver. > > > + Supports R-Car Gen3 SoCs. > > > + > > > + To compile this driver as a module, choose M here: the > > > + module will be called rcar-csi2. > > > + > > > config VIDEO_RCAR_VIN > > > tristate "R-Car Video Input (VIN) Driver" > > > depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && > > > MEDIA_CONTROLLER > > > diff --git a/drivers/media/platform/rcar-vin/Makefile > > > b/drivers/media/platform/rcar-vin/Makefile > > > index 48c5632c21dc060b..5ab803d3e7c1aa57 100644 > > > --- a/drivers/media/platform/rcar-vin/Makefile > > > +++ b/drivers/media/platform/rcar-vin/Makefile > > > @@ -1,3 +1,4 @@ > > > rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o > > > > > > +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o > > > obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o > > > diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c > > > b/drivers/media/platform/rcar-vin/rcar-csi2.c > > > new file mode 100644 > > > index ..53601e171aa179b7 > > > --- /dev/null > > > +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c > > > @@ -0,0 +1,872 @@ > > > +/* > > > + * Driver for Renesas R-Car MIPI CSI-2 Receiver > > > + * > > > + * Copyright (C) 2017 Renesas Electronics Corp. > > > + * > > > + * This program is free software; you can redistribute it and/or modify > > > it > > > + * under the terms of the GNU General Public License as published by > > > the > > > + * Free Software Foundation; either version 2 of the License, or (at > > > your > > > + * option) any later version. > > > + */ > > > + > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > + > > > +#include > > > +#include > > > +#include > > > +#include > > > > Could you rebase also this on the V4L2 fwnode patchset? > > > > https://git.linuxtv.org/sailus/media_tree.git/log/?h=v4l2-acpi> > > Yes, I rebased the series on top of v4l2-acpi-merge. I like the fwnode > patches, nice work! I'm glad you like it. :-) > > > > > > +#include > > > + > > > +/* Register offsets and bits */ > > > + > > > +/* Control Timing Select */ > > > +#define TREF_REG 0x00 > > > +#define TREF_TREF(1 << 0) > > > + > > > +/* Software Reset */ > > > +#define SRST_REG 0x04 > > > +#define SRST_SRST(1 << 0) > > > + > > > +/* PHY Operation Control */ > > > +#define PHYCNT_REG 0x08 > > > +#define PHYCNT_SHUTDOWNZ (1 << 17) > > > +#define PHYCNT_RSTZ (1 << 16) > > > +#define PHYCNT_ENABLECLK (1 << 4) > > > +#define PHYCNT_ENABLE_3 (1 << 3) > > > +#define PHYCNT_ENABLE_2 (1 << 2) > > > +#define PHYCNT_ENABLE_1 (1 << 1) > > > +#define PHYCNT_ENABLE_0 (1 << 0) > > > + > > > +/* Checksum Control */ > > > +#define CHKSUM_REG 0x0c > > > +#define CHKSUM_ECC_EN(1 << 1) > > > +#define CHKSUM_CRC_EN(1 << 0) > > > + > > > +/* > > > + * Channel Data Type Select > > > + * VCDT[0-15]: Channel 1 VCDT[16-31]: Channel 2 > > > + * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4 > > > + */ > > > +#define VCDT_REG 0x10 > > > +#define VCDT2_REG0x14 > > > +#define VCDT_VCDTN_EN(1 << 15) > > > +#define VCDT_SEL_VC(n) (((n) & 0x3) << 8) >