Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [GIT PULL] Mailbox changes for v4.10
From: Jassi Brar @ 2016-12-20 14:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

The following changes since commit 16ae16c6e5616c084168740990fc508bda6655d4:

  Merge tag 'mmc-v4.9-rc5' of
git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc (2016-11-24
10:51:18 -0800)

are available in the git repository at:

  git://git.linaro.org/landing-teams/working/fujitsu/integration.git
mailbox-for-next

for you to fetch changes up to db4d22c07e3e652eeec82abcc1399e6305edd838:

  mailbox: mailbox-test: allow reserved areas in SRAM (2016-12-19
20:10:23 +0530)

----------------------------------------------------------------
- New features (poll and SRAM usage) added to the mailbox-test driver
- Major update of Broadcom's PDC controller driver
- Minor fix for auto-loading test and STI driver modules

----------------------------------------------------------------
Javier Martinez Canillas (2):
      mailbox: mailbox-test: Fix module autoload
      mailbox: sti: Fix module autoload for OF registration

Rob Rice (9):
      mailbox: bcm-pdc: Use octal permissions rather than symbolic
      mailbox: bcm-pdc: Convert from interrupts to poll for tx done
      mailbox: bcm-pdc: streamline rx code
      mailbox: bcm-pdc: Try to improve branch prediction
      mailbox: bcm-pdc: Convert from threaded IRQ to tasklet
      mailbox: bcm-pdc: Don't use iowrite32 to write DMA descriptors
      mailbox: bcm-pdc: Performance improvements
      mailbox: bcm-pdc: Simplify interrupt handler logic
      mailbox: bcm-pdc: Remove unnecessary void* casts

Steve Lin (2):
      mailbox: bcm-pdc: Changes so mbox client can be removed / re-inserted
      mailbox: bcm-pdc: PDC driver leaves debugfs files after removal

Sudeep Holla (2):
      mailbox: mailbox-test: add support for fasync/poll
      mailbox: mailbox-test: allow reserved areas in SRAM

 drivers/mailbox/bcm-pdc-mailbox.c | 548 ++++++++++++++++++++++----------------
 drivers/mailbox/mailbox-sti.c     |   1 +
 drivers/mailbox/mailbox-test.c    |  92 ++++++-
 3 files changed, 407 insertions(+), 234 deletions(-)

^ permalink raw reply

* [linux-sunxi][PATCH 2/3] ARM: dts: sun6i: Add the SPDIF block to the A31
From: Maxime Ripard @ 2016-12-20 14:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161220104038.22532-3-codekipper@gmail.com>

Hi,

On Tue, Dec 20, 2016 at 11:40:37AM +0100, codekipper at gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
> 
> Add the SPDIF transceiver controller block to the A31 dtsi.
> 
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
>  arch/arm/boot/dts/sun6i-a31.dtsi | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
> index 7370ba6c9993..559c53efa7e6 100644
> --- a/arch/arm/boot/dts/sun6i-a31.dtsi
> +++ b/arch/arm/boot/dts/sun6i-a31.dtsi
> @@ -613,6 +613,20 @@
>  			reg = <0x01c20ca0 0x20>;
>  		};
>  
> +		spdif: spdif at 01c21000 {
> +			#sound-dai-cells = <0>;
> +			compatible = "allwinner,sun6i-a31-spdif";
> +			reg = <0x01c21000 0x400>;
> +			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&ccu CLK_APB1_SPDIF>, <&ccu CLK_SPDIF>;
> +			resets = <&ccu RST_APB1_SPDIF>;
> +			clock-names = "apb", "spdif";
> +			dmas = <&dma 2>, <&dma 2>;
> +			dma-names = "rx", "tx";
> +			spdif-out = "disabled";

That property isn't documented anywhere, and doesn't seem to be used
in your driver either.

On a separate topic, is the channel inversion bug also found on the
A31?

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161220/b0c1450a/attachment.sig>

^ permalink raw reply

* [PATCH] ARM: dts: sun8i-q8-common: enable bluetooth on SDIO Wi-Fi
From: Maxime Ripard @ 2016-12-20 13:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGb2v67wU+Hw-6oa9FxzB33sZY8Up-59HZ_mneFBdcRhXbU1pA@mail.gmail.com>

On Mon, Dec 19, 2016 at 10:24:44PM +0800, Chen-Yu Tsai wrote:
> On Mon, Dec 19, 2016 at 10:08 PM, Icenowy Zheng <icenowy@aosc.xyz> wrote:
> >
> >
> > 19.12.2016, 18:09, "Maxime Ripard" <maxime.ripard@free-electrons.com>:
> >> On Fri, Dec 16, 2016 at 10:40:00PM +0800, Icenowy Zheng wrote:
> >>>  >>  > >  &r_pio {
> >>>  >>  > >  wifi_pwrseq_pin_q8: wifi_pwrseq_pin at 0 {
> >>>  >>  > > - pins = "PL6", "PL7", "PL11";
> >>>  >>  > > + pins = "PL6", "PL7", "PL8", "PL11";
> >>>  >>  > >  function = "gpio_in";
> >>>  >>  > >  bias-pull-up;
> >>>  >>  > >  };
> >>>  >>  >
> >>>  >>  > There's several things wrong here. The first one is that you rely
> >>>  >>  > solely on the pinctrl state to maintain a reset line. This is very
> >>>  >>  > fragile (especially since the GPIO pinctrl state are likely to go away
> >>>  >>  > at some point), but it also means that if your driver wants to recover
> >>>  >>  > from that situation at some point, it won't work.
> >>>  >>  >
> >>>  >>  > The other one is that the bluetooth and wifi chips are two devices in
> >>>  >>  > linux, and you assign that pin to the wrong device (wifi).
> >>>  >>  >
> >>>  >>  > rfkill-gpio is made just for that, so please use it.
> >>>  >>
> >>>  >>  The GPIO is not for the radio, but for the full Bluetooth part.
> >>>  >
> >>>  > I know.
> >>>  >
> >>>  >>  If it's set to 0, then the bluetooth part will reset, and the
> >>>  >>  hciattach will fail.
> >>>  >
> >>>  > Both rfkill-gpio and rfkill-regulator will shutdown when called
> >>>  > (either by poking the reset pin or shutting down the regulator), so
> >>>  > that definitely seems like an expected behavior to put the device in
> >>>  > reset.
> >>>  >
> >>>  >>  The BSP uses this as a rfkill, and the result is that the bluetooth
> >>>  >>  on/off switch do not work properly.
> >>>  >
> >>>  > Then rfkill needs fixing, but working around it by hoping that the
> >>>  > core will probe an entirely different device, and enforcing a default
> >>>  > that the rest of the kernel might or might not change is both fragile
> >>>  > and wrong.
> >>>
> >>>  I think a rfkill-gpio here works just like the BSP rfkill...
> >>>
> >>>  The real problem is that the Realtek UART bluetooth driver is a userspace
> >>>  program (a modified hciattach), which is not capable of the GPIO reset...
> >>
> >> Can't you run rfkill before attaching? What is the problem exactly?
> >> It's not in reset for long enough?
> >>
> >> This seems more and more like an issue in the BT stack you're
> >> using. We might consider workarounds in the kernel, but they have to
> >> be correct.
> >
> > One more rfkill interface will be generated for hci0 after hciattach, which can
> > be safely toggled block and unblock.
> >
> > However, if the GPIO is toggled down, the hciattach program will die.
> >
> > The bluetooth stack I used is fd.o's BlueZ.
> 
> I think the bigger issue is that the tty/serial subsystem does not have
> power sequencing support. Here we're trying to use rfkill to do that,
> but that doesn't seem to be what it was intended for. It might work with
> standalone USB bluetooth controllers that don't need any special setup,
> since the device will just appear and get registered. But it might not
> work so well with UART based adapters that need userspace fiddling with
> firmware and hciattach.

Then you can also have a look at the generic power sequence patches
that are floating around.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161220/4ffe5077/attachment.sig>

^ permalink raw reply

* [PATCH] crypto: testmgr: Use linear alias for test input
From: Ard Biesheuvel @ 2016-12-20 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482190646-7720-1-git-send-email-labbott@redhat.com>

On 19 December 2016 at 23:37, Laura Abbott <labbott@redhat.com> wrote:
> Christopher Covington reported a crash on aarch64 on recent Fedora
> kernels:
>
> kernel BUG at ./include/linux/scatterlist.h:140!
> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
> Modules linked in:
> CPU: 2 PID: 752 Comm: cryptomgr_test Not tainted 4.9.0-11815-ge93b1cc #162
> Hardware name: linux,dummy-virt (DT)
> task: ffff80007c650080 task.stack: ffff800008910000
> PC is at sg_init_one+0xa0/0xb8
> LR is at sg_init_one+0x24/0xb8
> ...
> [<ffff000008398db8>] sg_init_one+0xa0/0xb8
> [<ffff000008350a44>] test_acomp+0x10c/0x438
> [<ffff000008350e20>] alg_test_comp+0xb0/0x118
> [<ffff00000834f28c>] alg_test+0x17c/0x2f0
> [<ffff00000834c6a4>] cryptomgr_test+0x44/0x50
> [<ffff0000080dac70>] kthread+0xf8/0x128
> [<ffff000008082ec0>] ret_from_fork+0x10/0x50
>
> The test vectors used for input are part of the kernel image. These
> inputs are passed as a buffer to sg_init_one which eventually blows up
> with BUG_ON(!virt_addr_valid(buf)). On arm64, virt_addr_valid returns
> false for the kernel image since virt_to_page will not return the
> correct page. The kernel image is also aliased to the linear map so get
> the linear alias and pass that to the scatterlist instead.
>
> Reported-by: Christopher Covington <cov@codeaurora.org>
> Fixes: d7db7a882deb ("crypto: acomp - update testmgr with support for acomp")
> Signed-off-by: Laura Abbott <labbott@redhat.com>
> ---
> x86 supports virt_addr_valid working on kernel image addresses but arm64 is
> more strict. This is the direction things have been moving with my
> CONFIG_DEBUG_VIRTUAL series for arm64 which is tightening the definition of
> __pa/__pa_symbol.

A helper function would be nice, so that we can call
sg_init_table/sg_set_page directly, and avoid the redundant
virt_to_phys(__va()) translation (and add a comment *why* we should
not use sg_init_one() with the address of a kernel symbol).

But I will leave it up to Herbert to decide whether he prefers that or not.

In any case,
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

> ---
>  crypto/testmgr.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/crypto/testmgr.c b/crypto/testmgr.c
> index f616ad7..f5bac10 100644
> --- a/crypto/testmgr.c
> +++ b/crypto/testmgr.c
> @@ -1464,7 +1464,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
>
>                 memset(output, 0, dlen);
>                 init_completion(&result.completion);
> -               sg_init_one(&src, ctemplate[i].input, ilen);
> +               sg_init_one(&src, __va(__pa_symbol(ctemplate[i].input)), ilen);
>                 sg_init_one(&dst, output, dlen);
>
>                 req = acomp_request_alloc(tfm);
> @@ -1513,7 +1513,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
>
>                 memset(output, 0, dlen);
>                 init_completion(&result.completion);
> -               sg_init_one(&src, dtemplate[i].input, ilen);
> +               sg_init_one(&src, __va(__pa_symbol(dtemplate[i].input)), ilen);
>                 sg_init_one(&dst, output, dlen);
>
>                 req = acomp_request_alloc(tfm);
> --
> 2.7.4
>

^ permalink raw reply

* [PATCH v2] drm: zte: add overlay plane support
From: Shawn Guo @ 2016-12-20 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

It enables VOU VL (Video Layer) to support overlay plane with scaling
function.  VL0 has some quirks on scaling support.  We chose to skip it
and only adds VL1 and VL2 into DRM core for now.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
Changes for v2:
 - Use clipped coordinates for overlay position calculation

 drivers/gpu/drm/zte/zx_plane.c      | 293 ++++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/zte/zx_plane_regs.h |  51 +++++++
 drivers/gpu/drm/zte/zx_vou.c        | 149 +++++++++++++++++-
 drivers/gpu/drm/zte/zx_vou.h        |   3 +
 drivers/gpu/drm/zte/zx_vou_regs.h   |  18 +++
 5 files changed, 497 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 546eb92a94e8..8cd7cf71b2b0 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -40,6 +40,269 @@ struct zx_plane {
 	DRM_FORMAT_ARGB4444,
 };
 
+static const uint32_t vl_formats[] = {
+	DRM_FORMAT_NV12,	/* Semi-planar YUV420 */
+	DRM_FORMAT_YUV420,	/* Planar YUV420 */
+	DRM_FORMAT_YUYV,	/* Packed YUV422 */
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_VYUY,
+	DRM_FORMAT_YUV444,	/* YUV444 8bit */
+	/*
+	 * TODO: add formats below that HW supports:
+	 *  - YUV420 P010
+	 *  - YUV420 Hantro
+	 *  - YUV444 10bit
+	 */
+};
+
+#define FRAC_16_16(mult, div)    (((mult) << 16) / (div))
+
+static int zx_vl_plane_atomic_check(struct drm_plane *plane,
+				    struct drm_plane_state *plane_state)
+{
+	struct drm_framebuffer *fb = plane_state->fb;
+	struct drm_crtc *crtc = plane_state->crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_rect clip;
+	int min_scale = FRAC_16_16(1, 8);
+	int max_scale = FRAC_16_16(8, 1);
+
+	if (!crtc || !fb)
+		return 0;
+
+	crtc_state = drm_atomic_get_existing_crtc_state(plane_state->state,
+							crtc);
+	if (WARN_ON(!crtc_state))
+		return -EINVAL;
+
+	/* nothing to check when disabling or disabled */
+	if (!crtc_state->enable)
+		return 0;
+
+	/* plane must be enabled */
+	if (!plane_state->crtc)
+		return -EINVAL;
+
+	clip.x1 = 0;
+	clip.y1 = 0;
+	clip.x2 = crtc_state->adjusted_mode.hdisplay;
+	clip.y2 = crtc_state->adjusted_mode.vdisplay;
+
+	return drm_plane_helper_check_state(plane_state, &clip,
+					    min_scale, max_scale,
+					    true, true);
+}
+
+static u32 zx_vl_get_fmt(uint32_t format)
+{
+	u32 val = 0;
+
+	switch (format) {
+	case DRM_FORMAT_NV12:
+		val = VL_FMT_YUV420;
+		break;
+	case DRM_FORMAT_YUV420:
+		val = VL_YUV420_PLANAR | VL_FMT_YUV420;
+		break;
+	case DRM_FORMAT_YUYV:
+		val = VL_YUV422_YUYV | VL_FMT_YUV422;
+		break;
+	case DRM_FORMAT_YVYU:
+		val = VL_YUV422_YVYU | VL_FMT_YUV422;
+		break;
+	case DRM_FORMAT_UYVY:
+		val = VL_YUV422_UYVY | VL_FMT_YUV422;
+		break;
+	case DRM_FORMAT_VYUY:
+		val = VL_YUV422_VYUY | VL_FMT_YUV422;
+		break;
+	case DRM_FORMAT_YUV444:
+		val = VL_FMT_YUV444_8BIT;
+		break;
+	default:
+		WARN_ONCE(1, "invalid pixel format %d\n", format);
+	}
+
+	return val;
+}
+
+static inline void zx_vl_set_update(struct zx_plane *zplane)
+{
+	void __iomem *layer = zplane->layer;
+
+	zx_writel_mask(layer + VL_CTRL0, VL_UPDATE, VL_UPDATE);
+}
+
+static inline void zx_vl_rsz_set_update(struct zx_plane *zplane)
+{
+	zx_writel(zplane->rsz + RSZ_VL_ENABLE_CFG, 1);
+}
+
+static u32 zx_vl_rsz_get_fmt(uint32_t format)
+{
+	u32 val = 0;
+
+	switch (format) {
+	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_YUV420:
+		val = RSZ_VL_FMT_YCBCR420;
+		break;
+	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_YVYU:
+	case DRM_FORMAT_UYVY:
+	case DRM_FORMAT_VYUY:
+		val = RSZ_VL_FMT_YCBCR422;
+		break;
+	case DRM_FORMAT_YUV444:
+		val = RSZ_VL_FMT_YCBCR444;
+		break;
+	default:
+		WARN_ONCE(1, "invalid pixel format %d\n", format);
+	}
+
+	return val;
+}
+
+static inline u32 rsz_step_value(u32 src, u32 dst)
+{
+	u32 val = 0;
+
+	if (src == dst)
+		val = 0;
+	else if (src < dst)
+		val = RSZ_PARA_STEP((src << 16) / dst);
+	else if (src > dst)
+		val = RSZ_DATA_STEP(src / dst) |
+		      RSZ_PARA_STEP(((src << 16) / dst) & 0xffff);
+
+	return val;
+}
+
+static void zx_vl_rsz_setup(struct zx_plane *zplane, uint32_t format,
+			    u32 src_w, u32 src_h, u32 dst_w, u32 dst_h)
+{
+	void __iomem *rsz = zplane->rsz;
+	u32 src_chroma_w = src_w;
+	u32 src_chroma_h = src_h;
+	u32 fmt;
+
+	/* Set up source and destination resolution */
+	zx_writel(rsz + RSZ_SRC_CFG, RSZ_VER(src_h - 1) | RSZ_HOR(src_w - 1));
+	zx_writel(rsz + RSZ_DEST_CFG, RSZ_VER(dst_h - 1) | RSZ_HOR(dst_w - 1));
+
+	/* Configure data format for VL RSZ */
+	fmt = zx_vl_rsz_get_fmt(format);
+	zx_writel_mask(rsz + RSZ_VL_CTRL_CFG, RSZ_VL_FMT_MASK, fmt);
+
+	/* Calculate Chroma heigth and width */
+	if (fmt == RSZ_VL_FMT_YCBCR420) {
+		src_chroma_w = src_w >> 1;
+		src_chroma_h = src_h >> 1;
+	} else if (fmt == RSZ_VL_FMT_YCBCR422) {
+		src_chroma_w = src_w >> 1;
+	}
+
+	/* Set up Luma and Chroma step registers */
+	zx_writel(rsz + RSZ_VL_LUMA_HOR, rsz_step_value(src_w, dst_w));
+	zx_writel(rsz + RSZ_VL_LUMA_VER, rsz_step_value(src_h, dst_h));
+	zx_writel(rsz + RSZ_VL_CHROMA_HOR, rsz_step_value(src_chroma_w, dst_w));
+	zx_writel(rsz + RSZ_VL_CHROMA_VER, rsz_step_value(src_chroma_h, dst_h));
+
+	zx_vl_rsz_set_update(zplane);
+}
+
+static void zx_vl_plane_atomic_update(struct drm_plane *plane,
+				      struct drm_plane_state *old_state)
+{
+	struct zx_plane *zplane = to_zx_plane(plane);
+	struct drm_plane_state *state = plane->state;
+	struct drm_framebuffer *fb = state->fb;
+	struct drm_rect *src = &state->src;
+	struct drm_rect *dst = &state->dst;
+	struct drm_gem_cma_object *cma_obj;
+	void __iomem *layer = zplane->layer;
+	void __iomem *hbsc = zplane->hbsc;
+	void __iomem *paddr_reg;
+	dma_addr_t paddr;
+	u32 src_x, src_y, src_w, src_h;
+	u32 dst_x, dst_y, dst_w, dst_h;
+	uint32_t format;
+	u32 fmt;
+	int num_planes;
+	int i;
+
+	if (!fb)
+		return;
+
+	format = fb->pixel_format;
+
+	src_x = src->x1 >> 16;
+	src_y = src->y1 >> 16;
+	src_w = drm_rect_width(src) >> 16;
+	src_h = drm_rect_height(src) >> 16;
+
+	dst_x = dst->x1;
+	dst_y = dst->y1;
+	dst_w = drm_rect_width(dst);
+	dst_h = drm_rect_height(dst);
+
+	/* Set up data address registers for Y, Cb and Cr planes */
+	num_planes = drm_format_num_planes(format);
+	paddr_reg = layer + VL_Y;
+	for (i = 0; i < num_planes; i++) {
+		cma_obj = drm_fb_cma_get_gem_obj(fb, i);
+		paddr = cma_obj->paddr + fb->offsets[i];
+		paddr += src_y * fb->pitches[i];
+		paddr += src_x * drm_format_plane_cpp(format, i);
+		zx_writel(paddr_reg, paddr);
+		paddr_reg += 4;
+	}
+
+	/* Set up source height/width register */
+	zx_writel(layer + VL_SRC_SIZE, GL_SRC_W(src_w) | GL_SRC_H(src_h));
+
+	/* Set up start position register */
+	zx_writel(layer + VL_POS_START, GL_POS_X(dst_x) | GL_POS_Y(dst_y));
+
+	/* Set up end position register */
+	zx_writel(layer + VL_POS_END,
+		  GL_POS_X(dst_x + dst_w) | GL_POS_Y(dst_y + dst_h));
+
+	/* Strides of Cb and Cr planes should be identical */
+	zx_writel(layer + VL_STRIDE, LUMA_STRIDE(fb->pitches[0]) |
+		  CHROMA_STRIDE(fb->pitches[1]));
+
+	/* Set up video layer data format */
+	fmt = zx_vl_get_fmt(format);
+	zx_writel(layer + VL_CTRL1, fmt);
+
+	/* Always use scaler since it exists (set for not bypass) */
+	zx_writel_mask(layer + VL_CTRL2, VL_SCALER_BYPASS_MODE,
+		       VL_SCALER_BYPASS_MODE);
+
+	zx_vl_rsz_setup(zplane, format, src_w, src_h, dst_w, dst_h);
+
+	/* Enable HBSC block */
+	zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, HBSC_CTRL_EN);
+
+	zx_overlay_enable(plane);
+
+	zx_vl_set_update(zplane);
+}
+
+static void zx_vl_plane_atomic_disable(struct drm_plane *plane,
+				       struct drm_plane_state *old_state)
+{
+	zx_overlay_disable(plane);
+}
+
+static const struct drm_plane_helper_funcs zx_vl_plane_helper_funcs = {
+	.atomic_check = zx_vl_plane_atomic_check,
+	.atomic_update = zx_vl_plane_atomic_update,
+	.atomic_disable = zx_vl_plane_atomic_disable,
+};
+
 static int zx_gl_plane_atomic_check(struct drm_plane *plane,
 				    struct drm_plane_state *plane_state)
 {
@@ -107,14 +370,6 @@ static inline void zx_gl_rsz_set_update(struct zx_plane *zplane)
 	zx_writel(zplane->rsz + RSZ_ENABLE_CFG, 1);
 }
 
-void zx_plane_set_update(struct drm_plane *plane)
-{
-	struct zx_plane *zplane = to_zx_plane(plane);
-
-	zx_gl_rsz_set_update(zplane);
-	zx_gl_set_update(zplane);
-}
-
 static void zx_gl_rsz_setup(struct zx_plane *zplane, u32 src_w, u32 src_h,
 			    u32 dst_w, u32 dst_h)
 {
@@ -230,6 +485,24 @@ static void zx_plane_destroy(struct drm_plane *plane)
 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 };
 
+void zx_plane_set_update(struct drm_plane *plane)
+{
+	struct zx_plane *zplane = to_zx_plane(plane);
+
+	switch (plane->type) {
+	case DRM_PLANE_TYPE_PRIMARY:
+		zx_gl_rsz_set_update(zplane);
+		zx_gl_set_update(zplane);
+		break;
+	case DRM_PLANE_TYPE_OVERLAY:
+		zx_vl_rsz_set_update(zplane);
+		zx_vl_set_update(zplane);
+		break;
+	default:
+		WARN_ONCE(1, "unsupported plane type %d\n", plane->type);
+	}
+}
+
 static void zx_plane_hbsc_init(struct zx_plane *zplane)
 {
 	void __iomem *hbsc = zplane->hbsc;
@@ -279,7 +552,9 @@ struct drm_plane *zx_plane_init(struct drm_device *drm, struct device *dev,
 		format_count = ARRAY_SIZE(gl_formats);
 		break;
 	case DRM_PLANE_TYPE_OVERLAY:
-		/* TODO: add video layer (vl) support */
+		helper = &zx_vl_plane_helper_funcs;
+		formats = vl_formats;
+		format_count = ARRAY_SIZE(vl_formats);
 		break;
 	default:
 		return ERR_PTR(-ENODEV);
diff --git a/drivers/gpu/drm/zte/zx_plane_regs.h b/drivers/gpu/drm/zte/zx_plane_regs.h
index 3dde6716a558..65f271aeabed 100644
--- a/drivers/gpu/drm/zte/zx_plane_regs.h
+++ b/drivers/gpu/drm/zte/zx_plane_regs.h
@@ -46,6 +46,37 @@
 #define GL_POS_X(x)	(((x) << GL_POS_X_SHIFT) & GL_POS_X_MASK)
 #define GL_POS_Y(x)	(((x) << GL_POS_Y_SHIFT) & GL_POS_Y_MASK)
 
+/* VL registers */
+#define VL_CTRL0			0x00
+#define VL_UPDATE			BIT(3)
+#define VL_CTRL1			0x04
+#define VL_YUV420_PLANAR		BIT(5)
+#define VL_YUV422_SHIFT			3
+#define VL_YUV422_YUYV			(0 << VL_YUV422_SHIFT)
+#define VL_YUV422_YVYU			(1 << VL_YUV422_SHIFT)
+#define VL_YUV422_UYVY			(2 << VL_YUV422_SHIFT)
+#define VL_YUV422_VYUY			(3 << VL_YUV422_SHIFT)
+#define VL_FMT_YUV420			0
+#define VL_FMT_YUV422			1
+#define VL_FMT_YUV420_P010		2
+#define VL_FMT_YUV420_HANTRO		3
+#define VL_FMT_YUV444_8BIT		4
+#define VL_FMT_YUV444_10BIT		5
+#define VL_CTRL2			0x08
+#define VL_SCALER_BYPASS_MODE		BIT(0)
+#define VL_STRIDE			0x0c
+#define LUMA_STRIDE_SHIFT		16
+#define LUMA_STRIDE_MASK		(0xffff << LUMA_STRIDE_SHIFT)
+#define CHROMA_STRIDE_SHIFT		0
+#define CHROMA_STRIDE_MASK		(0xffff << CHROMA_STRIDE_SHIFT)
+#define VL_SRC_SIZE			0x10
+#define VL_Y				0x14
+#define VL_POS_START			0x30
+#define VL_POS_END			0x34
+
+#define LUMA_STRIDE(x)	 (((x) << LUMA_STRIDE_SHIFT) & LUMA_STRIDE_MASK)
+#define CHROMA_STRIDE(x) (((x) << CHROMA_STRIDE_SHIFT) & CHROMA_STRIDE_MASK)
+
 /* CSC registers */
 #define CSC_CTRL0			0x30
 #define CSC_COV_MODE_SHIFT		16
@@ -69,6 +100,18 @@
 #define RSZ_DEST_CFG			0x04
 #define RSZ_ENABLE_CFG			0x14
 
+#define RSZ_VL_LUMA_HOR			0x08
+#define RSZ_VL_LUMA_VER			0x0c
+#define RSZ_VL_CHROMA_HOR		0x10
+#define RSZ_VL_CHROMA_VER		0x14
+#define RSZ_VL_CTRL_CFG			0x18
+#define RSZ_VL_FMT_SHIFT		3
+#define RSZ_VL_FMT_MASK			(0x3 << RSZ_VL_FMT_SHIFT)
+#define RSZ_VL_FMT_YCBCR420		(0x0 << RSZ_VL_FMT_SHIFT)
+#define RSZ_VL_FMT_YCBCR422		(0x1 << RSZ_VL_FMT_SHIFT)
+#define RSZ_VL_FMT_YCBCR444		(0x2 << RSZ_VL_FMT_SHIFT)
+#define RSZ_VL_ENABLE_CFG		0x1c
+
 #define RSZ_VER_SHIFT			16
 #define RSZ_VER_MASK			(0xffff << RSZ_VER_SHIFT)
 #define RSZ_HOR_SHIFT			0
@@ -77,6 +120,14 @@
 #define RSZ_VER(x)	(((x) << RSZ_VER_SHIFT) & RSZ_VER_MASK)
 #define RSZ_HOR(x)	(((x) << RSZ_HOR_SHIFT) & RSZ_HOR_MASK)
 
+#define RSZ_DATA_STEP_SHIFT		16
+#define RSZ_DATA_STEP_MASK		(0xffff << RSZ_DATA_STEP_SHIFT)
+#define RSZ_PARA_STEP_SHIFT		0
+#define RSZ_PARA_STEP_MASK		(0xffff << RSZ_PARA_STEP_SHIFT)
+
+#define RSZ_DATA_STEP(x) (((x) << RSZ_DATA_STEP_SHIFT) & RSZ_DATA_STEP_MASK)
+#define RSZ_PARA_STEP(x) (((x) << RSZ_PARA_STEP_SHIFT) & RSZ_PARA_STEP_MASK)
+
 /* HBSC registers */
 #define HBSC_SATURATION			0x00
 #define HBSC_HUE			0x04
diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c
index 73fe15c17c32..8ca9c4bdeeaf 100644
--- a/drivers/gpu/drm/zte/zx_vou.c
+++ b/drivers/gpu/drm/zte/zx_vou.c
@@ -93,10 +93,38 @@ struct zx_crtc {
 	const struct zx_crtc_bits *bits;
 	enum vou_chn_type chn_type;
 	struct clk *pixclk;
+	u32 overlay_bitmap;
 };
 
 #define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc)
 
+struct zx_vl_bits {
+	u32 enable;
+	u32 chnsel;
+	u32 clksel;
+};
+
+static const struct zx_vl_bits zx_vl_bits[VL_NUM] = {
+	{
+		.enable = OSD_CTRL0_VL0_EN,
+		.chnsel = OSD_CTRL0_VL0_SEL,
+		.clksel = VOU_CLK_VL0_SEL,
+	}, {
+		.enable = OSD_CTRL0_VL1_EN,
+		.chnsel = OSD_CTRL0_VL1_SEL,
+		.clksel = VOU_CLK_VL1_SEL,
+	}, {
+		.enable = OSD_CTRL0_VL2_EN,
+		.chnsel = OSD_CTRL0_VL2_SEL,
+		.clksel = VOU_CLK_VL2_SEL,
+	},
+};
+
+struct zx_overlay {
+	struct drm_plane *plane;
+	const struct zx_vl_bits *bits;
+};
+
 struct zx_vou_hw {
 	struct device *dev;
 	void __iomem *osd;
@@ -110,6 +138,7 @@ struct zx_vou_hw {
 	struct clk *aux_clk;
 	struct zx_crtc *main_crtc;
 	struct zx_crtc *aux_crtc;
+	struct zx_overlay overlays[VL_NUM];
 };
 
 static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc)
@@ -404,6 +433,112 @@ void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe)
 		       zcrtc->bits->int_frame_mask, 0);
 }
 
+static int zx_overlay_find_vl_idx(struct drm_plane *plane,
+				  struct zx_vou_hw *vou)
+{
+	int i;
+
+	for (i = 0; i < VL_NUM; i++) {
+		if (vou->overlays[i].plane == plane)
+			break;
+	}
+
+	if (i == VL_NUM) {
+		DRM_DEV_ERROR(vou->dev, "failed to find VL\n");
+		return -EINVAL;
+	}
+
+	return i;
+}
+
+void zx_overlay_enable(struct drm_plane *plane)
+{
+	struct zx_crtc *zcrtc = to_zx_crtc(plane->state->crtc);
+	struct zx_vou_hw *vou = zcrtc->vou;
+	const struct zx_vl_bits *bits;
+	int idx;
+
+	idx = zx_overlay_find_vl_idx(plane, vou);
+	if (idx < 0)
+		return;
+
+	bits = vou->overlays[idx].bits;
+	zcrtc->overlay_bitmap |= 1 << idx;
+
+	if (zcrtc->chn_type == VOU_CHN_MAIN) {
+		zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 0);
+		zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 0);
+	} else {
+		zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel,
+			       bits->chnsel);
+		zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel,
+			       bits->clksel);
+	}
+
+	zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable);
+}
+
+void zx_overlay_disable(struct drm_plane *plane)
+{
+	struct zx_crtc *zcrtc = to_zx_crtc(plane->crtc);
+	struct zx_vou_hw *vou = zcrtc->vou;
+	const struct zx_vl_bits *bits;
+	int idx;
+
+	idx = zx_overlay_find_vl_idx(plane, vou);
+	if (idx < 0)
+		return;
+
+	bits = vou->overlays[idx].bits;
+	zcrtc->overlay_bitmap &= ~(1 << idx);
+
+	zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0);
+}
+
+static void zx_overlay_init(struct drm_device *drm, struct zx_vou_hw *vou)
+{
+	struct device *dev = vou->dev;
+	struct drm_plane *plane;
+	struct zx_layer_data data;
+	int i;
+
+	/*
+	 * VL0 has some quirks on scaling support which need special handling.
+	 * Let's leave it out for now.
+	 */
+	for (i = 1; i < VL_NUM; i++) {
+		data.layer = vou->osd + OSD_VL_OFFSET(i);
+		data.hbsc = vou->osd + HBSC_VL_OFFSET(i);
+		data.rsz = vou->otfppu + RSZ_VL_OFFSET(i);
+
+		plane = zx_plane_init(drm, dev, &data, DRM_PLANE_TYPE_OVERLAY);
+		if (IS_ERR(plane)) {
+			DRM_DEV_ERROR(dev, "failed to init overlay %d\n", i);
+			continue;
+		}
+
+		vou->overlays[i].plane = plane;
+		vou->overlays[i].bits = &zx_vl_bits[i];
+	}
+}
+
+static inline void zx_osd_int_update(struct zx_crtc *zcrtc)
+{
+	u32 bitmap = zcrtc->overlay_bitmap;
+	int i;
+
+	vou_chn_set_update(zcrtc);
+	zx_plane_set_update(zcrtc->primary);
+
+	if (bitmap) {
+		for (i = 0; i < VL_NUM; i++)  {
+			if ((bitmap & (1 << i)) == 0)
+				continue;
+			zx_plane_set_update(zcrtc->vou->overlays[i].plane);
+		}
+	}
+}
+
 static irqreturn_t vou_irq_handler(int irq, void *dev_id)
 {
 	struct zx_vou_hw *vou = dev_id;
@@ -423,15 +558,11 @@ static irqreturn_t vou_irq_handler(int irq, void *dev_id)
 	state = zx_readl(vou->osd + OSD_INT_STA);
 	zx_writel(vou->osd + OSD_INT_CLRSTA, state);
 
-	if (state & OSD_INT_MAIN_UPT) {
-		vou_chn_set_update(vou->main_crtc);
-		zx_plane_set_update(vou->main_crtc->primary);
-	}
+	if (state & OSD_INT_MAIN_UPT)
+		zx_osd_int_update(vou->main_crtc);
 
-	if (state & OSD_INT_AUX_UPT) {
-		vou_chn_set_update(vou->aux_crtc);
-		zx_plane_set_update(vou->aux_crtc->primary);
-	}
+	if (state & OSD_INT_AUX_UPT)
+		zx_osd_int_update(vou->aux_crtc);
 
 	if (state & OSD_INT_ERROR)
 		DRM_DEV_ERROR(vou->dev, "OSD ERROR: 0x%08x!\n", state);
@@ -611,6 +742,8 @@ static int zx_crtc_bind(struct device *dev, struct device *master, void *data)
 		goto disable_ppu_clk;
 	}
 
+	zx_overlay_init(drm, vou);
+
 	return 0;
 
 disable_ppu_clk:
diff --git a/drivers/gpu/drm/zte/zx_vou.h b/drivers/gpu/drm/zte/zx_vou.h
index 349e06cd86f4..1559c1f79db7 100644
--- a/drivers/gpu/drm/zte/zx_vou.h
+++ b/drivers/gpu/drm/zte/zx_vou.h
@@ -43,4 +43,7 @@ struct vou_inf {
 int zx_vou_enable_vblank(struct drm_device *drm, unsigned int pipe);
 void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe);
 
+void zx_overlay_enable(struct drm_plane *plane);
+void zx_overlay_disable(struct drm_plane *plane);
+
 #endif /* __ZX_VOU_H__ */
diff --git a/drivers/gpu/drm/zte/zx_vou_regs.h b/drivers/gpu/drm/zte/zx_vou_regs.h
index f44e7a4ae441..193c1ce01fe7 100644
--- a/drivers/gpu/drm/zte/zx_vou_regs.h
+++ b/drivers/gpu/drm/zte/zx_vou_regs.h
@@ -22,6 +22,15 @@
 #define AUX_HBSC_OFFSET			0x860
 #define AUX_RSZ_OFFSET			0x800
 
+#define OSD_VL0_OFFSET			0x040
+#define OSD_VL_OFFSET(i)		(OSD_VL0_OFFSET + 0x050 * (i))
+
+#define HBSC_VL0_OFFSET			0x760
+#define HBSC_VL_OFFSET(i)		(HBSC_VL0_OFFSET + 0x040 * (i))
+
+#define RSZ_VL1_U0			0xa00
+#define RSZ_VL_OFFSET(i)		(RSZ_VL1_U0 + 0x200 * (i))
+
 /* OSD (GPC_GLOBAL) registers */
 #define OSD_INT_STA			0x04
 #define OSD_INT_CLRSTA			0x08
@@ -42,6 +51,12 @@
 )
 #define OSD_INT_ENABLE (OSD_INT_ERROR | OSD_INT_AUX_UPT | OSD_INT_MAIN_UPT)
 #define OSD_CTRL0			0x10
+#define OSD_CTRL0_VL0_EN		BIT(13)
+#define OSD_CTRL0_VL0_SEL		BIT(12)
+#define OSD_CTRL0_VL1_EN		BIT(11)
+#define OSD_CTRL0_VL1_SEL		BIT(10)
+#define OSD_CTRL0_VL2_EN		BIT(9)
+#define OSD_CTRL0_VL2_SEL		BIT(8)
 #define OSD_CTRL0_GL0_EN		BIT(7)
 #define OSD_CTRL0_GL0_SEL		BIT(6)
 #define OSD_CTRL0_GL1_EN		BIT(5)
@@ -146,6 +161,9 @@
 #define VOU_INF_DATA_SEL		0x08
 #define VOU_SOFT_RST			0x14
 #define VOU_CLK_SEL			0x18
+#define VOU_CLK_VL2_SEL			BIT(8)
+#define VOU_CLK_VL1_SEL			BIT(7)
+#define VOU_CLK_VL0_SEL			BIT(6)
 #define VOU_CLK_GL1_SEL			BIT(5)
 #define VOU_CLK_GL0_SEL			BIT(4)
 #define VOU_CLK_REQEN			0x20
-- 
1.9.1

^ permalink raw reply related

* [PATCH] drm: zte: add overlay plane support
From: Shawn Guo @ 2016-12-20 12:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161208155755.GY31595@intel.com>

Hi Ville,

On Thu, Dec 08, 2016 at 05:57:55PM +0200, Ville Syrj?l? wrote:
> On Thu, Dec 08, 2016 at 11:12:41AM +0800, Shawn Guo wrote:
> <snip>
> > +static void zx_vl_plane_atomic_update(struct drm_plane *plane,
> > +				      struct drm_plane_state *old_state)
> > +{
> > +	struct zx_plane *zplane = to_zx_plane(plane);
> > +	struct drm_framebuffer *fb = plane->state->fb;
> > +	struct drm_gem_cma_object *cma_obj;
> > +	void __iomem *layer = zplane->layer;
> > +	void __iomem *hbsc = zplane->hbsc;
> > +	void __iomem *paddr_reg;
> > +	dma_addr_t paddr;
> > +	u32 src_x, src_y, src_w, src_h;
> > +	u32 dst_x, dst_y, dst_w, dst_h;
> > +	uint32_t format;
> > +	u32 fmt;
> > +	int num_planes;
> > +	int i;
> > +
> > +	if (!fb)
> > +		return;
> > +
> > +	format = fb->pixel_format;
> > +
> > +	src_x = plane->state->src_x >> 16;
> > +	src_y = plane->state->src_y >> 16;
> > +	src_w = plane->state->src_w >> 16;
> > +	src_h = plane->state->src_h >> 16;
> > +
> > +	dst_x = plane->state->crtc_x;
> > +	dst_y = plane->state->crtc_y;
> > +	dst_w = plane->state->crtc_w;
> > +	dst_h = plane->state->crtc_h;
> 
> This shouls use the clipped coordiantes.

Thanks for spotting this.  I will fix it in v2.

Shawn

^ permalink raw reply

* [PATCH 0/2] s5p-mfc fix for using reserved memory
From: Marek Szyprowski @ 2016-12-20 11:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481888915-19624-1-git-send-email-pankaj.dubey@samsung.com>

Hi Pankaj


On 2016-12-16 12:48, Pankaj Dubey wrote:
> It has been observed on ARM64 based Exynos SoC, if IOMMU is not enabled
> and we try to use reserved memory for MFC, reqbufs fails with below
> mentioned error
> ---------------------------------------------------------------------------
> V4L2 Codec decoding example application
> Kamil Debski <k.debski@samsung.com>
> Copyright 2012 Samsung Electronics Co., Ltd.
>
> Opening MFC.
> (mfc.c:mfc_open:58): MFC Info (/dev/video0): driver="s5p-mfc" \
> bus_info="platform:12c30000.mfc0" card="s5p-mfc-dec" fd=0x4[
> 42.339165] Remapping memory failed, error: -6
>
> MFC Open Success.
> (main.c:main:711): Successfully opened all necessary files and devices
> (mfc.c:mfc_dec_setup_output:103): Setup MFC decoding OUTPUT buffer \
> size=4194304 (requested=4194304)
> (mfc.c:mfc_dec_setup_output:120): Number of MFC OUTPUT buffers is 2 \
> (requested 2)
>
> [App] Out buf phy : 0x00000000, virt : 0xffffffff
> Output Length is = 0x300000
> Error (mfc.c:mfc_dec_setup_output:145): Failed to MMAP MFC OUTPUT buffer
> -------------------------------------------------------------------------
> This is because the device requesting for memory is mfc0.left not the parent mfc0.
> Hence setting of alloc_devs need to be done only if IOMMU is enabled
> and in that case both the left and right device is treated as mfc0 only.
> Also we need to populate vb2_queue's dev pointer with mfc dev pointer.

I also got this issue but Your solution is imho not the proper approach.
Too much hacking in the driver, while the issue is in the core. ARM64 
requires
to call arch_setup_dma_ops() for each device that will be used for 
dma-mapping.
So the issue is in drivers/of/of_reserved_mem.c - in
of_reserved_mem_device_init_by_idx() function, which should ensure that
arch_setup_dma_ops() is called also for the virtual devices for reserved 
memory.

s5p-mfc driver however still requires some patching for 
dma-mapping/iommu glue
used on ARM64 architecture.

> Smitha T Murthy (2):
>    media: s5p-mfc: convert drivers to use the new vb2_queue dev field
>    media: s5p-mfc: fix MMAP of mfc buffer during reqbufs
>
>   drivers/media/platform/s5p-mfc/s5p_mfc.c     |  2 ++
>   drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 17 ++++++++++-------
>   drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 18 +++++++++++-------
>   3 files changed, 23 insertions(+), 14 deletions(-)
>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply

* [PATCH v3] arm64: SMMU-v2: Workaround for Cavium ThunderX erratum 28168
From: Will Deacon @ 2016-12-20 11:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <bd950765-8c1f-14d5-2be8-efa76f2d6b6b@arm.com>

On Tue, Dec 20, 2016 at 11:52:58AM +0000, Marc Zyngier wrote:
> On 20/12/16 11:06, Geetha sowjanya wrote:
> > From: Tirumalesh Chalamarla <tchalamarla@caviumnetworks.com>
> > +#ifdef CONFIG_CAVIUM_ERRATUM_28168
> > +/*
> > + * Cavium ThunderX erratum 28168
> > + *
> > + * Due to erratum #28168 PCI-inbound MSI-X store to the interrupt
> > + * controller are delivered to the interrupt controller before older
> > + * PCI-inbound memory stores are committed. Doing a sync on SMMU
> > + * will make sure all prior data transfers are completed before
> > + * invoking ISR.
> > + *
> > + */
> > +void dev_smmu_tlb_sync(struct device *dev)
> > +{
> > +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> > +	struct arm_smmu_device *smmu = fwspec_smmu(fwspec);
> > +
> > +	if (smmu)
> > +		__arm_smmu_tlb_sync(smmu);
> > +}
> > +#endif
> 
> I'll let Robin and Will comment on this, but it strikes be as rather odd
> that nothing will happen if the SMMU is in bypass or simply compiled
> out. So this workaround is at best incomplete.

Agreed. Unless the SMMU is the cause of the issue, relying on it to
implement the workaround is fragile and unnecessarily introduces a linkage
between SMMU driver internals and the interrupt handling code.

Not a fan.

Will

^ permalink raw reply

* [PATCH v3] arm64: SMMU-v2: Workaround for Cavium ThunderX erratum 28168
From: Marc Zyngier @ 2016-12-20 11:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482231993-27571-1-git-send-email-gakula@caviumnetworks.com>

Geetha,

On 20/12/16 11:06, Geetha sowjanya wrote:
> From: Tirumalesh Chalamarla <tchalamarla@caviumnetworks.com>
> 
>   This patch implements Cavium ThunderX erratum 28168.
> 
>   PCI requires stores complete in order. Due to erratum #28168
>   PCI-inbound MSI-X store to the interrupt controller are delivered
>   to the interrupt controller before older PCI-inbound memory stores
>   are committed.
>   Doing a sync on SMMU will make sure all prior data transfers are
>   completed before invoking ISR.
> 
>  changes from v2:
>         - added entry in Documentation/arm64/silicon-errata.txt
>         - moved registration of the preflow_handler into
>            msi_domain_ops.msi_finish() handler.
>         - create linux/arm.smmu.h to expose smmu API.
> 
> Signed-off-by: Tirumalesh Chalamarla <Tirumalesh.Chalamarla@cavium.com>

Where is your SoB? This is a requirement if you're picking a patch from
someone else.

> ---
>  Documentation/arm64/silicon-errata.txt   |  1 +
>  arch/arm64/Kconfig                       | 12 ++++++++
>  arch/arm64/include/asm/cpucaps.h         |  3 +-
>  arch/arm64/kernel/cpu_errata.c           | 16 +++++++++++
>  drivers/iommu/arm-smmu.c                 | 22 +++++++++++++++
>  drivers/irqchip/irq-gic-v3-its-pci-msi.c | 48 +++++++++++++++++++++++++++++++-
>  include/linux/arm-smmu.h                 |  8 ++++++
>  7 files changed, 108 insertions(+), 2 deletions(-)
>  create mode 100644 include/linux/arm-smmu.h
> 
> diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
> index 405da11..1311f90 100644
> --- a/Documentation/arm64/silicon-errata.txt
> +++ b/Documentation/arm64/silicon-errata.txt
> @@ -61,5 +61,6 @@ stable kernels.
>  | Cavium         | ThunderX GICv3  | #23154          | CAVIUM_ERRATUM_23154    |
>  | Cavium         | ThunderX Core   | #27456          | CAVIUM_ERRATUM_27456    |
>  | Cavium         | ThunderX SMMUv2 | #27704          | N/A		       |
> +| Cavium         | ThunderX PCI    | #28168          | CAVIUM_ERRATUM_28168    |
>  |                |                 |                 |                         |
>  | Freescale/NXP  | LS2080A/LS1043A | A-008585        | FSL_ERRATUM_A008585     |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 969ef88..cb647f4 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -474,6 +474,18 @@ config CAVIUM_ERRATUM_27456
>  
>  	  If unsure, say Y.
>  
> +config CAVIUM_ERRATUM_28168
> +       bool "Cavium erratum 28168: Make sure DMA data transfer is done before MSIX"
> +       depends on ARM64 && ARM_SMMU
> +       default y
> +       select IRQ_PREFLOW_FASTEOI
> +       help
> +        Due to erratum #28168 PCI-inbound MSI-X store to the interrupt
> +        controller are delivered to the interrupt controller before older
> +        PCI-inbound memory stores are committed. Doing a sync on SMMU
> +        will make sure all prior data transfers are done before invoking ISR.
> +
> +        If unsure, say Y.
>  endmenu
>  
>  
> diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
> index 87b4465..6975a01 100644
> --- a/arch/arm64/include/asm/cpucaps.h
> +++ b/arch/arm64/include/asm/cpucaps.h
> @@ -34,7 +34,8 @@
>  #define ARM64_HAS_32BIT_EL0			13
>  #define ARM64_HYP_OFFSET_LOW			14
>  #define ARM64_MISMATCHED_CACHE_LINE_SIZE	15
> +#define ARM64_WORKAROUND_CAVIUM_28168		16
>  
> -#define ARM64_NCAPS				16
> +#define ARM64_NCAPS				17
>  
>  #endif /* __ASM_CPUCAPS_H */
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index b75e917..fac6d74 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -123,6 +123,22 @@ static int cpu_enable_trap_ctr_access(void *__unused)
>  		MIDR_RANGE(MIDR_THUNDERX_81XX, 0x00, 0x00),
>  	},
>  #endif
> +#ifdef CONFIG_CAVIUM_ERRATUM_28168
> +	{
> +	/* Cavium ThunderX, T88 pass 1.x - 2.1 */
> +		.desc = "Cavium erratum 28168",
> +		.capability = ARM64_WORKAROUND_CAVIUM_28168,
> +		MIDR_RANGE(MIDR_THUNDERX, 0x00,
> +			   (1 << MIDR_VARIANT_SHIFT) | 1),
> +	},
> +	{
> +	/* Cavium ThunderX, T81 pass 1.0 */
> +		.desc = "Cavium erratum 28168",
> +		.capability = ARM64_WORKAROUND_CAVIUM_28168,
> +		MIDR_RANGE(MIDR_THUNDERX_81XX, 0x00, 0x00),
> +	},
> +#endif
> +
>  	{
>  		.desc = "Mismatched cache line size",
>  		.capability = ARM64_MISMATCHED_CACHE_LINE_SIZE,
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 06167da..451b393 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -49,6 +49,8 @@
>  #include <linux/spinlock.h>
>  
>  #include <linux/amba/bus.h>
> +#include <linux/arm-smmu.h>
> +
>  
>  #include "io-pgtable.h"
>  
> @@ -577,6 +579,26 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu)
>  	}
>  }
>  
> +#ifdef CONFIG_CAVIUM_ERRATUM_28168
> +/*
> + * Cavium ThunderX erratum 28168
> + *
> + * Due to erratum #28168 PCI-inbound MSI-X store to the interrupt
> + * controller are delivered to the interrupt controller before older
> + * PCI-inbound memory stores are committed. Doing a sync on SMMU
> + * will make sure all prior data transfers are completed before
> + * invoking ISR.
> + *
> + */
> +void dev_smmu_tlb_sync(struct device *dev)
> +{
> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> +	struct arm_smmu_device *smmu = fwspec_smmu(fwspec);
> +
> +	if (smmu)
> +		__arm_smmu_tlb_sync(smmu);
> +}
> +#endif

I'll let Robin and Will comment on this, but it strikes be as rather odd
that nothing will happen if the SMMU is in bypass or simply compiled
out. So this workaround is at best incomplete.

>  static void arm_smmu_tlb_sync(void *cookie)
>  {
>  	struct arm_smmu_domain *smmu_domain = cookie;
> diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
> index aee1c60..36ce696 100644
> --- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c
> +++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
> @@ -20,6 +20,7 @@
>  #include <linux/of.h>
>  #include <linux/of_irq.h>
>  #include <linux/of_pci.h>
> +#include <linux/arm-smmu.h>
>  
>  static void its_mask_msi_irq(struct irq_data *d)
>  {
> @@ -86,11 +87,53 @@ static int its_pci_msi_prepare(struct irq_domain *domain, struct device *dev,
>  
>  	/* ITS specific DeviceID, as the core ITS ignores dev. */
>  	info->scratchpad[0].ul = pci_msi_domain_get_msi_rid(domain, pdev);
> -
> +	info->scratchpad[1].ptr = &pdev->dev;
>  	return msi_info->ops->msi_prepare(domain->parent,
>  					  dev, dev_alias.count, info);
>  }
>  
> +#ifdef CONFIG_CAVIUM_ERRATUM_28168
> +#define	THUNDER_PME_DEVICE_ID		0xA100
> +
> +static void cavium_irq_preflow_handler(struct irq_data *data)
> +{
> +	struct pci_dev *pdev;
> +
> +	pdev = msi_desc_to_pci_dev(irq_data_get_msi_desc(data));
> +	dev_smmu_tlb_sync(&pdev->dev);
> +}

Missing space between the two functions.

> +static void cavium_its_pci_msi_finish(msi_alloc_info_t *info, int ret)
> +{
> +	struct device *dev = info->scratchpad[1].ptr;
> +	struct pci_dev *pdev = to_pci_dev(dev);
> +	struct device *parent_dev;
> +	struct msi_desc *desc;
> +
> +	if (ret)
> +		return;
> +
> +	if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) {
> +		for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) {
> +			pdev = to_pci_dev(parent_dev);
> +			if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT)
> +				continue;
> +
> +			if (pdev->device == THUNDER_PME_DEVICE_ID)
> +				for_each_pci_msi_entry(desc, to_pci_dev(dev))
> +					__irq_set_preflow_handler(desc->irq, cavium_irq_preflow_handler);

So only the PME device is affected? Why can't you simply use INTx for it
(there is already some provision for that in the PME driver
("pcie_pme=nomsi").

If your PME device doesn't implement legacy interrupt, can't you do
something in the PME interrupt handler instead? Like reading from the
end-point or something similar?

> +			break;
> +		}
> +	}
> +}
> +#else
> +static void cavium_irq_preflow_handler(struct irq_data *data)
> +{
> +}

Why is this defined? It is just going to generate a warning if
CONFIG_CAVIUM_ERRATUM_28168 is not defined...

> +static void cavium_its_pci_msi_finish(msi_alloc_info_t *info, int ret)
> +{
> +}

You might as well have
#define cavium_its_pci_msi_finish	NULL

> +#endif
> +
>  static struct msi_domain_ops its_pci_msi_ops = {
>  	.msi_prepare	= its_pci_msi_prepare,
>  };
> @@ -118,6 +161,9 @@ static int __init its_pci_msi_init_one(struct fwnode_handle *handle,
>  		return -ENXIO;
>  	}
>  
> +	if (cpus_have_cap(ARM64_WORKAROUND_CAVIUM_28168))
> +		its_pci_msi_ops.msi_finish = cavium_its_pci_msi_finish;
> +
>  	if (!pci_msi_create_irq_domain(handle, &its_pci_msi_domain_info,
>  				       parent)) {
>  		pr_err("%s: Unable to create PCI domain\n", name);
> diff --git a/include/linux/arm-smmu.h b/include/linux/arm-smmu.h
> new file mode 100644
> index 0000000..d3f5dff
> --- /dev/null
> +++ b/include/linux/arm-smmu.h
> @@ -0,0 +1,8 @@
> +#ifndef _ARM_SMMU_H
> +#define _ARM_SMMU_H
> +
> +#include<linux/pci.h>
> +
> +extern void dev_smmu_tlb_sync(struct device *dev);
> +
> +#endif /* _ARM_SMMU_H */
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [linux-sunxi] Problems to Allwinner H3's eFUSE/SID
From: Bernhard Nortmann @ 2016-12-20 11:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <136061482160932@web34j.yandex.ru>

Hi all!

This is rather interesting stuff. Actually it's possible to find partial
documentation for this method (of reading SID/efuse values) even for older
SoCs. There's an early version of the A20 User Manual (Revision 1.0 -
Feb. 18, 2013) available on the net, where chapter 1.18 describes the
registers involved. This section seems to have been removed in later
editions. (Search for the file A20_UM-V1.020130322.pdf)

The U-Boot code that Allwinner published also has source files for various
SoCs that contain corresponding implementations of `sid_program_key()` and
`sid_read_key()` (in efuse.c),
see https://github.com/allwinner-zh/bootloader/search?q=sid_read_key.

Regards, B. Nortmann

Am 19.12.2016 um 16:22 schrieb Icenowy Zheng:
> Hi everyone,
>
> Today, I and KotCzarny on IRC of linux-sunxi found a problem in the SID
> controller of H3 (incl. H2+).
>
> See https://irclog.whitequark.org/linux-sunxi/2016-12-19 .
>
> Two read method of the H3 eFUSE is used in the BSP: by register accessing, or
> directly access 0x01c14200.
>
>  From http://linux-sunxi.org/SID_Register_Guide we can see a difference between
> the H3 SIDs read out by sunxi-fel and the H3 SIDs read out by devmem2 (in
> legacy kernel).
>
> According to the source of H2+ BSP[1], H2+ and H3 can be differed by the last
> byte of the first word of SID. (0x42 and 0x83 is H2+, 0x00 and 0x81 is H3,
> 0x58 is H3D (currently not known SoC) )
>
> However, all the SIDs retrieved by `sunxi-fel sid`, both H2+ and H3, start
> with 0x02004620, which do not match this rule.
>
> The readout by devmem2 is satisfying this rule: their first word is
> 0x02c00081, matches H3.
>
> Then I found the SID-reading code from BSP U-Boot[2], which is based on
> register operations. With this kind of code (I wrote one prototype in
> userspace with /dev/mem), I got "02c00081 74004620 50358720 3c27048e" on
> my Orange Pi One. ("02004620 74358720 5027048e 3c0000c3" with sunxi-fel sid)
> And, after accessing to the SID by registers, the value of *0x01c14200 become
> also "02c00081".
>
> With direct access to 0x01c14200 after boot with mainline kernel, I got also
> "02004620".
>
> Then I altered the program to do the register operations with sunxi-fel, the
> result is also "02c00081", and changed `sunxi-fel sid` result to "02c00081".
>
> Summary:
>
> +-----------------------------------------------+----------------+
> | Read situation                                | The first word |
> +-----------------------------------------------+----------------+
> | Direct read by sunxi-fel                      | 02004620       |
> | Direct read in mainline /dev/mem              | 02004620       |
> | Direct read in legacy /dev/mem                | 02c00081       |
> | Register access in FEL                        | 02c00081       |
> | Register access in mainline                   | 02c00081       |
> | Direct read after register access in FEL      | 02c00081       |
> | Direct read after register access in mainline | 02c00081       |
> +-----------------------------------------------+----------------+
>
> According to some facts:
> - The register based access to SID is weird: it needs ~5 register
>    operations per word of SID.
> - Reading via register access will change the value when reading by accessing
>    0x01c14200.
> - In the u-boot code[2] there's some functions which read out the SID by
>    registers and then abandoned the value.
> - This mismatch do not exist on A64.
>
> I think that: Allwinner designed a "cache" to the SID to make the simplify the
> code to read it, and it automatically loaded the cache when booting; however,
> when doing first cache on H3, some byte shifts occured, and the value become
> wrong. A manual read on H3 can make the cache right again. This is a silicon
> bug, and fixed in A64.
>
> This raises a problem: currently many systems has used the misread SID value to
> generated lots of MAC addresses, and workaround this SID bug will change them.
>
> However, if this bug is not workarounded, the sun8i-ths driver won't work well
> (as some calibartion value lies in eFUSE). I think some early user of this
> driver has already experienced bad readout value.
> (The calibration value differs on my opi1 and KotCzarny's opipc)
>
> And many wrong SID values have been generated by `sunxi-fel sid`. (Although I
> think sunxi-fel must have the workaround)
>
> Note: in this email, "SID" and "eFUSE" both indicate the controller on H3/A64
> at 0x01c14000, which is a OTP memory implemented by eFUSE technique.
>
> Furthermore, A83T may also have this problem, testers are welcome!
>
> [1] http://filez.zoobab.com/allwinner/h2/201609022/lichee/linux-3.4/arch/arm/mach-sunxi/sun8i.c
> [2] http://filez.zoobab.com/allwinner/h2/201609022/lichee/brandy/u-boot-2011.09/arch/arm/cpu/armv7/sun8iw7/efuse.c
>
> Experiments:
> - https://gist.github.com/Icenowy/2f4859ab1bc05814522fc7445179a8c9
>    A SID readout shell script via FEL with register access.
> - https://31.135.195.151:20281/d/efuse/
>    A SID readout program via /dev/mem with register access by KotCzarny.
>    (with statically compiled binary)
>
> Regards,
> Icenowy
>

^ permalink raw reply

* [PATCH v3] arm64: SMMU-v2: Workaround for Cavium ThunderX erratum 28168
From: Geetha sowjanya @ 2016-12-20 11:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tirumalesh Chalamarla <tchalamarla@caviumnetworks.com>

  This patch implements Cavium ThunderX erratum 28168.

  PCI requires stores complete in order. Due to erratum #28168
  PCI-inbound MSI-X store to the interrupt controller are delivered
  to the interrupt controller before older PCI-inbound memory stores
  are committed.
  Doing a sync on SMMU will make sure all prior data transfers are
  completed before invoking ISR.

 changes from v2:
        - added entry in Documentation/arm64/silicon-errata.txt
        - moved registration of the preflow_handler into
           msi_domain_ops.msi_finish() handler.
        - create linux/arm.smmu.h to expose smmu API.

Signed-off-by: Tirumalesh Chalamarla <Tirumalesh.Chalamarla@cavium.com>
---
 Documentation/arm64/silicon-errata.txt   |  1 +
 arch/arm64/Kconfig                       | 12 ++++++++
 arch/arm64/include/asm/cpucaps.h         |  3 +-
 arch/arm64/kernel/cpu_errata.c           | 16 +++++++++++
 drivers/iommu/arm-smmu.c                 | 22 +++++++++++++++
 drivers/irqchip/irq-gic-v3-its-pci-msi.c | 48 +++++++++++++++++++++++++++++++-
 include/linux/arm-smmu.h                 |  8 ++++++
 7 files changed, 108 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/arm-smmu.h

diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 405da11..1311f90 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -61,5 +61,6 @@ stable kernels.
 | Cavium         | ThunderX GICv3  | #23154          | CAVIUM_ERRATUM_23154    |
 | Cavium         | ThunderX Core   | #27456          | CAVIUM_ERRATUM_27456    |
 | Cavium         | ThunderX SMMUv2 | #27704          | N/A		       |
+| Cavium         | ThunderX PCI    | #28168          | CAVIUM_ERRATUM_28168    |
 |                |                 |                 |                         |
 | Freescale/NXP  | LS2080A/LS1043A | A-008585        | FSL_ERRATUM_A008585     |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 969ef88..cb647f4 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -474,6 +474,18 @@ config CAVIUM_ERRATUM_27456
 
 	  If unsure, say Y.
 
+config CAVIUM_ERRATUM_28168
+       bool "Cavium erratum 28168: Make sure DMA data transfer is done before MSIX"
+       depends on ARM64 && ARM_SMMU
+       default y
+       select IRQ_PREFLOW_FASTEOI
+       help
+        Due to erratum #28168 PCI-inbound MSI-X store to the interrupt
+        controller are delivered to the interrupt controller before older
+        PCI-inbound memory stores are committed. Doing a sync on SMMU
+        will make sure all prior data transfers are done before invoking ISR.
+
+        If unsure, say Y.
 endmenu
 
 
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 87b4465..6975a01 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -34,7 +34,8 @@
 #define ARM64_HAS_32BIT_EL0			13
 #define ARM64_HYP_OFFSET_LOW			14
 #define ARM64_MISMATCHED_CACHE_LINE_SIZE	15
+#define ARM64_WORKAROUND_CAVIUM_28168		16
 
-#define ARM64_NCAPS				16
+#define ARM64_NCAPS				17
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index b75e917..fac6d74 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -123,6 +123,22 @@ static int cpu_enable_trap_ctr_access(void *__unused)
 		MIDR_RANGE(MIDR_THUNDERX_81XX, 0x00, 0x00),
 	},
 #endif
+#ifdef CONFIG_CAVIUM_ERRATUM_28168
+	{
+	/* Cavium ThunderX, T88 pass 1.x - 2.1 */
+		.desc = "Cavium erratum 28168",
+		.capability = ARM64_WORKAROUND_CAVIUM_28168,
+		MIDR_RANGE(MIDR_THUNDERX, 0x00,
+			   (1 << MIDR_VARIANT_SHIFT) | 1),
+	},
+	{
+	/* Cavium ThunderX, T81 pass 1.0 */
+		.desc = "Cavium erratum 28168",
+		.capability = ARM64_WORKAROUND_CAVIUM_28168,
+		MIDR_RANGE(MIDR_THUNDERX_81XX, 0x00, 0x00),
+	},
+#endif
+
 	{
 		.desc = "Mismatched cache line size",
 		.capability = ARM64_MISMATCHED_CACHE_LINE_SIZE,
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 06167da..451b393 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -49,6 +49,8 @@
 #include <linux/spinlock.h>
 
 #include <linux/amba/bus.h>
+#include <linux/arm-smmu.h>
+
 
 #include "io-pgtable.h"
 
@@ -577,6 +579,26 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu)
 	}
 }
 
+#ifdef CONFIG_CAVIUM_ERRATUM_28168
+/*
+ * Cavium ThunderX erratum 28168
+ *
+ * Due to erratum #28168 PCI-inbound MSI-X store to the interrupt
+ * controller are delivered to the interrupt controller before older
+ * PCI-inbound memory stores are committed. Doing a sync on SMMU
+ * will make sure all prior data transfers are completed before
+ * invoking ISR.
+ *
+ */
+void dev_smmu_tlb_sync(struct device *dev)
+{
+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+	struct arm_smmu_device *smmu = fwspec_smmu(fwspec);
+
+	if (smmu)
+		__arm_smmu_tlb_sync(smmu);
+}
+#endif
 static void arm_smmu_tlb_sync(void *cookie)
 {
 	struct arm_smmu_domain *smmu_domain = cookie;
diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
index aee1c60..36ce696 100644
--- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/of_pci.h>
+#include <linux/arm-smmu.h>
 
 static void its_mask_msi_irq(struct irq_data *d)
 {
@@ -86,11 +87,53 @@ static int its_pci_msi_prepare(struct irq_domain *domain, struct device *dev,
 
 	/* ITS specific DeviceID, as the core ITS ignores dev. */
 	info->scratchpad[0].ul = pci_msi_domain_get_msi_rid(domain, pdev);
-
+	info->scratchpad[1].ptr = &pdev->dev;
 	return msi_info->ops->msi_prepare(domain->parent,
 					  dev, dev_alias.count, info);
 }
 
+#ifdef CONFIG_CAVIUM_ERRATUM_28168
+#define	THUNDER_PME_DEVICE_ID		0xA100
+
+static void cavium_irq_preflow_handler(struct irq_data *data)
+{
+	struct pci_dev *pdev;
+
+	pdev = msi_desc_to_pci_dev(irq_data_get_msi_desc(data));
+	dev_smmu_tlb_sync(&pdev->dev);
+}
+static void cavium_its_pci_msi_finish(msi_alloc_info_t *info, int ret)
+{
+	struct device *dev = info->scratchpad[1].ptr;
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct device *parent_dev;
+	struct msi_desc *desc;
+
+	if (ret)
+		return;
+
+	if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) {
+		for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) {
+			pdev = to_pci_dev(parent_dev);
+			if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT)
+				continue;
+
+			if (pdev->device == THUNDER_PME_DEVICE_ID)
+				for_each_pci_msi_entry(desc, to_pci_dev(dev))
+					__irq_set_preflow_handler(desc->irq, cavium_irq_preflow_handler);
+			break;
+		}
+	}
+}
+#else
+static void cavium_irq_preflow_handler(struct irq_data *data)
+{
+}
+static void cavium_its_pci_msi_finish(msi_alloc_info_t *info, int ret)
+{
+}
+#endif
+
 static struct msi_domain_ops its_pci_msi_ops = {
 	.msi_prepare	= its_pci_msi_prepare,
 };
@@ -118,6 +161,9 @@ static int __init its_pci_msi_init_one(struct fwnode_handle *handle,
 		return -ENXIO;
 	}
 
+	if (cpus_have_cap(ARM64_WORKAROUND_CAVIUM_28168))
+		its_pci_msi_ops.msi_finish = cavium_its_pci_msi_finish;
+
 	if (!pci_msi_create_irq_domain(handle, &its_pci_msi_domain_info,
 				       parent)) {
 		pr_err("%s: Unable to create PCI domain\n", name);
diff --git a/include/linux/arm-smmu.h b/include/linux/arm-smmu.h
new file mode 100644
index 0000000..d3f5dff
--- /dev/null
+++ b/include/linux/arm-smmu.h
@@ -0,0 +1,8 @@
+#ifndef _ARM_SMMU_H
+#define _ARM_SMMU_H
+
+#include<linux/pci.h>
+
+extern void dev_smmu_tlb_sync(struct device *dev);
+
+#endif /* _ARM_SMMU_H */
-- 
1.9.1

^ permalink raw reply related

* [PATCH renesas/devel 1/4] arm64: dts: r8a7796: Use R-Car Gen 3 fallback binding for msiof nodes
From: Simon Horman @ 2016-12-20 11:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAMuHMdV50sQtV_Rk5Kw=dyJ=rzX3_Fq=WThjhaFU+GPbzXNhbg@mail.gmail.com>

On Tue, Dec 20, 2016 at 11:44:14AM +0100, Geert Uytterhoeven wrote:
> On Tue, Dec 20, 2016 at 11:42 AM, Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
> > On Tue, Dec 20, 2016 at 11:32 AM, Simon Horman
> > <horms+renesas@verge.net.au> wrote:
> >> Use recently added R-Car Gen 3 fallback binding for msiof nodes in
> >> DT for r8a7796 SoC.
> >>
> >> This has no run-time effect for the current driver as the initialisation
> >> sequence is the same for the SoC-specific binding for r8a7796 and the
> >> fallback binding for R-Car Gen 3.
> >>
> >> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
> >
> > Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
> 
> and
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

I have taken the liberty of only adding your second tag.

^ permalink raw reply

* [PATCH renesas/devel 0/4] ARM, arm64: dts: Use R-Car fallback bindings for msiof nodes
From: Simon Horman @ 2016-12-20 11:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482229959-25584-1-git-send-email-horms+renesas@verge.net.au>

On Tue, Dec 20, 2016 at 11:32:35AM +0100, Simon Horman wrote:
> Hi,
> 
> this short series makes use of newly added R-Car fallback bindings in msiof
> nodes of the DTs for SoCs where the drivers in question are already used.
> 
> This should have no run-time effect at this time as the current driver
> implementations use the same initialisation sequences for SoC-specific and
> R-Car fallback bindings for all the cases covered by this patch-set.
> 
> Based on renesas-devel-20161212-v4.9
> 
> Simon Horman (4):
>   arm64: dts: r8a7796: Use R-Car Gen 3 fallback binding for msiof nodes
>   ARM: dts: r8a7791: Use R-Car Gen 2 fallback binding for msiof nodes
>   ARM: dts: r8a7792: Use R-Car Gen 2 fallback binding for msiof nodes
>   ARM: dts: r8a7790: Use R-Car Gen 2 fallback binding for msiof nodes

I have queued these up with Geert's Acks.

^ permalink raw reply

* [PATCH resend] arm64: dts: r8a7796: salvator-x: Update memory node to 4 GiB map
From: Simon Horman @ 2016-12-20 10:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481815889-15583-1-git-send-email-geert+renesas@glider.be>

On Thu, Dec 15, 2016 at 04:31:29PM +0100, Geert Uytterhoeven wrote:
> From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> 
> This patch updates memory region:
> 
>   - After changes, the new map of the Salvator-X board on R8A7796 SoC
>     Bank0: 2GiB RAM : 0x000048000000 -> 0x000bfffffff
>     Bank1: 2GiB RAM : 0x000600000000 -> 0x0067fffffff
> 
>   - Before changes, the old map looked like this:
>     Bank0: 2GiB RAM : 0x000048000000 -> 0x000bfffffff
> 
> Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> [geert: Correct size of old map]
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> Simon, please apply!
> 
> U-Boot already adds the second memory region to the "reg" property of
> the first memory node in DT, so this patch is actually a no-op.
> IMHO it doesn't make much sense to keep on pretending we don't have
> enabled memory outside the 32-bit address space.

Hi Geert,

I agree with the reasoning above and have queued up this patch for v4.11.

It is a shame that u-boot has enabled this for us as it would have
been nice to retain control of that occuring. But alas it was not to be so.

^ permalink raw reply

* [PATCH v2 renesas/devel 00/13] ARM, arm64: dts: Use R-Car fallback bindings for i2c/iic nodes
From: Simon Horman @ 2016-12-20 10:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481629559-14187-1-git-send-email-horms+renesas@verge.net.au>

On Tue, Dec 13, 2016 at 12:45:46PM +0100, Simon Horman wrote:
> Hi,
> 
> this short series makes use of newly added R-Car fallback bindings in i2c
> and iic nodes of the DTs for SoCs where the drivers in question are already
> used.
> 
> This should have no run-time effect at this time as the current driver
> implementations use the same initialisation squeuences for SoC-specific and
> R-Car fallback bindings for all the cases covered by this patch-set.
> 
> Based on renesas-devel-20161212-v4.9

I have queued these up for v4.11.

^ permalink raw reply

* [PATCH v2 1/5] clk: samsung: exynos5433: Set NoC (Network On Chip) clocks as critical
From: Sylwester Nawrocki @ 2016-12-20 10:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <58521D0F.5040704@samsung.com>

On 12/15/2016 05:33 AM, Chanwoo Choi wrote:
> Could you please review this patch?

Chanwoo, the patch looks good to me, I'm going to queue it after
v4.10-rc1 is released.

-- 
Thanks,
Sylwester

^ permalink raw reply

* [PATCH renesas/devel 4/4] ARM: dts: r8a7790: Use R-Car Gen 2 fallback binding for msiof nodes
From: Geert Uytterhoeven @ 2016-12-20 10:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482229959-25584-5-git-send-email-horms+renesas@verge.net.au>

On Tue, Dec 20, 2016 at 11:32 AM, Simon Horman
<horms+renesas@verge.net.au> wrote:
> Use recently added R-Car Gen 2 fallback binding for msiof nodes in
> DT for r8a7790 SoC.
>
> This has no run-time effect for the current driver as the initialisation
> sequence is the same for the SoC-specific binding for r8a7790 and the
> fallback binding for R-Car Gen 2.
>
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at 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

^ permalink raw reply

* [PATCH renesas/devel 3/4] ARM: dts: r8a7792: Use R-Car Gen 2 fallback binding for msiof nodes
From: Geert Uytterhoeven @ 2016-12-20 10:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482229959-25584-4-git-send-email-horms+renesas@verge.net.au>

On Tue, Dec 20, 2016 at 11:32 AM, Simon Horman
<horms+renesas@verge.net.au> wrote:
> Use recently added R-Car Gen 2 fallback binding for msiof nodes in
> DT for r8a7792 SoC.
>
> This has no run-time effect for the current driver as the initialisation
> sequence is the same for the SoC-specific binding for r8a7792 and the
> fallback binding for R-Car Gen 2.
>
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>



-- 
Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at 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

^ permalink raw reply

* [linux-sunxi][PATCH] clk: sunxi-ng: A31: Fix spdif clock register
From: codekipper at gmail.com @ 2016-12-20 10:44 UTC (permalink / raw)
  To: linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

As the SPDIF was rarely documented on the earlier Allwinner SoCs
it was assumed that it had a similar clock register to the one
described in the H3 User Manual.

However this is not the case and it looks to shares the same setup
as the I2S clock registers.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 drivers/clk/sunxi-ng/ccu-sun6i-a31.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
index fc75a335a7ce..4c9a920ff4ab 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
@@ -468,8 +468,8 @@ static SUNXI_CCU_MUX_WITH_GATE(daudio0_clk, "daudio0", daudio_parents,
 static SUNXI_CCU_MUX_WITH_GATE(daudio1_clk, "daudio1", daudio_parents,
 			       0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
 
-static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
-			     0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
+static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", daudio_parents,
+			       0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
 
 static SUNXI_CCU_GATE(usb_phy0_clk,	"usb-phy0",	"osc24M",
 		      0x0cc, BIT(8), 0);
-- 
2.11.0

^ permalink raw reply related

* [PATCH renesas/devel 1/4] arm64: dts: r8a7796: Use R-Car Gen 3 fallback binding for msiof nodes
From: Geert Uytterhoeven @ 2016-12-20 10:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAMuHMdXpN9x5YH0tiSRxme0yySS1NpaF41_DaePzuWd+3QD=AQ@mail.gmail.com>

On Tue, Dec 20, 2016 at 11:42 AM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> On Tue, Dec 20, 2016 at 11:32 AM, Simon Horman
> <horms+renesas@verge.net.au> wrote:
>> Use recently added R-Car Gen 3 fallback binding for msiof nodes in
>> DT for r8a7796 SoC.
>>
>> This has no run-time effect for the current driver as the initialisation
>> sequence is the same for the SoC-specific binding for r8a7796 and the
>> fallback binding for R-Car Gen 3.
>>
>> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
>
> Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>

and
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

;-)

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at 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

^ permalink raw reply

* [PATCH renesas/devel 2/4] ARM: dts: r8a7791: Use R-Car Gen 2 fallback binding for msiof nodes
From: Geert Uytterhoeven @ 2016-12-20 10:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482229959-25584-3-git-send-email-horms+renesas@verge.net.au>

On Tue, Dec 20, 2016 at 11:32 AM, Simon Horman
<horms+renesas@verge.net.au> wrote:
> Use recently added R-Car Gen 2 fallback binding for msiof nodes in
> DT for r8a7791 SoC.
>
> This has no run-time effect for the current driver as the initialisation
> sequence is the same for the SoC-specific binding for r8a7791 and the
> fallback binding for R-Car Gen 2.
>
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at 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

^ permalink raw reply

* [PATCH renesas/devel 1/4] arm64: dts: r8a7796: Use R-Car Gen 3 fallback binding for msiof nodes
From: Geert Uytterhoeven @ 2016-12-20 10:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482229959-25584-2-git-send-email-horms+renesas@verge.net.au>

On Tue, Dec 20, 2016 at 11:32 AM, Simon Horman
<horms+renesas@verge.net.au> wrote:
> Use recently added R-Car Gen 3 fallback binding for msiof nodes in
> DT for r8a7796 SoC.
>
> This has no run-time effect for the current driver as the initialisation
> sequence is the same for the SoC-specific binding for r8a7796 and the
> fallback binding for R-Car Gen 3.
>
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>

Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at 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

^ permalink raw reply

* [linux-sunxi][PATCH 3/3] ARM: dts: sun6i: Add SPDIF to the Mele I7
From: codekipper at gmail.com @ 2016-12-20 10:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161220104038.22532-1-codekipper@gmail.com>

From: Marcus Cooper <codekipper@gmail.com>

Enable the S/PDIF transmitter that is present on the Mele I7.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 arch/arm/boot/dts/sun6i-a31-i7.dts | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31-i7.dts b/arch/arm/boot/dts/sun6i-a31-i7.dts
index a2193309a199..2bc57d2dcd80 100644
--- a/arch/arm/boot/dts/sun6i-a31-i7.dts
+++ b/arch/arm/boot/dts/sun6i-a31-i7.dts
@@ -69,6 +69,23 @@
 			gpios = <&pio 7 13 GPIO_ACTIVE_HIGH>;
 		};
 	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "On-board SPDIF";
+		simple-audio-card,cpu {
+			sound-dai = <&spdif>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&spdif_out>;
+		};
+	};
+
+	spdif_out: spdif-out {
+		#sound-dai-cells = <0>;
+		compatible = "linux,spdif-dit";
+	};
 };
 
 &codec {
@@ -138,6 +155,13 @@
 	status = "okay";
 };
 
+&spdif {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spdif_pins_a>;
+	spdif-out = "okay";
+	status = "okay";
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins_a>;
-- 
2.11.0

^ permalink raw reply related

* [linux-sunxi][PATCH 2/3] ARM: dts: sun6i: Add the SPDIF block to the A31
From: codekipper at gmail.com @ 2016-12-20 10:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161220104038.22532-1-codekipper@gmail.com>

From: Marcus Cooper <codekipper@gmail.com>

Add the SPDIF transceiver controller block to the A31 dtsi.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 7370ba6c9993..559c53efa7e6 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -613,6 +613,20 @@
 			reg = <0x01c20ca0 0x20>;
 		};
 
+		spdif: spdif at 01c21000 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,sun6i-a31-spdif";
+			reg = <0x01c21000 0x400>;
+			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_APB1_SPDIF>, <&ccu CLK_SPDIF>;
+			resets = <&ccu RST_APB1_SPDIF>;
+			clock-names = "apb", "spdif";
+			dmas = <&dma 2>, <&dma 2>;
+			dma-names = "rx", "tx";
+			spdif-out = "disabled";
+			status = "disabled";
+		};
+
 		lradc: lradc at 01c22800 {
 			compatible = "allwinner,sun4i-a10-lradc-keys";
 			reg = <0x01c22800 0x100>;
-- 
2.11.0

^ permalink raw reply related

* [linux-sunxi][PATCH 1/3] ARM: dts: sun6i: Add SPDIF TX pin to the A31
From: codekipper at gmail.com @ 2016-12-20 10:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161220104038.22532-1-codekipper@gmail.com>

From: Marcus Cooper <codekipper@gmail.com>

Add the SPDIF TX pin to the A31 dtsi.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 20a0331ddfb5..7370ba6c9993 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -586,6 +586,11 @@
 				bias-pull-up;
 			};
 
+			spdif_pins_a: spdif at 0 {
+				pins = "PH28";
+				function = "spdif";
+			};
+
 			uart0_pins_a: uart0 at 0 {
 				pins = "PH20", "PH21";
 				function = "uart0";
-- 
2.11.0

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox